From eb9a7e8fbdf34374162b6f2e14cbf12f55c9b44d Mon Sep 17 00:00:00 2001 From: TheTurtle Date: Mon, 8 Sep 2025 04:08:26 +0300 Subject: [PATCH] liverpool: Write valid queries on PixelPipeStatDump (#3553) * liverpool: Write valid queries on PixelPipeStatDump * export: Small assert swap * liverpool: Advance zpass counter on every dump request --- .../frontend/translate/export.cpp | 3 ++- src/video_core/amdgpu/liverpool.cpp | 14 ++++++++++++-- src/video_core/amdgpu/liverpool.h | 2 ++ src/video_core/amdgpu/pm4_cmds.h | 7 +++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/shader_recompiler/frontend/translate/export.cpp b/src/shader_recompiler/frontend/translate/export.cpp index f41765a66..9dccf1105 100644 --- a/src/shader_recompiler/frontend/translate/export.cpp +++ b/src/shader_recompiler/frontend/translate/export.cpp @@ -129,12 +129,13 @@ void Translator::EmitExport(const GcnInst& inst) { return ExportRenderTarget(inst); } - ASSERT_MSG(!exp.compr, "Compressed exports only supported for render targets"); if (attrib == IR::Attribute::Depth && exp.en != 0 && exp.en != 1) { LOG_WARNING(Render_Vulkan, "Unsupported depth export"); return; } + ASSERT_MSG(!exp.compr, "Compressed exports only supported for render targets"); + u32 mask = exp.en; for (u32 i = 0; i < 4; i++, mask >>= 1) { if ((mask & 1) == 0) { diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index bcb869286..a504737a5 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -9,6 +9,7 @@ #include "common/polyfill_thread.h" #include "common/thread.h" #include "core/debug_state.h" +#include "core/libraries/kernel/process.h" #include "core/libraries/videoout/driver.h" #include "core/memory.h" #include "video_core/amdgpu/liverpool.h" @@ -64,6 +65,7 @@ static std::span NextPacket(std::span span, size_t offset) } Liverpool::Liverpool() { + num_counter_pairs = Libraries::Kernel::sceKernelIsNeoMode() ? 16 : 8; process_thread = std::jthread{std::bind_front(&Liverpool::Process, this)}; } @@ -163,7 +165,7 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span ccb) { const auto* it_body = reinterpret_cast(header) + 1; switch (opcode) { case PM4ItOpcode::Nop: { - const auto* nop = reinterpret_cast(header); + // const auto* nop = reinterpret_cast(header); break; } case PM4ItOpcode::WriteConstRam: { @@ -604,7 +606,15 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::spanevent_index.Value() == EventIndex::ZpassDone) { - LOG_WARNING(Render, "Unimplemented occlusion query"); + if (event->event_type.Value() == EventType::PixelPipeStatDump) { + static constexpr u64 OcclusionCounterValidMask = 0x8000000000000000ULL; + static constexpr u64 OcclusionCounterStep = 0x2FFFFFFULL; + u64* results = event->Address(); + for (s32 i = 0; i < num_counter_pairs; ++i, results += 2) { + *results = pixel_counter | OcclusionCounterValidMask; + } + pixel_counter += OcclusionCounterStep; + } } break; } diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index ad4801d84..43c40d2b5 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -1666,6 +1666,8 @@ private: u32 num_mapped_queues{1u}; // GFX is always available VAddr indirect_args_addr{}; + u32 num_counter_pairs{}; + u64 pixel_counter{}; struct ConstantEngine { void Reset() { diff --git a/src/video_core/amdgpu/pm4_cmds.h b/src/video_core/amdgpu/pm4_cmds.h index 3df73f3d6..b7d058f1a 100644 --- a/src/video_core/amdgpu/pm4_cmds.h +++ b/src/video_core/amdgpu/pm4_cmds.h @@ -415,6 +415,13 @@ struct PM4CmdEventWrite { BitField<20, 1, u32> inv_l2; ///< Send WBINVL2 op to the TC L2 cache when EVENT_INDEX = 0111 }; u32 address[]; + + template + T Address() const { + ASSERT(event_index.Value() >= EventIndex::ZpassDone && + event_index.Value() <= EventIndex::SampleStreamoutStatSx); + return std::bit_cast((u64(address[1]) << 32u) | u64(address[0])); + } }; struct PM4CmdEventWriteEop {