@@ -558,19 +558,11 @@ void GPUDisplayBackendVulkan::createSemaphoresAndFences()
558558 vk::FenceCreateInfo fenceInfo{};
559559 fenceInfo.flags = vk::FenceCreateFlagBits::eSignaled;
560560 mImageAvailableSemaphore .resize (mFramesInFlight );
561- mRenderFinishedSemaphore .resize (mFramesInFlight );
562- mTextFinishedSemaphore .resize (mFramesInFlight );
563- mMixFinishedSemaphore .resize (mFramesInFlight );
564- mDownsampleFinishedSemaphore .resize (mFramesInFlight );
565561 mPresentSemaphore .resize (mImageCount );
566562 mInFlightFence .resize (mFramesInFlight );
567563 mImageFence .resize (mImageCount );
568564 for (uint32_t i = 0 ; i < mFramesInFlight ; i++) {
569565 mImageAvailableSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
570- mRenderFinishedSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
571- mTextFinishedSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
572- mMixFinishedSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
573- mDownsampleFinishedSemaphore [i] = mDevice .createSemaphore (semaphoreInfo, nullptr );
574566 mInFlightFence [i] = mDevice .createFence (fenceInfo, nullptr );
575567 }
576568 for (uint32_t i = 0 ; i < mImageCount ; i++) {
@@ -584,10 +576,6 @@ void GPUDisplayBackendVulkan::createSemaphoresAndFences()
584576void GPUDisplayBackendVulkan::clearSemaphoresAndFences ()
585577{
586578 clearVector (mImageAvailableSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
587- clearVector (mRenderFinishedSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
588- clearVector (mTextFinishedSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
589- clearVector (mMixFinishedSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
590- clearVector (mDownsampleFinishedSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
591579 clearVector (mPresentSemaphore , [&](auto & x) { mDevice .destroySemaphore (x, nullptr ); });
592580 clearVector (mInFlightFence , [&](auto & x) { mDevice .destroyFence (x, nullptr ); });
593581 mDevice .destroyFence (mSingleCommitFence , nullptr );
@@ -861,22 +849,25 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo
861849 colorAttachmentRef.attachment = nAttachments++;
862850 colorAttachmentRef.layout = vk::ImageLayout::eColorAttachmentOptimal;
863851 vk::AttachmentReference depthAttachmentRef{};
864- // depthAttachmentRef.attachment // below
865852 depthAttachmentRef.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
866853 vk::AttachmentReference colorAttachmentResolveRef{};
867- // colorAttachmentResolveRef.attachment // below
868854 colorAttachmentResolveRef.layout = vk::ImageLayout::eColorAttachmentOptimal;
869855 vk::SubpassDescription subpass{};
870856 subpass.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
871857 subpass.colorAttachmentCount = 1 ;
872858 subpass.pColorAttachments = &colorAttachmentRef;
873- vk::SubpassDependency dependency{};
874- dependency.srcSubpass = VK_SUBPASS_EXTERNAL ;
875- dependency.dstSubpass = 0 ;
876- dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests;
877- dependency.srcAccessMask = {};
878- dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests;
879- dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
859+ std::array<vk::SubpassDependency, 2 > dependencies{};
860+ dependencies[0 ].srcSubpass = dependencies[1 ].dstSubpass = VK_SUBPASS_EXTERNAL ;
861+ dependencies[0 ].dstSubpass = 0 ;
862+ dependencies[0 ].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests | vk::PipelineStageFlagBits::eTransfer | vk::PipelineStageFlagBits::eFragmentShader; // Includes eColorAttachmentOutput, the wait stage of the image acquire semaphore
863+ dependencies[0 ].srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite | vk::AccessFlagBits::eTransferWrite;
864+ dependencies[0 ].dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests;
865+ dependencies[0 ].dstAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
866+ dependencies[1 ].srcSubpass = 0 ;
867+ dependencies[1 ].srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eLateFragmentTests;
868+ dependencies[1 ].srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
869+ dependencies[1 ].dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eTransfer | vk::PipelineStageFlagBits::eFragmentShader;
870+ dependencies[1 ].dstAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eTransferRead | vk::AccessFlagBits::eShaderRead;
880871
881872 std::vector<vk::AttachmentDescription> attachments = {colorAttachment};
882873 if (mZActive ) {
@@ -895,8 +886,8 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo
895886 renderPassInfo.pAttachments = attachments.data ();
896887 renderPassInfo.subpassCount = 1 ;
897888 renderPassInfo.pSubpasses = &subpass;
898- renderPassInfo.dependencyCount = 1 ;
899- renderPassInfo.pDependencies = &dependency ;
889+ renderPassInfo.dependencyCount = dependencies. size () ;
890+ renderPassInfo.pDependencies = dependencies. data () ;
900891 mRenderPass = mDevice .createRenderPass (renderPassInfo, nullptr );
901892
902893 const uint32_t imageCountWithMixImages = mImageCount * (mMixingSupported ? 2 : 1 );
@@ -928,11 +919,6 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo
928919 renderPassInfo.pAttachments = &colorAttachment;
929920 subpass.pDepthStencilAttachment = nullptr ;
930921 subpass.pResolveAttachments = nullptr ;
931- if (mFramebuffersText .size ()) {
932- dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput; // Remove early fragment test
933- dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
934- dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite; // Remove depth/stencil dependencies
935- }
936922 colorAttachment.loadOp = vk::AttachmentLoadOp::eLoad; // Don't clear the frame buffer
937923 colorAttachment.initialLayout = vk::ImageLayout::ePresentSrcKHR; // Initial layout is not undefined after 1st pass
938924 colorAttachment.samples = vk::SampleCountFlagBits::e1 ; // No MSAA for Text
@@ -944,11 +930,6 @@ void GPUDisplayBackendVulkan::createOffscreenBuffers(bool forScreenshot, bool fo
944930 colorAttachment.initialLayout = vk::ImageLayout::eColorAttachmentOptimal;
945931 colorAttachment.finalLayout = mDownsampleFSAA ? vk::ImageLayout::eColorAttachmentOptimal : vk::ImageLayout::ePresentSrcKHR;
946932 }
947- if (mFramebuffersTexture .size ()) {
948- dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput; // Remove early fragment test
949- dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
950- dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite; // Remove depth/stencil dependencies
951- }
952933 mRenderPassTexture = mDevice .createRenderPass (renderPassInfo, nullptr );
953934 }
954935
@@ -1553,6 +1534,7 @@ void GPUDisplayBackendVulkan::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
15531534 CHKERR (mDevice .resetFences (1 , &mInFlightFence [mCurrentFrame ]));
15541535
15551536 mHasDrawnText = false ;
1537+ mFrameCommandBuffers .clear ();
15561538 const hmm_mat4 modelViewProj = proj * view;
15571539 writeToBuffer (mUniformBuffersMat [0 ][mCurrentImageIndex ], sizeof (modelViewProj), &modelViewProj);
15581540 }
@@ -1562,7 +1544,6 @@ void GPUDisplayBackendVulkan::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
15621544 if (!mCommandBufferUpToDate [mCurrentImageIndex ]) {
15631545 startFillCommandBuffer (mCurrentCommandBuffer , mCurrentImageIndex , toMixBuffer);
15641546 }
1565- mSubmitQueue .clear ();
15661547}
15671548
15681549void GPUDisplayBackendVulkan::finishDraw (bool doScreenshot, bool toMixBuffer, float includeMixImage)
@@ -1577,73 +1558,46 @@ void GPUDisplayBackendVulkan::finishDraw(bool doScreenshot, bool toMixBuffer, fl
15771558
15781559void GPUDisplayBackendVulkan::finishFrame (bool doScreenshot, bool toMixBuffer, float includeMixImage)
15791560{
1580- vk::Semaphore* stageFinishedSemaphore = &mRenderFinishedSemaphore [mCurrentFrame ];
1581-
1582- vk::SubmitInfo submitInfo{};
1583- vk::PipelineStageFlags waitStages[] = {vk::PipelineStageFlagBits::eColorAttachmentOutput};
1584- submitInfo.pWaitSemaphores = includeMixImage > 0 .f ? &mRenderFinishedSemaphore [mCurrentFrame ] : &mImageAvailableSemaphore [mCurrentFrame ];
1585- submitInfo.waitSemaphoreCount = 1 ;
1586- submitInfo.pWaitDstStageMask = waitStages;
1587- submitInfo.commandBufferCount = 1 ;
1588- submitInfo.pCommandBuffers = &mCurrentCommandBuffer ;
1589- submitInfo.signalSemaphoreCount = 1 ;
1590- submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1591- mSubmitQueue .emplace_back (submitInfo);
1592-
1561+ mFrameCommandBuffers .emplace_back (mCurrentCommandBuffer );
15931562 if (!toMixBuffer) {
15941563 if (includeMixImage > 0 .f ) {
15951564 mixImages (mCommandBuffersTexture [mCurrentImageIndex ], includeMixImage);
1596- submitInfo.pWaitSemaphores = stageFinishedSemaphore;
1597- waitStages[0 ] = {vk::PipelineStageFlagBits::eColorAttachmentOutput};
1598- submitInfo.waitSemaphoreCount = 1 ;
1599- submitInfo.pCommandBuffers = &mCommandBuffersTexture [mCurrentImageIndex ];
1600- stageFinishedSemaphore = &mMixFinishedSemaphore [mCurrentFrame ];
1601- submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1602- mSubmitQueue .emplace_back (submitInfo);
1565+ mFrameCommandBuffers .emplace_back (mCommandBuffersTexture [mCurrentImageIndex ]);
16031566 }
1604-
16051567 if (mDownsampleFSAA ) {
16061568 downsampleToFramebuffer (mCommandBuffersDownsample [mCurrentImageIndex ]);
1607- submitInfo.pCommandBuffers = &mCommandBuffersDownsample [mCurrentImageIndex ];
1608- submitInfo.pWaitSemaphores = stageFinishedSemaphore;
1609- waitStages[0 ] = {vk::PipelineStageFlagBits::eTransfer};
1610- submitInfo.waitSemaphoreCount = 1 ;
1611- stageFinishedSemaphore = &mDownsampleFinishedSemaphore [mCurrentFrame ];
1612- submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1613- mSubmitQueue .emplace_back (submitInfo);
1569+ mFrameCommandBuffers .emplace_back (mCommandBuffersDownsample [mCurrentImageIndex ]);
16141570 }
16151571
1572+ vk::PipelineStageFlags waitStage = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eTransfer;
1573+ vk::SubmitInfo submitInfo{};
1574+ submitInfo.waitSemaphoreCount = 1 ;
1575+ submitInfo.pWaitSemaphores = &mImageAvailableSemaphore [mCurrentFrame ];
1576+ submitInfo.pWaitDstStageMask = &waitStage;
16161577 if (doScreenshot) {
1617- CHKERR (mGraphicsQueue .submit (mSubmitQueue .size (), mSubmitQueue .data (), VkFence (VK_NULL_HANDLE )));
1578+ submitInfo.commandBufferCount = mFrameCommandBuffers .size ();
1579+ submitInfo.pCommandBuffers = mFrameCommandBuffers .data ();
1580+ CHKERR (mGraphicsQueue .submit (1 , &submitInfo, VkFence (VK_NULL_HANDLE )));
16181581 mDevice .waitIdle ();
16191582 if (mDisplay ->cfgR ().screenshotScaleFactor != 1 ) {
16201583 readImageToPixels (mDownsampleImages [mCurrentImageIndex ].image , vk::ImageLayout::eColorAttachmentOptimal, mScreenshotPixels );
16211584 } else {
16221585 readImageToPixels (mSwapChainImages [mCurrentImageIndex ], vk::ImageLayout::ePresentSrcKHR, mScreenshotPixels );
16231586 }
1624- mSubmitQueue .clear ();
1587+ mFrameCommandBuffers .clear ();
1588+ submitInfo.waitSemaphoreCount = 0 ;
16251589 }
1626-
16271590 if (mHasDrawnText ) {
1628- submitInfo.pWaitSemaphores = stageFinishedSemaphore;
1629- waitStages[0 ] = {vk::PipelineStageFlagBits::eColorAttachmentOutput};
1630- submitInfo.waitSemaphoreCount = 1 ;
1631- submitInfo.pCommandBuffers = &mCommandBuffersText [mCurrentImageIndex ];
1632- stageFinishedSemaphore = &mTextFinishedSemaphore [mCurrentFrame ];
1633- submitInfo.pSignalSemaphores = stageFinishedSemaphore;
1634- mSubmitQueue .emplace_back (submitInfo);
1635- }
1636-
1637- if (mSubmitQueue .size ()) {
1638- vk::SubmitInfo& submitInfoLast = mSubmitQueue .back ();
1639- vk::PipelineStageFlags presentWaitStage = vk::PipelineStageFlagBits::eAllCommands; // Last commit signals to present
1640- submitInfoLast.pWaitDstStageMask = &presentWaitStage;
1641- submitInfoLast.pSignalSemaphores = &mPresentSemaphore [mCurrentImageIndex ];
1642- CHKERR (mGraphicsQueue .submit (mSubmitQueue .size (), mSubmitQueue .data (), mInFlightFence [mCurrentFrame ]));
1591+ mFrameCommandBuffers .emplace_back (mCommandBuffersText [mCurrentImageIndex ]);
16431592 }
1593+ submitInfo.commandBufferCount = mFrameCommandBuffers .size ();
1594+ submitInfo.pCommandBuffers = mFrameCommandBuffers .data ();
1595+ submitInfo.signalSemaphoreCount = 1 ;
1596+ submitInfo.pSignalSemaphores = &mPresentSemaphore [mCurrentImageIndex ];
1597+ CHKERR (mGraphicsQueue .submit (1 , &submitInfo, mInFlightFence [mCurrentFrame ]));
16441598
16451599 vk::PresentInfoKHR presentInfo{};
1646- presentInfo.waitSemaphoreCount = mSubmitQueue . size () ? 1 : 0 ;
1600+ presentInfo.waitSemaphoreCount = 1 ;
16471601 presentInfo.pWaitSemaphores = &mPresentSemaphore [mCurrentImageIndex ];
16481602 presentInfo.swapchainCount = 1 ;
16491603 presentInfo.pSwapchains = &mSwapChain ;
@@ -1666,7 +1620,7 @@ void GPUDisplayBackendVulkan::downsampleToFramebuffer(vk::CommandBuffer& command
16661620 commandBuffer.begin (beginInfo);
16671621
16681622 cmdImageMemoryBarrier (commandBuffer, mSwapChainImages [mCurrentImageIndex ], {}, vk::AccessFlagBits::eTransferWrite, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer);
1669- cmdImageMemoryBarrier (commandBuffer, mDownsampleImages [mCurrentImageIndex ].image , vk::AccessFlagBits::eMemoryRead , vk::AccessFlagBits::eTransferRead, vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits::eTransfer , vk::PipelineStageFlagBits::eTransfer);
1623+ cmdImageMemoryBarrier (commandBuffer, mDownsampleImages [mCurrentImageIndex ].image , vk::AccessFlagBits::eColorAttachmentWrite , vk::AccessFlagBits::eTransferRead, vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits::eColorAttachmentOutput , vk::PipelineStageFlagBits::eTransfer);
16701624
16711625 vk::Offset3D blitSizeSrc;
16721626 blitSizeSrc.x = mRenderWidth ;
@@ -1685,8 +1639,8 @@ void GPUDisplayBackendVulkan::downsampleToFramebuffer(vk::CommandBuffer& command
16851639 imageBlitRegion.dstOffsets [1 ] = blitSizeDst;
16861640 commandBuffer.blitImage (mDownsampleImages [mCurrentImageIndex ].image , vk::ImageLayout::eTransferSrcOptimal, mSwapChainImages [mCurrentImageIndex ], vk::ImageLayout::eTransferDstOptimal, 1 , &imageBlitRegion, vk::Filter::eLinear);
16871641
1688- cmdImageMemoryBarrier (commandBuffer, mSwapChainImages [mCurrentImageIndex ], vk::AccessFlagBits::eTransferWrite, vk::AccessFlagBits::eMemoryRead , vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::ePresentSrcKHR, vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer);
1689- cmdImageMemoryBarrier (commandBuffer, mDownsampleImages [mCurrentImageIndex ].image , vk::AccessFlagBits::eTransferRead , vk::AccessFlagBits::eMemoryRead , vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal, vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer);
1642+ cmdImageMemoryBarrier (commandBuffer, mSwapChainImages [mCurrentImageIndex ], vk::AccessFlagBits::eTransferWrite, vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite , vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::ePresentSrcKHR, vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eColorAttachmentOutput); // Next: text pass, or present (ordered by the present semaphore)
1643+ cmdImageMemoryBarrier (commandBuffer, mDownsampleImages [mCurrentImageIndex ].image , {} , vk::AccessFlagBits::eColorAttachmentWrite , vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal, vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eColorAttachmentOutput); // Next frame renders into it again
16901644
16911645 commandBuffer.end ();
16921646}
@@ -1753,7 +1707,7 @@ void GPUDisplayBackendVulkan::mixImages(vk::CommandBuffer commandBuffer, float m
17531707
17541708 vk::Image& image = mDownsampleFSAA ? mDownsampleImages [mCurrentImageIndex + mImageCount ].image : mMixImages [mCurrentImageIndex ].image ;
17551709 vk::ImageLayout srcLayout = mDownsampleFSAA ? vk::ImageLayout::eColorAttachmentOptimal : vk::ImageLayout::ePresentSrcKHR;
1756- cmdImageMemoryBarrier (commandBuffer, image, {} , vk::AccessFlagBits::eMemoryRead , srcLayout, vk::ImageLayout::eShaderReadOnlyOptimal, vk::PipelineStageFlagBits::eAllCommands , vk::PipelineStageFlagBits::eFragmentShader);
1710+ cmdImageMemoryBarrier (commandBuffer, image, vk::AccessFlagBits::eColorAttachmentWrite , vk::AccessFlagBits::eShaderRead , srcLayout, vk::ImageLayout::eShaderReadOnlyOptimal, vk::PipelineStageFlagBits::eColorAttachmentOutput , vk::PipelineStageFlagBits::eFragmentShader);
17571711
17581712 vk::RenderPassBeginInfo renderPassInfo{};
17591713 renderPassInfo.renderPass = mRenderPassTexture ;
0 commit comments