mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
gpu: queue GDS release interrupts behind earlier interrupts
This commit is contained in:
@@ -979,11 +979,7 @@ void CommandProcessor::ReleaseMem(uint32_t data_sel, uint32_t interrupt_selector
|
|||||||
const auto gds = static_cast<uint32_t>(data);
|
const auto gds = static_cast<uint32_t>(data);
|
||||||
Sync::ReadGds(*m_renderer.GetBufferCache().GetGdsBuffer(),
|
Sync::ReadGds(*m_renderer.GetBufferCache().GetGdsBuffer(),
|
||||||
static_cast<uint32_t*>(address), gds & 0xffffu, gds >> 16u);
|
static_cast<uint32_t*>(address), gds & 0xffffu, gds >> 16u);
|
||||||
if (interrupt) {
|
break;
|
||||||
// The GPU is idle, so the interrupt needs no fence.
|
|
||||||
m_renderer.TriggerInterrupt(m_interrupt_event_id, interrupt_context_id);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
default: EXIT("unknown release_mem data selector: %" PRIu32 "\n", data_sel);
|
default: EXIT("unknown release_mem data selector: %" PRIu32 "\n", data_sel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3362,6 +3362,38 @@ public:
|
|||||||
interrupt_event.ident == 0x20 && interrupt_event.data == 0x789u,
|
interrupt_event.ident == 0x20 && interrupt_event.data == 0x789u,
|
||||||
"kSendIntCtx lost its interrupt or context id");
|
"kSendIntCtx lost its interrupt or context id");
|
||||||
|
|
||||||
|
// A GDS release interrupt follows the interrupts queued before it, so
|
||||||
|
// neither arrives while the priority thread is parked.
|
||||||
|
std::binary_semaphore priority_parked{0};
|
||||||
|
gpu.SendCommandSync([&] {
|
||||||
|
auto &scheduler = context.GetCommandScheduler();
|
||||||
|
scheduler.Finish();
|
||||||
|
scheduler.DeferPriorityOperation([&] { priority_parked.acquire(); });
|
||||||
|
});
|
||||||
|
uint32_t ordered_gds_label = 0;
|
||||||
|
const auto ordered_first = make_interrupt_packet(0, 2, nullptr, 0, 0xa1u);
|
||||||
|
const auto ordered_gds =
|
||||||
|
make_interrupt_packet(5, 2, &ordered_gds_label, 1u << 16u, 0xa2u);
|
||||||
|
std::array<uint32_t, 16> ordered_commands{};
|
||||||
|
std::copy(ordered_first.begin(), ordered_first.end(), ordered_commands.begin());
|
||||||
|
std::copy(ordered_gds.begin(), ordered_gds.end(), ordered_commands.begin() + 8);
|
||||||
|
gpu.SubmitCompute(0x20, ordered_commands);
|
||||||
|
gpu.WaitForIdle();
|
||||||
|
interrupt_count = 0;
|
||||||
|
const auto parked_wait = wait_for_interrupt(interrupt_event, interrupt_count);
|
||||||
|
priority_parked.release();
|
||||||
|
finish_gpu();
|
||||||
|
LibKernel::EventQueue::KernelEvent second_event{};
|
||||||
|
int second_count = 0;
|
||||||
|
interrupt_count = 0;
|
||||||
|
const auto first_wait = wait_for_interrupt(interrupt_event, interrupt_count);
|
||||||
|
const auto second_wait = wait_for_interrupt(second_event, second_count);
|
||||||
|
Require("GpuCommandLane", "GDS interrupt order",
|
||||||
|
parked_wait == LibKernel::KERNEL_ERROR_ETIMEDOUT && first_wait == 0 &&
|
||||||
|
interrupt_count == 1 && interrupt_event.data == 0xa1u &&
|
||||||
|
second_wait == 0 && second_count == 1 && second_event.data == 0xa2u,
|
||||||
|
"a GDS release interrupt overtook an earlier interrupt");
|
||||||
|
|
||||||
interrupt_count = 0;
|
interrupt_count = 0;
|
||||||
const auto extra_interrupt_wait =
|
const auto extra_interrupt_wait =
|
||||||
wait_for_interrupt(interrupt_event, interrupt_count);
|
wait_for_interrupt(interrupt_event, interrupt_count);
|
||||||
|
|||||||
Reference in New Issue
Block a user