From 8e42e99788faf3b8443e479b3ab7e5f6201358d6 Mon Sep 17 00:00:00 2001 From: nmzik Date: Tue, 29 Sep 2026 03:00:57 +0400 Subject: [PATCH] graphics: batch release labels without redundant submissions --- .../command_processor/pm4Handlers.cpp | 10 ++++---- tests/ShaderRecompilerComputeTests.cpp | 24 ++++++++++++------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp index c95983b69..8df48e30a 100644 --- a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp +++ b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp @@ -2266,7 +2266,6 @@ KYTY_CP_OP_PARSER(CpOpReleaseMem) { const bool gl2_writeback = ((gcr_cntl & GcrGl2Writeback) != 0); auto trigger_interrupt = [&]() { - bool queued = false; switch (interrupt_selector) { case 0x00: case 0x03: break; @@ -2274,13 +2273,10 @@ KYTY_CP_OP_PARSER(CpOpReleaseMem) { case 0x02: case 0x04: cp.TriggerEopEventAtEndOfPipe(interrupt_context_id); - queued = true; + cp.BufferFlush(); break; default: EXIT("unknown release_mem interrupt selector\n"); } - if (queued) { - cp.BufferFlush(); - } }; if (data_sel == 0 || interrupt_selector == 4) { @@ -2318,7 +2314,9 @@ KYTY_CP_OP_PARSER(CpOpReleaseMem) { cp.WriteAtEndOfPipe32(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_source, dst_gpu_addr, static_cast(value), interrupt_selector, interrupt_context_id); - cp.BufferFlush(); + if (interrupt_selector == 0x01 || interrupt_selector == 0x02) { + cp.BufferFlush(); + } return 7; } diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index e070b2d7c..cf6c445ba 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -2565,13 +2565,20 @@ public: release_label <= Sync::ReadReferenceClock(), "clock write with writeback and interrupt lost its data"); - auto immediate = make_release_mem(1, 0, &release_label, 0x11223344u); - Pm4Execution immediate_execution; - const auto immediate_tick = gpu_scheduler.CurrentTick(); - const auto immediate_result = - processor->Process(immediate_execution, immediate); - const bool immediate_split_once = - gpu_scheduler.CurrentTick() == immediate_tick + 1; + for (const auto interrupt : {0u, 3u, 1u, 2u}) { + release_label = 0; + auto immediate = make_release_mem(1, interrupt, &release_label, 0x11223344u); + Pm4Execution immediate_execution; + const auto immediate_tick = gpu_scheduler.CurrentTick(); + const auto immediate_result = + processor->Process(immediate_execution, immediate); + Require("GpuCommandLane", "32-bit release boundary", + immediate_result == Pm4ProcessResult::Complete && + gpu_scheduler.CurrentTick() == + immediate_tick + (interrupt == 1 || interrupt == 2) && + release_label == (interrupt == 1 ? 0 : 0x11223344u), + "label-only release submitted work or interrupt release lost its boundary"); + } auto gds = make_release_mem(5, 0, &gds_label, 1ull << 16u); Pm4Execution gds_execution; @@ -2597,8 +2604,7 @@ public: gpu_scheduler.CurrentTick() == gds_interrupt_tick + 1; release_mem_submission_counts = - immediate_result == Pm4ProcessResult::Complete && - immediate_split_once && gds_result == Pm4ProcessResult::Complete && + gds_result == Pm4ProcessResult::Complete && gds_waited_once && interrupt_result == Pm4ProcessResult::Complete && interrupt_split_once && gds_interrupt_result == Pm4ProcessResult::Complete &&