Skip to content

Commit f36e638

Browse files
Vulkan swap chain: throttle frame submission when window is minimized (fix #600)
1 parent 5f08020 commit f36e638

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class SwapChainVkImpl final : public SwapChainBase<ISwapChainVk>
9090
VkResult AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk);
9191
void RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtxVk);
9292
void ReleaseSwapChainResources(DeviceContextVkImpl* pImmediateCtxVk, bool DestroyVkSwapChain);
93+
void ThrottleFrameSubmission();
9394

9495
const NativeWindow m_Window;
9596

Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ SwapChainVkImpl::SwapChainVkImpl(IReferenceCounters* pRefCounters,
5757

5858
AcquireNextImage(pDeviceContextVk);
5959
// Note that the image may be immediately out of date.
60+
// https://github.com/DiligentGraphics/DiligentCore/issues/632
6061

6162
FenceDesc FenceCI;
6263
FenceCI.Name = "Swap chain frame complete fence";
@@ -597,6 +598,14 @@ void SwapChainVkImpl::InitBuffersAndViews()
597598
}
598599
}
599600

601+
void SwapChainVkImpl::ThrottleFrameSubmission()
602+
{
603+
if (m_FrameIndex > m_SwapChainDesc.BufferCount)
604+
{
605+
m_FrameCompleteFence->Wait(m_FrameIndex - m_SwapChainDesc.BufferCount);
606+
}
607+
}
608+
600609
VkResult SwapChainVkImpl::AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk)
601610
{
602611
RenderDeviceVkImpl* pDeviceVk = m_pRenderDevice.RawPtr<RenderDeviceVkImpl>();
@@ -612,10 +621,7 @@ VkResult SwapChainVkImpl::AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk)
612621
// vkAcquireNextImageKHR requires that the semaphore is not in use, so we must wait
613622
// for the frame (FrameIndex - BufferCount) to complete.
614623
// This also ensures that there are no more than BufferCount frames in flight at any time.
615-
if (m_FrameIndex > m_SwapChainDesc.BufferCount)
616-
{
617-
m_FrameCompleteFence->Wait(m_FrameIndex - m_SwapChainDesc.BufferCount);
618-
}
624+
ThrottleFrameSubmission();
619625

620626
RefCntAutoPtr<ManagedSemaphore>& ImageAcquiredSemaphore = m_ImageAcquiredSemaphores[m_SemaphoreIndex];
621627

@@ -673,14 +679,15 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval)
673679
// The context can be empty if no render commands were issued by the app
674680
//VERIFY(pImmediateCtxVk->GetNumCommandsInCtx() != 0, "The context must not be flushed");
675681
pImmediateCtxVk->AddSignalSemaphore(DrawCompleteSemaphore);
676-
pImmediateCtxVk->EnqueueSignal(m_FrameCompleteFence, m_FrameIndex++);
677682
}
678683

684+
pImmediateCtxVk->EnqueueSignal(m_FrameCompleteFence, m_FrameIndex++);
679685
pImmediateCtxVk->Flush();
680686

681687
if (!m_IsMinimized)
682688
{
683689
VkResult Result = VK_ERROR_OUT_OF_DATE_KHR;
690+
// Only present if the image was acquired successfully
684691
if (m_ImageAcquired)
685692
{
686693
VkPresentInfoKHR PresentInfo{};
@@ -750,6 +757,12 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval)
750757
}
751758
// The image may still be out of date if the window keeps changing size
752759
}
760+
else
761+
{
762+
// Throttle frame submission to make sure that resources are released
763+
// https://github.com/DiligentGraphics/DiligentSamples/issues/234
764+
ThrottleFrameSubmission();
765+
}
753766
}
754767

755768
void SwapChainVkImpl::ReleaseSwapChainResources(DeviceContextVkImpl* pImmediateCtxVk, bool DestroyVkSwapChain)

0 commit comments

Comments
 (0)