diff --git a/src/graphics/guest_gpu/graphicsRun.cpp b/src/graphics/guest_gpu/graphicsRun.cpp index af897547b..62d03c77a 100644 --- a/src/graphics/guest_gpu/graphicsRun.cpp +++ b/src/graphics/guest_gpu/graphicsRun.cpp @@ -1205,8 +1205,9 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr } break; case 0x02: + case 0x04: if constexpr (sizeof(T) == sizeof(uint32_t)) { - if (eop_event_type == 0x2f && event_index == 0x06) { + 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; @@ -1214,6 +1215,9 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr } } } else { + if (event_write_source == 0x04) { + value = Sync::ReadReferenceClock(); + } auto write64 = [&](bool with_writeback) { auto* dst = static_cast(dst_gpu_addr); std::memcpy(dst, &value, sizeof(value)); @@ -1270,7 +1274,7 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr case 0x14: case 0x28: if (((eop_event_type == 0x04 || eop_event_type == 0x28) && - event_index == 0x05 && !with_interrupt) || + event_index == 0x05) || (event_index == 0x00)) { write64(true); return; @@ -1302,45 +1306,6 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr } } break; - case 0x04: - if constexpr (sizeof(T) == sizeof(uint64_t)) { - const auto clock = Sync::ReadReferenceClock(); - auto* dst = static_cast(dst_gpu_addr); - std::memcpy(dst, &clock, sizeof(clock)); - switch (cache_action) { - case 0x00: - if ((eop_event_type == 0x04 && event_index == 0x05) || - (eop_event_type == 0x28 && event_index == 0x00)) { - if (with_interrupt) { - Sync::WriteAtEndOfPipeWithInterrupt64( - m_submit_id, command, dst, clock, m_interrupt_event_id, - interrupt_context_id); - } else { - Sync::WriteAtEndOfPipeClockCounter(m_submit_id, command, - dst, clock); - } - return; - } - break; - case 0x38: - if ((eop_event_type == 0x04 && - (event_index == 0x00 || event_index == 0x05)) || - (eop_event_type == 0x28 && event_index == 0x00)) { - if (with_interrupt) { - Sync::WriteAtEndOfPipeWithInterruptWriteBack64( - m_submit_id, command, dst, clock, m_interrupt_event_id, - interrupt_context_id); - } else { - Sync::WriteAtEndOfPipeClockCounterWithWriteBack( - m_submit_id, command, dst, clock); - } - return; - } - break; - default: break; - } - } - break; default: break; } diff --git a/src/graphics/host_gpu/renderer/sync.cpp b/src/graphics/host_gpu/renderer/sync.cpp index db3003c58..5a6e89f6a 100644 --- a/src/graphics/host_gpu/renderer/sync.cpp +++ b/src/graphics/host_gpu/renderer/sync.cpp @@ -112,26 +112,6 @@ void WriteAtEndOfPipe64(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::Write); } -void WriteAtEndOfPipeClockCounter(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst_gpu_addr, - uint64_t value) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), 0, - EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::Write); - - LOGF_COLOR(Log::Color::BrightGreen, - "EndOfPipe Signal!!! [0x%016" PRIx64 "] <- Clock: 0x%016" PRIx64 "\n", - reinterpret_cast(dst_gpu_addr), value); -} - -void WriteAtEndOfPipeClockCounterWithWriteBack(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value) { - RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast(dst_gpu_addr), 0, - EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::WriteBack); - - LOGF_COLOR(Log::Color::BrightGreen, - "EndOfPipe Signal!!! [0x%016" PRIx64 "] <- Clock: 0x%016" PRIx64 "\n", - reinterpret_cast(dst_gpu_addr), value); -} - 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, diff --git a/src/graphics/host_gpu/renderer/sync.h b/src/graphics/host_gpu/renderer/sync.h index cec6677ca..f0e9b6bf9 100644 --- a/src/graphics/host_gpu/renderer/sync.h +++ b/src/graphics/host_gpu/renderer/sync.h @@ -25,10 +25,6 @@ void WriteAtEndOfPipe64(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst 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 WriteAtEndOfPipeClockCounter(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst_gpu_addr, - uint64_t value); -void WriteAtEndOfPipeClockCounterWithWriteBack(uint64_t submit_id, CommandBuffer& buffer, - uint64_t* dst_gpu_addr, uint64_t value); void WriteAtEndOfPipeWithWriteBack32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, uint32_t value); void WriteAtEndOfPipeWithWriteBack64(uint64_t submit_id, CommandBuffer& buffer, diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index d4c9493b6..8e5a0377f 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -2480,6 +2480,22 @@ public: cb_db_release_label == 0 && gpu_scheduler.CurrentTick() == cb_db_tick; + for (const auto gcr : {0u, 1u << 9u}) { + const auto before = Sync::ReadReferenceClock(); + auto timestamp = + make_release_mem(3, 0, &cb_db_release_label, UINT64_MAX, 0x14u, gcr); + Pm4Execution timestamp_execution; + const auto timestamp_result = + processor->Process(timestamp_execution, timestamp); + Require("GpuCommandLane", "timestamp write", + timestamp_result == Pm4ProcessResult::Complete && + cb_db_release_label >= before && + cb_db_release_label <= Sync::ReadReferenceClock() && + gpu_scheduler.CurrentTick() == cb_db_tick, + "timestamp write failed, returned an invalid time, or " + "submitted extra GPU work"); + } + auto gds_interrupt_only = make_release_mem(5, 1, &interrupt_only_gds_label, 1ull << 16u); Pm4Execution gds_interrupt_execution; @@ -2521,6 +2537,14 @@ public: gpu.SendCommandSync([&] { processor->BufferInit(); + const auto clock_before = Sync::ReadReferenceClock(); + processor->WriteAtEndOfPipe64(0, 0, 0x04, 0x38, 5, 4, + &release_label, UINT64_MAX, 2); + Require("GpuCommandLane", "EOP reference clock with interrupt", + release_label >= clock_before && + 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();