summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-01-03 04:26:08 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-01-03 04:26:08 +0000
commite77960b3b4382b18c42094760e0df4e79520f416 (patch)
tree6f7adb5b66799d2f1f3adf40b32f1b06b4f7b3dc /Graphics/GraphicsEngineVulkan
parentUpdated glslang module (fixed linux build error) (diff)
downloadDiligentCore-e77960b3b4382b18c42094760e0df4e79520f416.tar.gz
DiligentCore-e77960b3b4382b18c42094760e0df4e79520f416.zip
Added swap chain recovery if acquire next image fails in Vulkan backend
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp40
2 files changed, 27 insertions, 15 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h
index 8d830cbc..aada3ab5 100644
--- a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h
@@ -71,7 +71,7 @@ public:
private:
void CreateVulkanSwapChain();
void InitBuffersAndViews();
- void AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk);
+ VkResult AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk);
void RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtxVk);
std::shared_ptr<const VulkanUtilities::VulkanInstance> m_VulkanInstance;
diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp
index 7abde39d..f3837886 100644
--- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp
@@ -97,7 +97,8 @@ SwapChainVkImpl::SwapChainVkImpl(IReferenceCounters* pRefCounters,
CreateVulkanSwapChain();
InitBuffersAndViews();
- AcquireNextImage(pDeviceContextVk);
+ auto res = AcquireNextImage(pDeviceContextVk);
+ DEV_CHECK_ERR(res == VK_SUCCESS, "Failed to acquire next image for the newly created swap chain"); (void)res;
}
void SwapChainVkImpl::CreateVulkanSwapChain()
@@ -400,24 +401,27 @@ void SwapChainVkImpl::InitBuffersAndViews()
m_pDepthBufferDSV = RefCntAutoPtr<ITextureViewVk>(pDSV, IID_TextureViewVk);
}
-void SwapChainVkImpl::AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk)
+VkResult SwapChainVkImpl::AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk)
{
auto* pDeviceVk = m_pRenderDevice.RawPtr<RenderDeviceVkImpl>();
const auto& LogicalDevice = pDeviceVk->GetLogicalDevice();
auto res = vkAcquireNextImageKHR(LogicalDevice.GetVkDevice(), m_VkSwapChain, UINT64_MAX, m_ImageAcquiredSemaphores[m_SemaphoreIndex], (VkFence)nullptr, &m_BackBufferIndex);
- VERIFY(res == VK_SUCCESS, "Failed to acquire next swap chain image"); (void)res;
-
- // Next command in the device context must wait for the next image to be acquired
- // Unlike fences or events, the act of waiting for a semaphore also unsignals that semaphore (6.4.2)
- pDeviceCtxVk->AddWaitSemaphore(m_ImageAcquiredSemaphores[m_SemaphoreIndex], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
- if (!m_SwapChainImagesInitialized[m_BackBufferIndex])
+ if (res == VK_SUCCESS)
{
- // Vulkan validation layers do not like uninitialized memory.
- // Clear back buffer first time we acquire it. This will use vkCmdClearColorImage()
- pDeviceCtxVk->ClearRenderTarget(GetCurrentBackBufferRTV(), nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
- m_SwapChainImagesInitialized[m_BackBufferIndex] = true;
+ // Next command in the device context must wait for the next image to be acquired
+ // Unlike fences or events, the act of waiting for a semaphore also unsignals that semaphore (6.4.2)
+ pDeviceCtxVk->AddWaitSemaphore(m_ImageAcquiredSemaphores[m_SemaphoreIndex], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+ if (!m_SwapChainImagesInitialized[m_BackBufferIndex])
+ {
+ // Vulkan validation layers do not like uninitialized memory.
+ // Clear back buffer first time we acquire it. This will use vkCmdClearColorImage()
+ pDeviceCtxVk->ClearRenderTarget(GetCurrentBackBufferRTV(), nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ m_SwapChainImagesInitialized[m_BackBufferIndex] = true;
+ }
}
+
+ return res;
}
IMPLEMENT_QUERY_INTERFACE( SwapChainVkImpl, IID_SwapChainVk, TSwapChainBase )
@@ -489,7 +493,14 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval)
if (m_SemaphoreIndex >= m_SwapChainDesc.BufferCount)
m_SemaphoreIndex = 0;
- AcquireNextImage(pImmediateCtxVk);
+ auto res = AcquireNextImage(pImmediateCtxVk);
+ if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR)
+ {
+ RecreateVulkanSwapchain(pImmediateCtxVk);
+ m_SemaphoreIndex = m_SwapChainDesc.BufferCount-1; // To start with 0 index when acquire next image
+ res = AcquireNextImage(pImmediateCtxVk);
+ }
+ DEV_CHECK_ERR(res == VK_SUCCESS, "Failed to acquire next swap chain image");
if (IsDefaultFBBound)
{
@@ -542,7 +553,8 @@ void SwapChainVkImpl::Resize( Uint32 NewWidth, Uint32 NewHeight )
bool bIsDefaultFBBound = pImmediateCtxVk->IsDefaultFBBound();
RecreateVulkanSwapchain(pImmediateCtxVk);
- AcquireNextImage(pImmediateCtxVk);
+ auto res = AcquireNextImage(pImmediateCtxVk);
+ DEV_CHECK_ERR(res == VK_SUCCESS, "Failed to acquire next image for the just resized swap chain"); (void)res;
if( bIsDefaultFBBound )
{