From 38c6f53506a1ba9014cdc343c573c1153973c407 Mon Sep 17 00:00:00 2001 From: Framer Date: Sun, 8 Nov 2026 05:06:35 +0100 Subject: [PATCH] perf(gpu): avoid empty sync-request mutex acquisition on every draw --- src/video_core/gpu.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 48cf6abce8..311de54499 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -144,6 +144,7 @@ struct GPU::Impl { std::unique_lock lck{sync_request_mutex}; const u64 fence = ++last_sync_fence; sync_requests.emplace_back(std::forward(action)); + pending_sync_requests.fetch_add(1, std::memory_order_release); return fence; } @@ -165,10 +166,16 @@ struct GPU::Impl { /// Tick pending requests within the GPU. void TickWork() { + // Fast path for the overwhelmingly common empty queue: do not lock per draw. + // A new request racing this check is processed on the next tick, as before. + if (pending_sync_requests.load(std::memory_order_acquire) == 0) { + return; + } std::unique_lock lck{sync_request_mutex}; while (!sync_requests.empty()) { auto request = std::move(sync_requests.front()); sync_requests.pop_front(); + pending_sync_requests.fetch_sub(1, std::memory_order_relaxed); sync_request_mutex.unlock(); request(); current_sync_fence.fetch_add(1, std::memory_order_release); @@ -393,6 +400,7 @@ struct GPU::Impl { std::condition_variable sync_cv; std::list> sync_requests; + std::atomic pending_sync_requests{}; std::atomic current_sync_fence{}; u64 last_sync_fence{};