@@ -562,7 +562,9 @@ void GPUDisplayBackendVulkan::createSemaphoresAndFences()
562562 mTextFinishedSemaphore .resize (mFramesInFlight );
563563 mMixFinishedSemaphore .resize (mFramesInFlight );
564564 mDownsampleFinishedSemaphore .resize (mFramesInFlight );
565+ mPresentSemaphore .resize (mImageCount );
565566 mInFlightFence .resize (mFramesInFlight );
567+ mImageFence .resize (mImageCount );
566568 for (uint32_t i = 0 ; i < mFramesInFlight ; i++) {
567569 mImageAvailableSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
568570 mRenderFinishedSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
@@ -571,6 +573,10 @@ void GPUDisplayBackendVulkan::createSemaphoresAndFences()
571573 mDownsampleFinishedSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
572574 mInFlightFence [i] = mDevice .createFence (fenceInfo, nullptr );
573575 }
576+ for (uint32_t i = 0 ; i < mImageCount ; i++) {
577+ mPresentSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
578+ mImageFence [i] = VkFence (VK_NULL_HANDLE );
579+ }
574580 fenceInfo.flags = {};
575581 mSingleCommitFence = mDevice .createFence (fenceInfo, nullptr );
576582}
@@ -582,6 +588,7 @@ void GPUDisplayBackendVulkan::clearSemaphoresAndFences()
582588 clearVector (mTextFinishedSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
583589 clearVector (mMixFinishedSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
584590 clearVector (mDownsampleFinishedSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
591+ clearVector (mPresentSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
585592 clearVector (mInFlightFence , [&](auto & x) { mDevice .destroyFence (x, nullptr ); });
586593 mDevice .destroyFence (mSingleCommitFence , nullptr );
587594}
@@ -768,11 +775,11 @@ void GPUDisplayBackendVulkan::createSwapChain(bool forScreenshot, bool forMixing
768775 mSwapChain = mDevice .createSwapchainKHR (swapCreateInfo, nullptr );
769776
770777 mSwapChainImages = mDevice .getSwapchainImagesKHR (mSwapChain );
771- uint32_t oldFramesInFlight = mFramesInFlight ;
778+ uint32_t oldFramesInFlight = mFramesInFlight , oldImageCount = mImageCount ;
772779 mFramesInFlight = mDisplay ->cfg ().vulkan .nFramesInFlight ;
773780 mImageCount = mSwapChainImages .size ();
774781
775- if (mFramesInFlight > oldFramesInFlight || !mCommandInfrastructureCreated ) {
782+ if (mFramesInFlight != oldFramesInFlight || mImageCount != oldImageCount || !mCommandInfrastructureCreated ) {
776783 if (mCommandInfrastructureCreated ) {
777784 clearUniformLayoutsAndBuffers (); // TODO: Check what must actually be cleaned up if frames in flight changes
778785 clearCommandBuffers ();
@@ -1522,12 +1529,7 @@ void GPUDisplayBackendVulkan::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
15221529 mCurrentFrame = (mCurrentFrame + 1 ) % mFramesInFlight ;
15231530 CHKERR (mDevice .waitForFences (1 , &mInFlightFence [mCurrentFrame ], true , UINT64_MAX ));
15241531 auto getImage = [&]() {
1525- vk::Fence fen = VkFence (VK_NULL_HANDLE );
1526- vk::Semaphore sem = VkSemaphore (VK_NULL_HANDLE );
1527- fen = mInFlightFence [mCurrentFrame ];
1528- CHKERR (mDevice .resetFences (1 , &fen));
1529- // sem = mImageAvailableSemaphore[mCurrentFrame]; // TODO: Why not !
1530- return mDevice .acquireNextImageKHR (mSwapChain , UINT64_MAX , sem, fen, &mCurrentImageIndex );
1532+ return mDevice .acquireNextImageKHR (mSwapChain , UINT64_MAX , mImageAvailableSemaphore [mCurrentFrame ], VkFence (VK_NULL_HANDLE ), &mCurrentImageIndex );
15311533 };
15321534
15331535 vk::Result retVal = vk::Result::eSuccess;
@@ -1545,8 +1547,12 @@ void GPUDisplayBackendVulkan::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
15451547 retVal = getImage ();
15461548 }
15471549 CHKERR (retVal);
1548- CHKERR (mDevice .waitForFences (1 , &mInFlightFence [mCurrentFrame ], true , UINT64_MAX ));
1550+ if (mImageFence [mCurrentImageIndex ]) {
1551+ CHKERR (mDevice .waitForFences (1 , &mImageFence [mCurrentImageIndex ], true , UINT64_MAX ));
1552+ }
1553+ mImageFence [mCurrentImageIndex ] = mInFlightFence [mCurrentFrame ];
15491554 CHKERR (mDevice .resetFences (1 , &mInFlightFence [mCurrentFrame ]));
1555+
15501556 mMustUpdateSwapChain = false ;
15511557 mHasDrawnText = false ;
15521558
@@ -1578,14 +1584,14 @@ void GPUDisplayBackendVulkan::finishFrame(bool doScreenshot, bool toMixBuffer, f
15781584
15791585 vk::SubmitInfo submitInfo{};
15801586 vk::PipelineStageFlags waitStages[] = {vk::PipelineStageFlagBits::eColorAttachmentOutput};
1581- submitInfo.pWaitSemaphores = includeMixImage > 0 .f ? &mRenderFinishedSemaphore [mCurrentFrame ] : nullptr ;
1582- submitInfo.waitSemaphoreCount = submitInfo. pWaitSemaphores != nullptr ? 1 : 0 ;
1587+ submitInfo.pWaitSemaphores = includeMixImage > 0 .f ? &mRenderFinishedSemaphore [mCurrentFrame ] : & mImageAvailableSemaphore [ mCurrentFrame ] ;
1588+ submitInfo.waitSemaphoreCount = 1 ;
15831589 submitInfo.pWaitDstStageMask = waitStages;
15841590 submitInfo.commandBufferCount = 1 ;
15851591 submitInfo.pCommandBuffers = &mCurrentCommandBuffer ;
15861592 submitInfo.signalSemaphoreCount = 1 ;
15871593 submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1588- CHKERR (mGraphicsQueue .submit (1 , &submitInfo, includeMixImage > 0 || toMixBuffer || mHasDrawnText || mDownsampleFSAA ? noFence : mInFlightFence [ mCurrentFrame ] ));
1594+ CHKERR (mGraphicsQueue .submit (1 , &submitInfo, noFence));
15891595 if (!toMixBuffer) {
15901596 if (includeMixImage > 0 .f ) {
15911597 mixImages (mCommandBuffersTexture [mCurrentImageIndex ], includeMixImage);
@@ -1595,7 +1601,7 @@ void GPUDisplayBackendVulkan::finishFrame(bool doScreenshot, bool toMixBuffer, f
15951601 submitInfo.pCommandBuffers = &mCommandBuffersTexture [mCurrentImageIndex ];
15961602 stageFinishedSemaphore = &mMixFinishedSemaphore [mCurrentFrame ];
15971603 submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1598- CHKERR (mGraphicsQueue .submit (1 , &submitInfo, mHasDrawnText || mDownsampleFSAA ? noFence : mInFlightFence [ mCurrentFrame ] ));
1604+ CHKERR (mGraphicsQueue .submit (1 , &submitInfo, noFence));
15991605 }
16001606
16011607 if (mDownsampleFSAA ) {
@@ -1606,7 +1612,7 @@ void GPUDisplayBackendVulkan::finishFrame(bool doScreenshot, bool toMixBuffer, f
16061612 submitInfo.waitSemaphoreCount = 1 ;
16071613 stageFinishedSemaphore = &mDownsampleFinishedSemaphore [mCurrentFrame ];
16081614 submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1609- CHKERR (mGraphicsQueue .submit (1 , &submitInfo, mHasDrawnText ? noFence : mInFlightFence [ mCurrentFrame ] ));
1615+ CHKERR (mGraphicsQueue .submit (1 , &submitInfo, noFence));
16101616 }
16111617
16121618 if (doScreenshot) {
@@ -1625,13 +1631,21 @@ void GPUDisplayBackendVulkan::finishFrame(bool doScreenshot, bool toMixBuffer, f
16251631 submitInfo.pCommandBuffers = &mCommandBuffersText [mCurrentImageIndex ];
16261632 stageFinishedSemaphore = &mTextFinishedSemaphore [mCurrentFrame ];
16271633 submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1628- CHKERR (mGraphicsQueue .submit (1 , &submitInfo, mInFlightFence [ mCurrentFrame ] ));
1634+ CHKERR (mGraphicsQueue .submit (1 , &submitInfo, noFence ));
16291635 }
16301636
1631- CHKERR (mDevice .waitForFences (1 , &mInFlightFence [mCurrentFrame ], true , UINT64_MAX )); // TODO: I think we need to wait for the fence, so that the image was acquired before we present. Perhaps we can present later to avoid delays
1637+ vk::PipelineStageFlags presentWaitStage = vk::PipelineStageFlagBits::eAllCommands;
1638+ submitInfo.commandBufferCount = 0 ;
1639+ submitInfo.waitSemaphoreCount = 1 ;
1640+ submitInfo.pWaitSemaphores = stageFinishedSemaphore;
1641+ submitInfo.pWaitDstStageMask = &presentWaitStage;
1642+ submitInfo.signalSemaphoreCount = 1 ;
1643+ submitInfo.pSignalSemaphores = &mPresentSemaphore [mCurrentImageIndex ];
1644+ CHKERR (mGraphicsQueue .submit (1 , &submitInfo, mInFlightFence [mCurrentFrame ])); // Empty submit to signal InFlightFence and PresentSemaphore
1645+
16321646 vk::PresentInfoKHR presentInfo{};
16331647 presentInfo.waitSemaphoreCount = 1 ;
1634- presentInfo.pWaitSemaphores = stageFinishedSemaphore ;
1648+ presentInfo.pWaitSemaphores = & mPresentSemaphore [ mCurrentImageIndex ] ;
16351649 presentInfo.swapchainCount = 1 ;
16361650 presentInfo.pSwapchains = &mSwapChain ;
16371651 presentInfo.pImageIndices = &mCurrentImageIndex ;
0 commit comments