graphics: share EOP clock and immediate write handling

Co-authored-by: Mac <me@itsmemac.com>
This commit is contained in:
nmzik
2026-09-25 15:58:23 +04:00
parent f7ae6e0a83
commit bfdbba3aa4
4 changed files with 30 additions and 65 deletions
+6 -41
View File
@@ -1205,8 +1205,9 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr
} }
break; break;
case 0x02: case 0x02:
case 0x04:
if constexpr (sizeof(T) == sizeof(uint32_t)) { 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) { switch (cache_action) {
case 0x00: write32(false); return; case 0x00: write32(false); return;
case 0x38: write32(true); return; case 0x38: write32(true); return;
@@ -1214,6 +1215,9 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr
} }
} }
} else { } else {
if (event_write_source == 0x04) {
value = Sync::ReadReferenceClock();
}
auto write64 = [&](bool with_writeback) { auto write64 = [&](bool with_writeback) {
auto* dst = static_cast<uint64_t*>(dst_gpu_addr); auto* dst = static_cast<uint64_t*>(dst_gpu_addr);
std::memcpy(dst, &value, sizeof(value)); std::memcpy(dst, &value, sizeof(value));
@@ -1270,7 +1274,7 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr
case 0x14: case 0x14:
case 0x28: case 0x28:
if (((eop_event_type == 0x04 || eop_event_type == 0x28) && if (((eop_event_type == 0x04 || eop_event_type == 0x28) &&
event_index == 0x05 && !with_interrupt) || event_index == 0x05) ||
(event_index == 0x00)) { (event_index == 0x00)) {
write64(true); write64(true);
return; return;
@@ -1302,45 +1306,6 @@ void CommandProcessor::WriteAtEndOfPipe(uint32_t cache_policy, uint32_t event_wr
} }
} }
break; break;
case 0x04:
if constexpr (sizeof(T) == sizeof(uint64_t)) {
const auto clock = Sync::ReadReferenceClock();
auto* dst = static_cast<uint64_t*>(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; default: break;
} }
-20
View File
@@ -112,26 +112,6 @@ void WriteAtEndOfPipe64(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst
EndOfPipeWriteSize::Qword, EndOfPipeWriteAction::Write); 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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(dst_gpu_addr), value);
}
void WriteAtEndOfPipeWithWriteBack64(uint64_t submit_id, CommandBuffer& buffer, void WriteAtEndOfPipeWithWriteBack64(uint64_t submit_id, CommandBuffer& buffer,
uint64_t* dst_gpu_addr, uint64_t value) { uint64_t* dst_gpu_addr, uint64_t value) {
RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast<uint64_t>(dst_gpu_addr), value, RecordEndOfPipeWrite(submit_id, buffer, reinterpret_cast<uint64_t>(dst_gpu_addr), value,
-4
View File
@@ -25,10 +25,6 @@ void WriteAtEndOfPipe64(uint64_t submit_id, CommandBuffer& buffer, uint64_t* dst
uint64_t value); uint64_t value);
void WriteAtEndOfPipeGds32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr, void WriteAtEndOfPipeGds32(uint64_t submit_id, CommandBuffer& buffer, uint32_t* dst_gpu_addr,
uint32_t dw_offset, uint32_t dw_num); 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, void WriteAtEndOfPipeWithWriteBack32(uint64_t submit_id, CommandBuffer& buffer,
uint32_t* dst_gpu_addr, uint32_t value); uint32_t* dst_gpu_addr, uint32_t value);
void WriteAtEndOfPipeWithWriteBack64(uint64_t submit_id, CommandBuffer& buffer, void WriteAtEndOfPipeWithWriteBack64(uint64_t submit_id, CommandBuffer& buffer,
+24
View File
@@ -2480,6 +2480,22 @@ public:
cb_db_release_label == 0 && cb_db_release_label == 0 &&
gpu_scheduler.CurrentTick() == cb_db_tick; 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 = auto gds_interrupt_only =
make_release_mem(5, 1, &interrupt_only_gds_label, 1ull << 16u); make_release_mem(5, 1, &interrupt_only_gds_label, 1ull << 16u);
Pm4Execution gds_interrupt_execution; Pm4Execution gds_interrupt_execution;
@@ -2521,6 +2537,14 @@ public:
gpu.SendCommandSync([&] { gpu.SendCommandSync([&] {
processor->BufferInit(); 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); auto immediate = make_release_mem(1, 0, &release_label, 0x11223344u);
Pm4Execution immediate_execution; Pm4Execution immediate_execution;
const auto immediate_tick = gpu_scheduler.CurrentTick(); const auto immediate_tick = gpu_scheduler.CurrentTick();