diff --git a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp index f059a0a47..5586ecec3 100644 --- a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp +++ b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp @@ -1934,13 +1934,7 @@ KYTY_CP_OP_PARSER(CpOpIndirectBuffer) { auto* indirect_buffer = reinterpret_cast(buffer[0] | (static_cast(buffer[1]) << 32u)); - uint32_t indirect_num_dw = control & 0xfffffu; - static std::atomic indirect_log_count {0}; - if (indirect_log_count.fetch_add(1) < 128) { - LOGF("\t indirect buffer: addr=0x%016" PRIx64 ", num_dw=%" PRIu32 ", control=0x%08" PRIx32 - "\n", - reinterpret_cast(indirect_buffer), indirect_num_dw, control); - } + const uint32_t indirect_num_dw = control & 0xfffffu; if (indirect_num_dw == 0) { return 3; diff --git a/src/graphics/guest_gpu/graphicsRun.cpp b/src/graphics/guest_gpu/graphicsRun.cpp index 2336fe50d..503898102 100644 --- a/src/graphics/guest_gpu/graphicsRun.cpp +++ b/src/graphics/guest_gpu/graphicsRun.cpp @@ -1072,8 +1072,7 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr case 0x03: with_interrupt = false; break; case 0x01: if (!IsAsyncComputeQueue()) { - Sync::TriggerEopEventAtEndOfPipe(command, m_interrupt_event_id, - interrupt_context_id); + TriggerEopEventAtEndOfPipe(interrupt_context_id); return; } with_interrupt = true; @@ -1082,24 +1081,15 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr default: EXIT("unknown interrupt_selector\n"); } - auto write32 = [&](bool with_writeback) { + auto write32 = [&] { auto* dst = static_cast(dst_gpu_addr); auto data = static_cast(value); + EXIT_IF(dst == nullptr); + (void)command.Handle(); std::memcpy(dst, &data, sizeof(data)); if (with_interrupt) { - if (with_writeback) { - Sync::WriteAtEndOfPipeWithInterruptWriteBack32(m_submit_id, command, dst, - data, m_interrupt_event_id, - interrupt_context_id); - } else { - Sync::WriteAtEndOfPipeWithInterrupt32(m_submit_id, command, dst, data, - m_interrupt_event_id, interrupt_context_id); - } - } else if (with_writeback) { - Sync::WriteAtEndOfPipeWithWriteBack32(m_submit_id, command, dst, data); - } else { - Sync::WriteAtEndOfPipe32(m_submit_id, command, dst, data); + TriggerEopEventAtEndOfPipe(interrupt_context_id); } }; @@ -1111,15 +1101,13 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr SynchronizeGpu(); Sync::ReadGds(*m_renderer.GetBufferCache().GetGdsBuffer(), dst, value & 0xffffu, value >> 16u); - Sync::WriteAtEndOfPipeGds32(m_submit_id, command, dst, value & 0xffffu, - value >> 16u); if (with_interrupt) { m_renderer.TriggerInterrupt(m_interrupt_event_id, interrupt_context_id); } return; } } else if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05) { - write32(false); + write32(); return; } break; @@ -1128,8 +1116,8 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr if constexpr (sizeof(T) == sizeof(uint32_t)) { if (event_write_source == 0x02 && eop_event_type == 0x2f && event_index == 0x06) { switch (cache_action) { - case 0x00: write32(false); return; - case 0x38: write32(true); return; + case 0x00: + case 0x38: write32(); return; default: break; } } @@ -1137,25 +1125,14 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr if (event_write_source == 0x04) { value = Sync::ReadReferenceClock(); } - auto write64 = [&](bool with_writeback) { + auto write64 = [&] { auto* dst = static_cast(dst_gpu_addr); + EXIT_IF(dst == nullptr); + (void)command.Handle(); std::memcpy(dst, &value, sizeof(value)); if (with_interrupt) { - if (with_writeback) { - Sync::WriteAtEndOfPipeWithInterruptWriteBack64( - m_submit_id, command, dst, value, m_interrupt_event_id, - interrupt_context_id); - } else { - Sync::WriteAtEndOfPipeWithInterrupt64(m_submit_id, command, dst, - value, m_interrupt_event_id, - interrupt_context_id); - } - } else if (with_writeback) { - Sync::WriteAtEndOfPipeWithWriteBack64(m_submit_id, command, dst, - value); - } else { - Sync::WriteAtEndOfPipe64(m_submit_id, command, dst, value); + TriggerEopEventAtEndOfPipe(interrupt_context_id); } }; @@ -1164,7 +1141,7 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr switch (eop_event_type) { case 0x04: if (event_index == 0x05) { - write64(false); + write64(); return; } break; @@ -1172,7 +1149,7 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr case 0x28: case 0x2f: if (event_index == 0x00) { - write64(false); + write64(); return; } break; @@ -1180,7 +1157,7 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr case 0x2d: case 0x30: if (event_index == 0x00 && !with_interrupt) { - write64(false); + write64(); return; } break; @@ -1195,20 +1172,20 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr if (((eop_event_type == 0x04 || eop_event_type == 0x28) && event_index == 0x05) || (event_index == 0x00)) { - write64(true); + write64(); return; } break; case 0x2b: case 0x2d: if (event_index == 0x00 && !with_interrupt) { - write64(true); + write64(); return; } break; case 0x2f: if (event_index == 0x06 && !with_interrupt) { - write64(true); + write64(); return; } break; @@ -1217,7 +1194,7 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr break; case 0x3b: if (eop_event_type == 0x04 && event_index == 0x05 && with_interrupt) { - write64(true); + write64(); return; } break; @@ -1270,7 +1247,11 @@ void CommandProcessor::EmitGlobalBarrier() { } void CommandProcessor::TriggerEopEventAtEndOfPipe(uint32_t interrupt_context_id) { - Sync::TriggerEopEventAtEndOfPipe(CurrentBuffer(), m_interrupt_event_id, interrupt_context_id); + (void)CurrentBuffer().Handle(); + GetScheduler().DeferPriorityOperation( + [&renderer = m_renderer, event_id = m_interrupt_event_id, interrupt_context_id] { + renderer.TriggerInterrupt(event_id, interrupt_context_id); + }); } void CommandProcessor::TriggerEvent(uint32_t event_type, uint32_t event_index, @@ -1360,8 +1341,9 @@ void CommandProcessor::Flip() { auto& command = CurrentBuffer(); auto request = Sync::PrepareVideoOutFlip(command, m_flip.handle, m_flip.index, m_flip.flip_mode, m_flip.flip_arg); - Sync::WriteAtEndOfPipeOnlyFlip(m_submit_id, command, m_flip.handle, m_flip.index, - m_flip.flip_mode, m_flip.flip_arg, request); + (void)command.Handle(); + GetScheduler().DeferPriorityOperation( + [&renderer = m_renderer, request] { renderer.GetVideoOut().CompleteFlip(request); }); GetScheduler().Flush(); } @@ -1375,12 +1357,13 @@ void CommandProcessor::Flip(void* dst_gpu_addr, uint32_t value) { reinterpret_cast(dst_gpu_addr), value); } + EXIT_IF(dst_gpu_addr == nullptr); std::memcpy(dst_gpu_addr, &value, sizeof(value)); auto request = Sync::PrepareVideoOutFlip(command, m_flip.handle, m_flip.index, m_flip.flip_mode, m_flip.flip_arg); - Sync::WriteAtEndOfPipeWithFlip32(m_submit_id, command, static_cast(dst_gpu_addr), - value, m_flip.handle, m_flip.index, m_flip.flip_mode, - m_flip.flip_arg, request); + (void)command.Handle(); + GetScheduler().DeferPriorityOperation( + [&renderer = m_renderer, request] { renderer.GetVideoOut().CompleteFlip(request); }); GetScheduler().Flush(); } @@ -1400,12 +1383,16 @@ void CommandProcessor::FlipWithInterrupt(uint32_t eop_event_type, uint32_t cache if (eop_event_type != 0x00000004 || cache_action != 0x00000038) { EXIT("unknown event type\n"); } + EXIT_IF(dst_gpu_addr == nullptr); std::memcpy(dst_gpu_addr, &value, sizeof(value)); auto request = Sync::PrepareVideoOutFlip(command, m_flip.handle, m_flip.index, m_flip.flip_mode, m_flip.flip_arg); - Sync::WriteAtEndOfPipeWithInterruptWriteBackFlip32( - m_submit_id, command, static_cast(dst_gpu_addr), value, m_flip.handle, - m_flip.index, m_flip.flip_mode, m_flip.flip_arg, request, m_interrupt_event_id); + (void)command.Handle(); + GetScheduler().DeferPriorityOperation( + [&renderer = m_renderer, event_id = m_interrupt_event_id, request] { + renderer.GetVideoOut().CompleteFlip(request); + renderer.TriggerInterrupt(event_id, 0); + }); GetScheduler().Flush(); } diff --git a/src/graphics/host_gpu/renderer/cache/textureCache.cpp b/src/graphics/host_gpu/renderer/cache/textureCache.cpp index fda47c1ac..9cbbdfda9 100644 --- a/src/graphics/host_gpu/renderer/cache/textureCache.cpp +++ b/src/graphics/host_gpu/renderer/cache/textureCache.cpp @@ -1932,6 +1932,9 @@ void TextureCache::RunGarbageCollector() { } void TextureCache::ProcessDownloadImages() { + if (!m_readback_linear_images) { + return; + } std::scoped_lock lock {m_lock}; for (const auto id: m_download_images) { const auto owner = m_slot_images.try_get(id); diff --git a/src/graphics/host_gpu/renderer/render.h b/src/graphics/host_gpu/renderer/render.h index a08c43b83..9e9b01481 100644 --- a/src/graphics/host_gpu/renderer/render.h +++ b/src/graphics/host_gpu/renderer/render.h @@ -39,13 +39,7 @@ enum class CommandBufferDebugOp : uint32_t { DispatchDirect, DrawIndex, DrawIndexAuto, - EopWrite, - EopInterrupt, - EopWriteBack, - EopFlip, - EopWriteBackFlip, - EopOnlyFlip, - DispatchIndirect, + DispatchIndirect = 9, Unknown, }; diff --git a/src/graphics/host_gpu/renderer/sync.cpp b/src/graphics/host_gpu/renderer/sync.cpp index 5229746db..59f00e1e9 100644 --- a/src/graphics/host_gpu/renderer/sync.cpp +++ b/src/graphics/host_gpu/renderer/sync.cpp @@ -1,10 +1,6 @@ #include "graphics/host_gpu/renderer/sync.h" #include "common/assert.h" -#include "common/common.h" -#include "common/logging/log.h" -#include "common/threads.h" -#include "graphics/host_gpu/graphicContext.h" #include "graphics/host_gpu/renderer/cache/bufferCache.h" #include "graphics/host_gpu/renderer/render.h" #include "graphics/host_gpu/renderer/renderContext.h" @@ -53,109 +49,6 @@ uint64_t ReadReferenceClock() { return value; } -enum class EndOfPipeWriteSize : uint32_t { Dword = 4, Qword = 8 }; -enum class EndOfPipeWriteAction { Write, WriteBack, Interrupt, InterruptWriteBack }; - -static CommandBufferDebugOp DebugOperation(EndOfPipeWriteAction action) { - switch (action) { - case EndOfPipeWriteAction::Write: return CommandBufferDebugOp::EopWrite; - case EndOfPipeWriteAction::WriteBack: - case EndOfPipeWriteAction::InterruptWriteBack: return CommandBufferDebugOp::EopWriteBack; - case EndOfPipeWriteAction::Interrupt: return CommandBufferDebugOp::EopInterrupt; - } - EXIT("unsupported end-of-pipe write action\n"); - return CommandBufferDebugOp::Unknown; -} - -static bool TriggersInterrupt(EndOfPipeWriteAction action) { - return action == EndOfPipeWriteAction::Interrupt || - action == EndOfPipeWriteAction::InterruptWriteBack; -} - -static void RecordEndOfPipeWrite(uint64_t submit_id, CommandBuffer& buffer, uint64_t destination, - uint64_t value, EndOfPipeWriteSize size, - EndOfPipeWriteAction action, int interrupt_event_id = 0, - uint32_t context_id = 0) { - EXIT_IF(destination == 0); - (void)buffer.Handle(); - - const auto width = static_cast(size); - const auto value_low = static_cast(value); - const auto value_high = static_cast(value >> 32u); - const auto operation = static_cast(DebugOperation(action)); - if (TriggersInterrupt(action)) { - buffer.SetDebugInfo(operation, submit_id, width, context_id, value_low, value_high, - destination); - TriggerEopEventAtEndOfPipe(buffer, interrupt_event_id, context_id); - } else { - buffer.SetDebugInfo(operation, submit_id, width, value_low, value_high, 0, destination); - } -} - -void WriteAtEndOfPipe32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, - uint32_t value) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Dword, EndOfPipeWriteAction::Write); -} - -void WriteAtEndOfPipeGds32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, - uint32_t dw_offset, uint32_t dw_num) { - EXIT_IF(dst_gpu_addr == nullptr); - (void)buffer.Handle(); - buffer.SetDebugInfo(static_cast(CommandBufferDebugOp::EopWrite), submit_id, - dw_offset, dw_num, 0, 0, reinterpret_cast(dst_gpu_addr)); -} - -void WriteAtEndOfPipe64(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst_gpu_addr, - uint64_t value) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::Write); -} - -void WriteAtEndOfPipeWithWriteBack64(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::WriteBack); -} - -void WriteAtEndOfPipeWithWriteBack32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Dword, EndOfPipeWriteAction::WriteBack); -} - -void WriteAtEndOfPipeWithInterruptWriteBack64(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value, int event_id, - uint32_t context_id) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::InterruptWriteBack, - event_id, context_id); -} - -void WriteAtEndOfPipeWithInterruptWriteBack32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value, int event_id, - uint32_t context_id) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Dword, EndOfPipeWriteAction::InterruptWriteBack, - event_id, context_id); -} - -void WriteAtEndOfPipeWithInterrupt64(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value, int event_id, - uint32_t context_id) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::Interrupt, event_id, - context_id); -} - -void WriteAtEndOfPipeWithInterrupt32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value, int event_id, - uint32_t context_id) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), value, - EndOfPipeWriteSize::Dword, EndOfPipeWriteAction::Interrupt, event_id, - context_id); -} - uint64_t PrepareVideoOutFlip(CommandBuffer& buffer, int handle, int index, int flip_mode, int64_t flip_arg) { for (;;) { @@ -176,65 +69,6 @@ uint64_t PrepareVideoOutFlip(CommandBuffer& buffer, int handle, int index, int f } } -void WriteAtEndOfPipeWithInterruptWriteBackFlip32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value, - int handle, int index, int flip_mode, - int64_t flip_arg, uint64_t request_id, - int event_id) { - EXIT_IF(dst_gpu_addr == nullptr); - (void)buffer.Handle(); - buffer.SetDebugInfo(static_cast(CommandBufferDebugOp::EopWriteBackFlip), submit_id, - static_cast(handle), static_cast(index), - static_cast(flip_mode), value, static_cast(flip_arg)); - - auto& renderer = buffer.GetContext(); - auto& scheduler = renderer.GetCommandScheduler(); - EXIT_IF(!scheduler.Active() || &buffer != &scheduler.Current()); - scheduler.DeferPriorityOperation([&renderer, event_id, request_id] { - renderer.GetVideoOut().CompleteFlip(request_id); - renderer.TriggerInterrupt(event_id, 0); - }); -} - -void WriteAtEndOfPipeWithFlip32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, - uint32_t value, int handle, int index, int flip_mode, - int64_t flip_arg, uint64_t request_id) { - EXIT_IF(dst_gpu_addr == nullptr); - (void)buffer.Handle(); - buffer.SetDebugInfo(static_cast(CommandBufferDebugOp::EopFlip), submit_id, - static_cast(handle), static_cast(index), - static_cast(flip_mode), value, static_cast(flip_arg)); - - auto& renderer = buffer.GetContext(); - auto& scheduler = renderer.GetCommandScheduler(); - EXIT_IF(!scheduler.Active() || &buffer != &scheduler.Current()); - scheduler.DeferPriorityOperation( - [&renderer, request_id] { renderer.GetVideoOut().CompleteFlip(request_id); }); -} - -void WriteAtEndOfPipeOnlyFlip(uint64_t submit_id, CommandBuffer& buffer, int handle, int index, - int flip_mode, int64_t flip_arg, uint64_t request_id) { - (void)buffer.Handle(); - buffer.SetDebugInfo(static_cast(CommandBufferDebugOp::EopOnlyFlip), submit_id, - static_cast(handle), static_cast(index), - static_cast(flip_mode), 0, static_cast(flip_arg)); - - auto& renderer = buffer.GetContext(); - auto& scheduler = renderer.GetCommandScheduler(); - EXIT_IF(!scheduler.Active() || &buffer != &scheduler.Current()); - scheduler.DeferPriorityOperation( - [&renderer, request_id] { renderer.GetVideoOut().CompleteFlip(request_id); }); -} - -void TriggerEopEventAtEndOfPipe(CommandBuffer& buffer, int event_id, uint32_t context_id) { - (void)buffer.Handle(); - auto& renderer = buffer.GetContext(); - auto& scheduler = renderer.GetCommandScheduler(); - EXIT_IF(!scheduler.Active() || &buffer != &scheduler.Current()); - scheduler.DeferPriorityOperation( - [&renderer, event_id, context_id] { renderer.TriggerInterrupt(event_id, context_id); }); -} - static void InterruptEventResetFunc(LibKernel::EventQueue::KernelEqueueEvent* event) { EXIT_IF(event == nullptr); event->triggered = false; diff --git a/src/graphics/host_gpu/renderer/sync.h b/src/graphics/host_gpu/renderer/sync.h index f0e9b6bf9..67a970c70 100644 --- a/src/graphics/host_gpu/renderer/sync.h +++ b/src/graphics/host_gpu/renderer/sync.h @@ -17,44 +17,8 @@ namespace Sync { uint64_t& value); [[nodiscard]] uint64_t ReadReferenceClock(); -void TriggerEopEventAtEndOfPipe(CommandBuffer& buffer, int event_id, uint32_t context_id); - -void WriteAtEndOfPipe32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, - uint32_t value); -void WriteAtEndOfPipe64(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst_gpu_addr, - uint64_t value); -void WriteAtEndOfPipeGds32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, - uint32_t dw_offset, uint32_t dw_num); -void WriteAtEndOfPipeWithWriteBack32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value); -void WriteAtEndOfPipeWithWriteBack64(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value); -void WriteAtEndOfPipeWithInterrupt32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value, int event_id, - uint32_t context_id = 0); -void WriteAtEndOfPipeWithInterrupt64(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value, int event_id, - uint32_t context_id = 0); -void WriteAtEndOfPipeWithInterruptWriteBack32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value, int event_id, - uint32_t context_id = 0); -void WriteAtEndOfPipeWithInterruptWriteBack64(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value, int event_id, - uint32_t context_id = 0); - [[nodiscard]] uint64_t PrepareVideoOutFlip(CommandBuffer& buffer, int handle, int index, int flip_mode, int64_t flip_arg); -void WriteAtEndOfPipeOnlyFlip(uint64_t submit_id, CommandBuffer& buffer, int handle, int index, - int flip_mode, int64_t flip_arg, uint64_t request_id); -void WriteAtEndOfPipeWithFlip32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, - uint32_t value, int handle, int index, int flip_mode, - int64_t flip_arg, uint64_t request_id); -void WriteAtEndOfPipeWithInterruptWriteBackFlip32(uint64_t submit_id, CommandBuffer& buffer, - uint32_t* dst_gpu_addr, uint32_t value, - int handle, int index, int flip_mode, - int64_t flip_arg, uint64_t request_id, - int event_id); - int AddEqEvent(RenderContext& renderer, LibKernel::EventQueue::KernelEqueue eq, int id, void* udata); int DeleteEqEvent(RenderContext& renderer, LibKernel::EventQueue::KernelEqueue eq, int id);