graphics: stall waitUntilSafeForRendering in its command processor instead of the GPU thread

This commit is contained in:
nmzik
2026-10-22 18:26:35 +02:00
parent a951a91703
commit a358b847c1
6 changed files with 142 additions and 22 deletions
+16 -5
View File
@@ -30,6 +30,7 @@
#include <mutex>
#include <semaphore>
#include <thread>
#include <utility>
#include <vector>
namespace Libs::Graphics {
@@ -91,6 +92,12 @@ void GuestGpu::SendCommand(Common::UniqueFunction<void>&& command) {
m_work_available.Signal();
}
void GuestGpu::Wake() {
Common::LockGuard lock(m_queue_mutex);
m_wake_pending = true;
m_work_available.Signal();
}
void GuestGpu::ProcessCommands() {
EXIT_IF(!IsGpuThread());
while (m_pending_commands.load(std::memory_order_acquire) != 0) {
@@ -464,7 +471,10 @@ void GuestGpu::ThreadRun(void* data) {
}
if (selected_queue < 0) {
gpu->m_processing = false;
gpu->m_work_available.WaitFor(&gpu->m_queue_mutex, 100);
// A wake that came before this wait must not be lost.
if (!std::exchange(gpu->m_wake_pending, false)) {
gpu->m_work_available.WaitFor(&gpu->m_queue_mutex, 100);
}
for (auto& queue: gpu->m_queues) {
if (!queue.empty()) {
queue.front().blocked = false;
@@ -998,10 +1008,11 @@ void CommandProcessor::DrawIndexAuto(DrawAutoArgs args) {
}
void CommandProcessor::WaitFlipDone(uint32_t video_out_handle, uint32_t display_buffer_index) {
BufferFlush();
m_renderer.GetVideoOut().WaitFlipDone(static_cast<int>(video_out_handle),
static_cast<int>(display_buffer_index));
// The SDK stalls only this command processor, not the host command lane or other queues.
if (!m_renderer.GetVideoOut().IsSafeForRendering(static_cast<int>(video_out_handle),
static_cast<int>(display_buffer_index))) {
SuspendPm4();
}
}
template <typename T>