From 1cfb0a118525e0e7987fd7383a9eb31dbe505c92 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 4 Dec 2016 00:23:37 +1000 Subject: [PATCH] Vulkan: Fix deadlock in some resize scenarios Only have experienced this on a few occasions when using the anv driver. --- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 2b8e0b63a6..d35a4b7660 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -661,8 +661,15 @@ void Renderer::DrawScreen(const EFBRectangle& source_rect, u32 xfb_addr, VkResult res = m_swap_chain->AcquireNextImage(m_image_available_semaphore); if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) { - // Window has been resized. Update the swap chain and try again. + // There's an issue here. We can't resize the swap chain while the GPU is still busy with it, + // but calling WaitForGPUIdle would create a deadlock as PrepareToSubmitCommandBuffer has been + // called by SwapImpl. WaitForGPUIdle waits on the semaphore, which PrepareToSubmitCommandBuffer + // has already done, so it blocks indefinitely. To work around this, we submit the current + // command buffer, resize the swap chain (which calls WaitForGPUIdle), and then finally call + // PrepareToSubmitCommandBuffer to return to the state that the caller expects. + g_command_buffer_mgr->SubmitCommandBuffer(false); ResizeSwapChain(); + g_command_buffer_mgr->PrepareToSubmitCommandBuffer(); res = m_swap_chain->AcquireNextImage(m_image_available_semaphore); } if (res != VK_SUCCESS)