From 3beb22ed7f356635aabdf3c06d4de6ec13628d30 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 7 Nov 2022 02:20:22 +0100 Subject: [PATCH] VideoBackends:Vulkan: Synchronize presentation Synchronize with the submission thread if the last present is not done yet. --- Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp | 1 + Source/Core/VideoBackends/Vulkan/CommandBufferManager.h | 2 ++ Source/Core/VideoBackends/Vulkan/VKRenderer.cpp | 3 +++ 3 files changed, 6 insertions(+) diff --git a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp index 19df14d4f3..8c9f744216 100644 --- a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp @@ -473,6 +473,7 @@ void CommandBufferManager::SubmitCommandBuffer(u32 command_buffer_index, nullptr}; m_last_present_result = vkQueuePresentKHR(g_vulkan_context->GetPresentQueue(), &present_info); + m_last_present_done.Set(); if (m_last_present_result != VK_SUCCESS) { // VK_ERROR_OUT_OF_DATE_KHR is not fatal, just means we need to recreate our swap chain. diff --git a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h index b253137868..7b4772760a 100644 --- a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h +++ b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.h @@ -83,6 +83,7 @@ public: // Was the last present submitted to the queue a failure? If so, we must recreate our swapchain. bool CheckLastPresentFail() { return m_last_present_failed.TestAndClear(); } VkResult GetLastPresentResult() const { return m_last_present_result; } + bool CheckLastPresentDone() { return m_last_present_done.TestAndClear(); } // Schedule a vulkan resource for destruction later on. This will occur when the command buffer // is next re-used, and the GPU has finished working with the specified resource. @@ -159,6 +160,7 @@ private: std::condition_variable m_submit_worker_condvar; bool m_submit_worker_idle = true; Common::Flag m_last_present_failed; + Common::Flag m_last_present_done; VkResult m_last_present_result = VK_SUCCESS; bool m_use_threaded_submission = false; u32 m_descriptor_set_count = DESCRIPTOR_SETS_PER_POOL; diff --git a/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp b/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp index 23dba4613b..31b4f1a3c2 100644 --- a/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp @@ -261,6 +261,9 @@ void Renderer::BindBackbuffer(const ClearColor& clear_color) { StateTracker::GetInstance()->EndRenderPass(); + if (!g_command_buffer_mgr->CheckLastPresentDone()) + g_command_buffer_mgr->WaitForWorkerThreadIdle(); + // Handle host window resizes. CheckForSurfaceChange(); CheckForSurfaceResize();