From 472c8213dbc4684201c79914ee13c65e81ddd87c Mon Sep 17 00:00:00 2001 From: nmzik Date: Tue, 11 Aug 2026 16:10:30 +0200 Subject: [PATCH] gpu: accept CB/DB release without GL2 writeback --- src/graphics/guest_gpu/graphicsRun.cpp | 9 +++++++-- tests/ShaderRecompilerComputeTests.cpp | 23 +++++++++++++++++------ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/graphics/guest_gpu/graphicsRun.cpp b/src/graphics/guest_gpu/graphicsRun.cpp index 87dc694f2..49ab334dd 100644 --- a/src/graphics/guest_gpu/graphicsRun.cpp +++ b/src/graphics/guest_gpu/graphicsRun.cpp @@ -1384,9 +1384,14 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr case 0x00: switch (eop_event_type) { case 0x04: + if (event_index == 0x05) { + write64(false); + return; + } + break; + case 0x14: case 0x28: - if ((eop_event_type == 0x04 && event_index == 0x05) || - (eop_event_type == 0x28 && event_index == 0x00)) { + if (event_index == 0x00) { write64(false); return; } diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index e8aa66144..faa879ebb 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -1611,13 +1611,14 @@ public: { const auto make_release_mem = [](uint32_t data_sel, uint32_t interrupt_selector, - void* destination, uint64_t value) { + void* destination, uint64_t value, + uint32_t action = 0x28u, + uint32_t gcr_cntl = 1u << 9u) { std::array packet {}; - const auto address = reinterpret_cast(destination); - constexpr uint32_t eop_none = 0x28u; - constexpr uint32_t gcr_gl2_writeback = 1u << 9u; + const auto address = reinterpret_cast(destination); + const auto event_index = (action >= 0x2fu ? 6u : 5u); packet[0] = KYTY_PM4(8, Pm4::IT_NOP, Pm4::R_RELEASE_MEM); - packet[1] = eop_none | (gcr_gl2_writeback << 12u); + packet[1] = action | (event_index << 8u) | (gcr_cntl << 12u); packet[2] = (interrupt_selector << 24u) | (data_sel << 29u); packet[3] = static_cast(address); packet[4] = static_cast(address >> 32u); @@ -1652,6 +1653,7 @@ public: std::binary_semaphore parser_complete {0}; alignas(uint64_t) uint64_t interrupt_only_gds_label = UINT64_MAX; + alignas(uint64_t) uint64_t cb_db_release_label = UINT64_MAX; bool parser_kept_nonblocking_boundaries = false; std::jthread no_gpu_wait([&] { gpu.SendCommandSync([&] { @@ -1666,6 +1668,15 @@ public: result == Pm4ProcessResult::Complete && gpu_scheduler.CurrentTick() == tick_before; + const auto cb_db_tick = gpu_scheduler.CurrentTick(); + auto cb_db_release = make_release_mem(2, 0, &cb_db_release_label, 0, 0x14u, 0); + Pm4Execution cb_db_execution; + const auto cb_db_result = processor->Process( + cb_db_execution, cb_db_release.data(), cb_db_release.size()); + const bool cb_db_release_did_not_submit = + cb_db_result == Pm4ProcessResult::Complete && cb_db_release_label == 0 && + gpu_scheduler.CurrentTick() == cb_db_tick; + auto gds_interrupt_only = make_release_mem(5, 1, &interrupt_only_gds_label, 1ull << 16u); Pm4Execution gds_interrupt_execution; @@ -1673,7 +1684,7 @@ public: const auto interrupt_result = processor->Process( gds_interrupt_execution, gds_interrupt_only.data(), gds_interrupt_only.size()); parser_kept_nonblocking_boundaries = - cache_and_counter_did_not_submit && + cache_and_counter_did_not_submit && cb_db_release_did_not_submit && interrupt_result == Pm4ProcessResult::Complete && gpu_scheduler.CurrentTick() == interrupt_tick + 1 && interrupt_only_gds_label == UINT64_MAX;