From 34c378a2bf25a4ccfaf0c035e9a7c35be6e0ba43 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 20 Mar 2019 20:37:07 -0700 Subject: Fixed one more Vulkan validation error re destroying a fence being in use --- .../GraphicsEngineVulkan/include/SwapChainVkImpl.h | 1 + .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 33 ++++++++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h index c20e7664..d4e3baa9 100644 --- a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h @@ -73,6 +73,7 @@ private: void InitBuffersAndViews(); VkResult AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk); void RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtxVk); + void WaitForImageAcquiredFences(); std::shared_ptr m_VulkanInstance; VkSurfaceKHR m_VkSurface = VK_NULL_HANDLE; diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index 3587d8e7..523f0896 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -334,6 +334,12 @@ SwapChainVkImpl::~SwapChainVkImpl() { auto *pDeviceVkImpl = m_pRenderDevice.RawPtr(); pDeviceVkImpl->IdleGPU(); + + // We need to explicitly wait for all submitted Image Acquired Fences to signal. + // Just idling the GPU is not enough and results in validation warnings. + // As a matter of fact, it is only required to check the fence status. + WaitForImageAcquiredFences(); + vkDestroySwapchainKHR(pDeviceVkImpl->GetVkDevice(), m_VkSwapChain, NULL); } if (m_VkSurface != VK_NULL_HANDLE) @@ -556,14 +562,27 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval) } } +void SwapChainVkImpl::WaitForImageAcquiredFences() +{ + const auto& LogicalDevice = m_pRenderDevice.RawPtr()->GetLogicalDevice(); + for (size_t i=0; i < m_ImageAcquiredFences.size(); ++i) + { + if (m_ImageAcquiredFenceSubmitted[i]) + { + VkFence vkFence = m_ImageAcquiredFences[i]; + if (LogicalDevice.GetFenceStatus(vkFence) != VK_SUCCESS) + LogicalDevice.WaitForFences(1, &vkFence, VK_TRUE, UINT64_MAX); + } + } +} + void SwapChainVkImpl::RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtxVk) { if (pImmediateCtxVk->IsDefaultFBBound()) pImmediateCtxVk->ResetRenderTargets(); RenderDeviceVkImpl* pDeviceVk = m_pRenderDevice.RawPtr(); - const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - + // This will release references to Vk swap chain buffers hold by // m_pBackBufferRTV[]. pDeviceVk->IdleGPU(); @@ -571,15 +590,7 @@ void SwapChainVkImpl::RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtx // We need to explicitly wait for all submitted Image Acquired Fences to signal. // Just idling the GPU is not enough and results in validation warnings. // As a matter of fact, it is only required to check the fence status. - for(size_t i=0; i < m_ImageAcquiredFences.size(); ++i) - { - if (m_ImageAcquiredFenceSubmitted[i]) - { - VkFence vkFence = m_ImageAcquiredFences[i]; - if (LogicalDevice.GetFenceStatus(vkFence) != VK_SUCCESS) - LogicalDevice.WaitForFences(1, &vkFence, VK_TRUE, UINT64_MAX); - } - } + WaitForImageAcquiredFences(); // All references to the swap chain must be released before it can be resized m_pBackBufferRTV.clear(); -- cgit v1.2.3