From ceddbaf7c4d9bb2554912828e3130c64f571713d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Nov 2019 23:12:07 +0100 Subject: [PATCH] [dxvk] Fix synchronization around vkDeviceWaitIdle From the spec: "Host access to all VkQueue objects created from device must be externally synchronized" We were not doing that, which could cause hangs and all sorts of issues when recreating the swap chain on Nvidia GPUs. --- src/d3d11/d3d11_swapchain.cpp | 2 ++ src/dxvk/dxvk_device.cpp | 4 ++-- src/vulkan/vulkan_presenter.cpp | 4 +--- src/vulkan/vulkan_presenter.h | 4 +++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 745ffedd..74105b2c 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -364,6 +364,8 @@ namespace dxvk { void D3D11SwapChain::RecreateSwapChain(BOOL Vsync) { // Ensure that we can safely destroy the swap chain m_device->waitForSubmission(&m_presentStatus); + m_device->waitForIdle(); + m_presentStatus.result = VK_SUCCESS; vk::PresenterDesc presenterDesc; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index a9bc68e5..cdacb000 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -237,10 +237,10 @@ namespace dxvk { void DxvkDevice::waitForIdle() { - m_submissionQueue.synchronize(); - + this->lockSubmission(); if (m_vkd->vkDeviceWaitIdle(m_vkd->device()) != VK_SUCCESS) Logger::err("DxvkDevice: waitForIdle: Operation failed"); + this->unlockSubmission(); } diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 623db231..fe247f29 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -198,7 +198,7 @@ namespace dxvk::vk { // Create one set of semaphores per swap image m_semaphores.resize(m_info.imageCount); - for (uint32_t i = 0; i < m_info.imageCount; i++) { + for (uint32_t i = 0; i < m_semaphores.size(); i++) { VkFenceCreateInfo fenceInfo; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.pNext = nullptr; @@ -399,8 +399,6 @@ namespace dxvk::vk { void Presenter::destroySwapchain() { - m_vkd->vkDeviceWaitIdle(m_vkd->device()); - for (const auto& img : m_images) m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr); diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index c78444d6..c01672c3 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -160,7 +160,9 @@ namespace dxvk::vk { /** * \brief Changes presenter properties * - * Recreates the swap chain immediately. + * Recreates the swap chain immediately. Note that + * no swap chain resources must be in use by the + * GPU at the time this is called. * \param [in] desc Swap chain description */ VkResult recreateSwapChain(