@@ -810,7 +810,7 @@ void VulkanDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, utils:
810810 assert_invariant (mDefaultRenderTarget ); // Default render target should already exist.
811811
812812 auto renderTarget = resource_ptr<VulkanRenderTarget>::make (&mResourceManager , rth,
813- std::move (std::move ( *mDefaultRenderTarget .get () )));
813+ std::move (*mDefaultRenderTarget .get ()));
814814
815815 mDefaultRenderTarget = renderTarget;
816816 mResourceManager .associateHandle (rth.getId (), std::move (tag));
@@ -1808,9 +1808,6 @@ void VulkanDriver::beginRenderPass(Handle<HwRenderTarget> rth, const RenderPassP
18081808 FVK_SYSTRACE_SCOPE ();
18091809
18101810 auto rt = resource_ptr<VulkanRenderTarget>::cast (&mResourceManager , rth);
1811- VkExtent2D const extent = rt->getExtent ();
1812-
1813- assert_invariant (rt == mDefaultRenderTarget || extent.width > 0 && extent.height > 0 );
18141811
18151812 VulkanCommandBuffer* commandBuffer = rt->isProtected () ?
18161813 &mCommands .getProtected () : &mCommands .get ();
@@ -1825,9 +1822,16 @@ void VulkanDriver::beginRenderPass(Handle<HwRenderTarget> rth, const RenderPassP
18251822 if (sc->isFirstRenderPass ()) {
18261823 discardStart |= TargetBufferFlags::COLOR;
18271824 sc->markFirstRenderPass ();
1825+ acquireNextSwapchainImage ();
18281826 }
18291827 }
18301828
1829+ // Note that retrieving the extent must come after the acquireNextSwapchainImage() above;
1830+ // otherwise it might be 0.
1831+ VkExtent2D const extent = rt->getExtent ();
1832+
1833+ assert_invariant (rt == mDefaultRenderTarget || extent.width > 0 && extent.height > 0 );
1834+
18311835#if FVK_ENABLED(FVK_DEBUG_TEXTURE)
18321836 if (rt->hasDepth ()) {
18331837 auto depth = rt->getDepth ();
@@ -2038,20 +2042,13 @@ void VulkanDriver::makeCurrent(Handle<HwSwapChain> drawSch, Handle<HwSwapChain>
20382042 ASSERT_PRECONDITION_NON_FATAL (drawSch == readSch,
20392043 " Vulkan driver does not support distinct draw/read swap chains." );
20402044
2045+ // Before we can render into the new swapchain, we need to make sure the default render target
2046+ // releases its old bound swapchain image.
2047+ mDefaultRenderTarget ->releaseSwapchain ();
2048+
20412049 resource_ptr<VulkanSwapChain> swapChain =
20422050 resource_ptr<VulkanSwapChain>::cast (&mResourceManager , drawSch);
20432051 mCurrentSwapChain = swapChain;
2044-
2045- bool resized = false ;
2046- swapChain->acquire (resized);
2047-
2048- if (resized) {
2049- mFramebufferCache .resetFramebuffers ();
2050- }
2051-
2052- if (UTILS_LIKELY (mDefaultRenderTarget )) {
2053- mDefaultRenderTarget ->bindToSwapChain (swapChain);
2054- }
20552052}
20562053
20572054void VulkanDriver::commit (Handle<HwSwapChain> sch) {
@@ -2222,6 +2219,14 @@ void VulkanDriver::blitDEPRECATED(TargetBufferFlags buffers,
22222219 auto dstTarget = resource_ptr<VulkanRenderTarget>::cast (&mResourceManager , dst);
22232220 auto srcTarget = resource_ptr<VulkanRenderTarget>::cast (&mResourceManager , src);
22242221
2222+ // This is a valid use of the api. We need to make sure that the swapchain image has been
2223+ // acquired and associated with the default render target. It's okay to call
2224+ // acquireNextSwapchainImage() even if a swapchain image has already been bound to the default
2225+ // render target.
2226+ if (dstTarget == mDefaultRenderTarget ) {
2227+ acquireNextSwapchainImage ();
2228+ }
2229+
22252230 VkFilter const vkfilter = (filter == SamplerMagFilter::NEAREST) ?
22262231 VK_FILTER_NEAREST : VK_FILTER_LINEAR;
22272232
@@ -2553,6 +2558,25 @@ void VulkanDriver::endCommandRecording() {
25532558 mDescriptorSetCache .resetCachedState ();
25542559}
25552560
2561+ void VulkanDriver::acquireNextSwapchainImage () {
2562+ assert_invariant (mCurrentSwapChain );
2563+ assert_invariant (mDefaultRenderTarget );
2564+
2565+ // Swapchain has already been bound to the default render target. We just return.
2566+ if (mDefaultRenderTarget ->isSwapchainBound ()) {
2567+ return ;
2568+ }
2569+
2570+ bool resized = false ;
2571+ mCurrentSwapChain ->acquire (resized);
2572+ if (resized) {
2573+ mFramebufferCache .resetFramebuffers ();
2574+ }
2575+ // Note that ordering this after the above lines is necessary since we set the swapchain image
2576+ // to the render target in bindSwapChain().
2577+ mDefaultRenderTarget ->bindSwapChain (mCurrentSwapChain );
2578+ }
2579+
25562580// explicit instantiation of the Dispatcher
25572581template class ConcreteDispatcher <VulkanDriver>;
25582582
0 commit comments