@@ -676,6 +676,12 @@ SwapchainInfoVk& VulkanRenderer::GetChainInfo(bool mainWindow) const
676676 return *GetChainInfoPtr (mainWindow);
677677}
678678
679+ void VulkanRenderer::StopUsingPadAndWait ()
680+ {
681+ m_destroyPadSwapchainNextAcquire = true ;
682+ m_padCloseReadySemaphore.wait ();
683+ }
684+
679685bool VulkanRenderer::IsPadWindowActive ()
680686{
681687 return IsSwapchainInfoValid (false );
@@ -1658,15 +1664,12 @@ bool VulkanRenderer::ImguiBegin(bool mainWindow)
16581664
16591665 auto & chainInfo = GetChainInfo (mainWindow);
16601666
1661- if (!IsSwapchainInfoValid (mainWindow))
1667+ if (!AcquireNextSwapchainImage (mainWindow))
16621668 return false ;
16631669
16641670 draw_endRenderPass ();
16651671 m_state.currentPipeline = VK_NULL_HANDLE;
16661672
1667- AcquireNextSwapchainImage (mainWindow);
1668-
1669-
16701673 ImGui_ImplVulkan_CreateFontsTexture (m_state.currentCommandBuffer );
16711674 ImGui_ImplVulkan_NewFrame (m_state.currentCommandBuffer , chainInfo.m_swapchainFramebuffers [chainInfo.swapchainImageIndex ], chainInfo.swapchainExtent );
16721675 ImGui_UpdateWindowInformation (mainWindow);
@@ -1718,11 +1721,9 @@ void VulkanRenderer::DeleteFontTextures()
17181721
17191722bool VulkanRenderer::BeginFrame (bool mainWindow)
17201723{
1721- if (!IsSwapchainInfoValid (mainWindow))
1724+ if (!AcquireNextSwapchainImage (mainWindow))
17221725 return false ;
17231726
1724- AcquireNextSwapchainImage (mainWindow);
1725-
17261727 auto & chainInfo = GetChainInfo (mainWindow);
17271728
17281729 VkClearColorValue clearColor{ 0 , 0 , 0 , 0 };
@@ -1743,9 +1744,6 @@ void VulkanRenderer::DrawEmptyFrame(bool mainWindow)
17431744
17441745void VulkanRenderer::PreparePresentationFrame (bool mainWindow)
17451746{
1746- if (!IsSwapchainInfoValid (mainWindow))
1747- return ;
1748-
17491747 AcquireNextSwapchainImage (mainWindow);
17501748}
17511749
@@ -2530,11 +2528,36 @@ VkPipeline VulkanRenderer::backbufferBlit_createGraphicsPipeline(VkDescriptorSet
25302528 return pipeline;
25312529}
25322530
2533- void VulkanRenderer::AcquireNextSwapchainImage (bool mainWindow)
2531+ bool VulkanRenderer::AcquireNextSwapchainImage (bool mainWindow)
25342532{
2533+ if (!IsSwapchainInfoValid (mainWindow))
2534+ return false ;
2535+
2536+ if (!mainWindow && m_destroyPadSwapchainNextAcquire)
2537+ {
2538+ RecreateSwapchain (mainWindow, true );
2539+ m_destroyPadSwapchainNextAcquire = false ;
2540+ m_padCloseReadySemaphore.notify ();
2541+ return false ;
2542+ }
2543+
25352544 auto & chainInfo = GetChainInfo (mainWindow);
2545+
2546+ UpdateVSyncState (mainWindow);
2547+
2548+ const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB ;
2549+ if (chainInfo.sizeOutOfDate || chainInfo.m_usesSRGB != latteBufferUsesSRGB)
2550+ {
2551+ try
2552+ {
2553+ RecreateSwapchain (mainWindow);
2554+ chainInfo.m_usesSRGB = latteBufferUsesSRGB;
2555+ }
2556+ catch (std::exception&) { cemu_assert_debug (false ); }
2557+ }
2558+
25362559 if (chainInfo.swapchainImageIndex != -1 )
2537- return ; // image already reserved
2560+ return true ; // image already reserved
25382561
25392562 vkWaitForFences (m_logicalDevice, 1 , &chainInfo.m_imageAvailableFence , VK_TRUE, std::numeric_limits<uint64_t >::max ());
25402563 vkResetFences (m_logicalDevice, 1 , &chainInfo.m_imageAvailableFence );
@@ -2553,7 +2576,7 @@ void VulkanRenderer::AcquireNextSwapchainImage(bool mainWindow)
25532576 vkResetFences (m_logicalDevice, 1 , &chainInfo.m_imageAvailableFence );
25542577 result = vkAcquireNextImageKHR (m_logicalDevice, chainInfo.swapchain , std::numeric_limits<uint64_t >::max (), acquireSemaphore, chainInfo.m_imageAvailableFence , &chainInfo.swapchainImageIndex );
25552578 if (result == VK_SUCCESS)
2556- return ;
2579+ return true ;
25572580 }
25582581 catch (std::exception&) {}
25592582
@@ -2565,11 +2588,11 @@ void VulkanRenderer::AcquireNextSwapchainImage(bool mainWindow)
25652588 }
25662589
25672590 chainInfo.m_acquireIndex = (chainInfo.m_acquireIndex + 1 ) % chainInfo.m_acquireSemaphores .size ();
2568-
25692591 SubmitCommandBuffer (nullptr , &acquireSemaphore);
2592+ return true ;
25702593}
25712594
2572- void VulkanRenderer::RecreateSwapchain (bool mainWindow)
2595+ void VulkanRenderer::RecreateSwapchain (bool mainWindow, bool skipCreate )
25732596{
25742597 SubmitCommandBuffer ();
25752598 WaitDeviceIdle ();
@@ -2591,7 +2614,10 @@ void VulkanRenderer::RecreateSwapchain(bool mainWindow)
25912614
25922615 chainInfo.Cleanup ();
25932616 chainInfo.setSize (size);
2594- chainInfo.Create (m_physicalDevice, m_logicalDevice);
2617+ if (!skipCreate)
2618+ {
2619+ chainInfo.Create (m_physicalDevice, m_logicalDevice);
2620+ }
25952621 chainInfo.swapchainImageIndex = -1 ;
25962622
25972623 if (mainWindow)
@@ -2610,23 +2636,10 @@ void VulkanRenderer::UpdateVSyncState(bool mainWindow)
26102636
26112637void VulkanRenderer::SwapBuffer (bool mainWindow)
26122638{
2613- auto & chainInfo = GetChainInfo (mainWindow);
2614-
2615- const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB ;
2616- if (chainInfo.sizeOutOfDate || chainInfo.m_usesSRGB != latteBufferUsesSRGB)
2617- {
2618- try
2619- {
2620- RecreateSwapchain (mainWindow);
2621- chainInfo.m_usesSRGB = latteBufferUsesSRGB;
2622- }
2623- catch (std::exception&) { cemu_assert_debug (false ); }
2639+ if (!AcquireNextSwapchainImage (mainWindow))
26242640 return ;
2625- }
26262641
2627- UpdateVSyncState (mainWindow);
2628-
2629- AcquireNextSwapchainImage (mainWindow);
2642+ auto & chainInfo = GetChainInfo (mainWindow);
26302643
26312644 if (!chainInfo.hasDefinedSwapchainImage )
26322645 {
@@ -2818,7 +2831,7 @@ void VulkanRenderer::CreateBackbufferIndexBuffer()
28182831
28192832void VulkanRenderer::DrawBackbufferQuad (LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter, sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight, bool padView, bool clearBackground)
28202833{
2821- if (! IsSwapchainInfoValid (!padView))
2834+ if (! AcquireNextSwapchainImage (!padView))
28222835 return ;
28232836
28242837 auto & chainInfo = GetChainInfo (!padView);
@@ -2828,8 +2841,6 @@ void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
28282841 if (clearBackground)
28292842 ClearColorbuffer (padView);
28302843
2831- AcquireNextSwapchainImage (!padView);
2832-
28332844 // barrier for input texture
28342845 VkMemoryBarrier memoryBarrier{};
28352846 memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
0 commit comments