mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 11:26:56 +02:00
graphics: share EOP clock and immediate write handling
Co-authored-by: Mac <me@itsmemac.com>
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user