aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan/vk_scheduler.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 05:46:59 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 20:49:47 -0400
commita99484f3cb6a78eed8563ac67551ab1ea0d0c0c3 (patch)
treebcaf5fce0f21fcf4b1cb18ea383a67f1396b9409 /src/video_core/renderer_vulkan/vk_scheduler.cpp
parent77cad674e5a73cb56ba1ed5d5c97a0d99eb21159 (diff)
vulkan: dispatch to the worker every 32 draws, wake it only when it waits
Every 8 draws the GPU thread handed a command chunk to the Vulkan worker and woke it with a system call (~2% of the GPU thread at ~55,000 draws a second). Chunks now go every 32 draws (a full chunk still goes on its own), and the worker is woken only when it is waiting; a busy worker pops the queue before waiting again.
Diffstat (limited to 'src/video_core/renderer_vulkan/vk_scheduler.cpp')
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp
index 4a7a7d5e78..aa8511a5cb 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.cpp
+++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp
@@ -84,11 +84,17 @@ void Scheduler::WaitWorker() {
void Scheduler::DispatchWork() {
if (chunk && !chunk->Empty()) {
+ // Waking the worker is a system call (~2% of the GPU thread at one dispatch per 8
+ // draws): skip it while the worker is still busy, it pops the queue before waiting.
+ bool wake;
{
std::scoped_lock ql{queue_mutex};
work_queue.push(std::move(chunk));
+ wake = worker_waiting;
+ }
+ if (wake) {
+ event_cv.notify_all();
}
- event_cv.notify_all();
AcquireNewChunk();
}
}
@@ -290,7 +296,11 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
std::unique_lock lk{queue_mutex};
// Wait for work.
- event_cv.wait(lk, stop_token, [&] { return TryPopQueue(work); });
+ event_cv.wait(lk, stop_token, [&] {
+ worker_waiting = !TryPopQueue(work);
+ return !worker_waiting;
+ });
+ worker_waiting = false;
// If we've been asked to stop, we're done.
if (stop_token.stop_requested()) {