From 0abbb751e498d39ea4353a8f5e56f034ca4fd09e Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Wed, 25 Dec 2024 13:06:25 +0300 Subject: [PATCH] Fix loading thread breaking waitable swap chain order. --- UnleashedRecomp/gpu/video.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 801dec6a..65d362d4 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -2173,10 +2173,23 @@ static void ProcDrawImGui(const RenderCommand& cmd) } } +// We have to check for this to properly handle the following situation: +// 1. Wait on swap chain. +// 2. Create loading thread. +// 3. Loading thread also waits on swap chain. +// 4. Loading thread presents and quits. +// 5. After the loading thread quits, application also presents. +static bool g_pendingWaitOnSwapChain = true; + void Video::WaitOnSwapChain() { - if (g_swapChainValid) - g_swapChain->wait(); + if (g_pendingWaitOnSwapChain) + { + if (g_swapChainValid) + g_swapChain->wait(); + + g_pendingWaitOnSwapChain = false; + } } static bool g_shouldPrecompilePipelines; @@ -2207,10 +2220,15 @@ void Video::Present() if (g_swapChainValid) { + if (g_pendingWaitOnSwapChain) + g_swapChain->wait(); // Never gonna happen outside loading threads as explained above. + RenderCommandSemaphore* signalSemaphores[] = { g_renderSemaphores[g_frame].get() }; g_swapChainValid = g_swapChain->present(g_backBufferIndex, signalSemaphores, std::size(signalSemaphores)); } + g_pendingWaitOnSwapChain = true; + g_frame = g_nextFrame; g_nextFrame = (g_frame + 1) % NUM_FRAMES;