@@ -54,9 +54,9 @@ SwapChainVkImpl::SwapChainVkImpl(IReferenceCounters* pRefCounters,
5454 CreateSurface ();
5555 CreateVulkanSwapChain ();
5656 InitBuffersAndViews ();
57- VkResult res = AcquireNextImage (pDeviceContextVk);
58- DEV_CHECK_ERR (res == VK_SUCCESS, " Failed to acquire next image for the newly created swap chain " );
59- ( void )res;
57+
58+ AcquireNextImage (pDeviceContextVk );
59+ // Note that the image may be immediately out of date.
6060
6161 FenceDesc FenceCI;
6262 FenceCI.Name = " Swap chain frame complete fence" ;
@@ -619,8 +619,9 @@ VkResult SwapChainVkImpl::AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk)
619619
620620 RefCntAutoPtr<ManagedSemaphore>& ImageAcquiredSemaphore = m_ImageAcquiredSemaphores[m_SemaphoreIndex];
621621
622- VkResult res = vkAcquireNextImageKHR (LogicalDevice.GetVkDevice (), m_VkSwapChain, UINT64_MAX, ImageAcquiredSemaphore->Get (), VK_NULL_HANDLE, &m_BackBufferIndex);
623- if (res == VK_SUCCESS)
622+ VkResult res = vkAcquireNextImageKHR (LogicalDevice.GetVkDevice (), m_VkSwapChain, UINT64_MAX, ImageAcquiredSemaphore->Get (), VK_NULL_HANDLE, &m_BackBufferIndex);
623+ m_ImageAcquired = (res == VK_SUCCESS || res == VK_SUBOPTIMAL_KHR);
624+ if (m_ImageAcquired)
624625 {
625626 // Next command in the device context must wait for the next image to be acquired.
626627 // Unlike fences or events, the act of waiting for a semaphore also unsignals that semaphore.
@@ -665,7 +666,7 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval)
665666 // a separate semaphore per swapchain image and index these semaphores using the index of the acquired image
666667 // https://github.com/DiligentGraphics/DiligentCore/issues/682
667668 RefCntAutoPtr<ManagedSemaphore>& DrawCompleteSemaphore = m_DrawCompleteSemaphores[m_BackBufferIndex];
668- if (!m_IsMinimized)
669+ if (m_ImageAcquired && !m_IsMinimized)
669670 {
670671 // TransitionImageLayout() never triggers flush
671672 pImmediateCtxVk->TransitionImageLayout (pBackBuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
@@ -679,26 +680,28 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval)
679680
680681 if (!m_IsMinimized)
681682 {
682- VkPresentInfoKHR PresentInfo = {};
683-
684- PresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
685- PresentInfo.pNext = nullptr ;
686- PresentInfo.waitSemaphoreCount = 1 ;
687- // Unlike fences or events, the act of waiting for a semaphore also unsignals that semaphore
688- VkSemaphore WaitSemaphore[] = {DrawCompleteSemaphore->Get ()};
689- PresentInfo.pWaitSemaphores = WaitSemaphore;
690- PresentInfo.swapchainCount = 1 ;
691- PresentInfo.pSwapchains = &m_VkSwapChain;
692- PresentInfo.pImageIndices = &m_BackBufferIndex;
693- VkResult Result = VK_SUCCESS;
694- PresentInfo.pResults = &Result;
695- pDeviceVk->LockCmdQueueAndRun (
696- pImmediateCtxVk->GetCommandQueueId (),
697- [&PresentInfo](ICommandQueueVk* pCmdQueueVk) //
698- {
699- pCmdQueueVk->Present (PresentInfo);
700- } //
701- );
683+ VkResult Result = VK_ERROR_OUT_OF_DATE_KHR;
684+ if (m_ImageAcquired)
685+ {
686+ VkPresentInfoKHR PresentInfo{};
687+ PresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
688+ PresentInfo.pNext = nullptr ;
689+ PresentInfo.waitSemaphoreCount = 1 ;
690+ // Unlike fences or events, the act of waiting for a semaphore also unsignals that semaphore
691+ VkSemaphore WaitSemaphore[] = {DrawCompleteSemaphore->Get ()};
692+ PresentInfo.pWaitSemaphores = WaitSemaphore;
693+ PresentInfo.swapchainCount = 1 ;
694+ PresentInfo.pSwapchains = &m_VkSwapChain;
695+ PresentInfo.pImageIndices = &m_BackBufferIndex;
696+ PresentInfo.pResults = &Result;
697+ pDeviceVk->LockCmdQueueAndRun (
698+ pImmediateCtxVk->GetCommandQueueId (),
699+ [&PresentInfo](ICommandQueueVk* pCmdQueueVk) //
700+ {
701+ pCmdQueueVk->Present (PresentInfo);
702+ } //
703+ );
704+ }
702705
703706 if (Result == VK_SUBOPTIMAL_KHR || Result == VK_ERROR_OUT_OF_DATE_KHR)
704707 {
@@ -745,7 +748,7 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval)
745748 }
746749#endif
747750 }
748- DEV_CHECK_ERR (res == VK_SUCCESS, " Failed to acquire next swap chain image " );
751+ // The image may still be out of date if the window keeps changing size
749752 }
750753}
751754
@@ -919,9 +922,8 @@ void SwapChainVkImpl::Resize(Uint32 NewWidth, Uint32 NewHeight, SURFACE_TRANSFOR
919922 // RecreateVulkanSwapchain() unbinds default FB
920923 RecreateVulkanSwapchain (pImmediateCtxVk);
921924
922- VkResult res = AcquireNextImage (pImmediateCtxVk);
923- DEV_CHECK_ERR (res == VK_SUCCESS, " Failed to acquire next image for the just resized swap chain" );
924- (void )res;
925+ AcquireNextImage (pImmediateCtxVk);
926+ // The image may be immediately out of date if the window keeps being resized
925927 }
926928 catch (const std::runtime_error&)
927929 {
0 commit comments