Skip to content

Commit 1385101

Browse files
Vulkan: Fix freeze when closing pad view (#435)
1 parent 948460c commit 1385101

File tree

3 files changed

+56
-36
lines changed

3 files changed

+56
-36
lines changed

src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
679685
bool 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

17191722
bool 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

17441745
void 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

26112637
void 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

28192832
void 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;

src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ class VulkanRenderer : public Renderer
187187
const std::unique_ptr<SwapchainInfoVk>& GetChainInfoPtr(bool mainWindow) const;
188188
SwapchainInfoVk& GetChainInfo(bool mainWindow) const;
189189

190+
void StopUsingPadAndWait();
190191
bool IsPadWindowActive() override;
191192

192193
void HandleScreenshotRequest(LatteTextureView* texView, bool padView) override;
@@ -432,6 +433,8 @@ class VulkanRenderer : public Renderer
432433
}m_state;
433434

434435
std::unique_ptr<SwapchainInfoVk> m_mainSwapchainInfo{}, m_padSwapchainInfo{};
436+
Semaphore m_padCloseReadySemaphore;
437+
bool m_destroyPadSwapchainNextAcquire = false;
435438
bool IsSwapchainInfoValid(bool mainWindow) const;
436439

437440
VkRenderPass m_imguiRenderPass = nullptr;
@@ -555,8 +558,8 @@ class VulkanRenderer : public Renderer
555558
void CreatePipelineCache();
556559
VkPipelineShaderStageCreateInfo CreatePipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule& module, const char* entryName) const;
557560
VkPipeline backbufferBlit_createGraphicsPipeline(VkDescriptorSetLayout descriptorLayout, bool padView, RendererOutputShader* shader);
558-
void AcquireNextSwapchainImage(bool mainWindow);
559-
void RecreateSwapchain(bool mainWindow);
561+
bool AcquireNextSwapchainImage(bool mainWindow);
562+
void RecreateSwapchain(bool mainWindow, bool skipCreate = false);
560563

561564
// streamout
562565
void streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) override;

src/gui/canvas/VulkanCanvas.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ VulkanCanvas::~VulkanCanvas()
4141
{
4242
Unbind(wxEVT_PAINT, &VulkanCanvas::OnPaint, this);
4343
Unbind(wxEVT_SIZE, &VulkanCanvas::OnResize, this);
44+
45+
if(!m_is_main_window)
46+
{
47+
if(auto vulkan_renderer = VulkanRenderer::GetInstance())
48+
vulkan_renderer->StopUsingPadAndWait();
49+
}
4450
}
4551

4652
void VulkanCanvas::OnPaint(wxPaintEvent& event)

0 commit comments

Comments
 (0)