mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-22 00:59:18 +01:00
Vulkan: Fix freeze when closing pad view (#435)
This commit is contained in:
parent
948460cad7
commit
138510106c
@ -676,6 +676,12 @@ SwapchainInfoVk& VulkanRenderer::GetChainInfo(bool mainWindow) const
|
|||||||
return *GetChainInfoPtr(mainWindow);
|
return *GetChainInfoPtr(mainWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::StopUsingPadAndWait()
|
||||||
|
{
|
||||||
|
m_destroyPadSwapchainNextAcquire = true;
|
||||||
|
m_padCloseReadySemaphore.wait();
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanRenderer::IsPadWindowActive()
|
bool VulkanRenderer::IsPadWindowActive()
|
||||||
{
|
{
|
||||||
return IsSwapchainInfoValid(false);
|
return IsSwapchainInfoValid(false);
|
||||||
@ -1658,15 +1664,12 @@ bool VulkanRenderer::ImguiBegin(bool mainWindow)
|
|||||||
|
|
||||||
auto& chainInfo = GetChainInfo(mainWindow);
|
auto& chainInfo = GetChainInfo(mainWindow);
|
||||||
|
|
||||||
if (!IsSwapchainInfoValid(mainWindow))
|
if (!AcquireNextSwapchainImage(mainWindow))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
draw_endRenderPass();
|
draw_endRenderPass();
|
||||||
m_state.currentPipeline = VK_NULL_HANDLE;
|
m_state.currentPipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
AcquireNextSwapchainImage(mainWindow);
|
|
||||||
|
|
||||||
|
|
||||||
ImGui_ImplVulkan_CreateFontsTexture(m_state.currentCommandBuffer);
|
ImGui_ImplVulkan_CreateFontsTexture(m_state.currentCommandBuffer);
|
||||||
ImGui_ImplVulkan_NewFrame(m_state.currentCommandBuffer, chainInfo.m_swapchainFramebuffers[chainInfo.swapchainImageIndex], chainInfo.swapchainExtent);
|
ImGui_ImplVulkan_NewFrame(m_state.currentCommandBuffer, chainInfo.m_swapchainFramebuffers[chainInfo.swapchainImageIndex], chainInfo.swapchainExtent);
|
||||||
ImGui_UpdateWindowInformation(mainWindow);
|
ImGui_UpdateWindowInformation(mainWindow);
|
||||||
@ -1718,11 +1721,9 @@ void VulkanRenderer::DeleteFontTextures()
|
|||||||
|
|
||||||
bool VulkanRenderer::BeginFrame(bool mainWindow)
|
bool VulkanRenderer::BeginFrame(bool mainWindow)
|
||||||
{
|
{
|
||||||
if (!IsSwapchainInfoValid(mainWindow))
|
if (!AcquireNextSwapchainImage(mainWindow))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AcquireNextSwapchainImage(mainWindow);
|
|
||||||
|
|
||||||
auto& chainInfo = GetChainInfo(mainWindow);
|
auto& chainInfo = GetChainInfo(mainWindow);
|
||||||
|
|
||||||
VkClearColorValue clearColor{ 0, 0, 0, 0 };
|
VkClearColorValue clearColor{ 0, 0, 0, 0 };
|
||||||
@ -1743,9 +1744,6 @@ void VulkanRenderer::DrawEmptyFrame(bool mainWindow)
|
|||||||
|
|
||||||
void VulkanRenderer::PreparePresentationFrame(bool mainWindow)
|
void VulkanRenderer::PreparePresentationFrame(bool mainWindow)
|
||||||
{
|
{
|
||||||
if (!IsSwapchainInfoValid(mainWindow))
|
|
||||||
return;
|
|
||||||
|
|
||||||
AcquireNextSwapchainImage(mainWindow);
|
AcquireNextSwapchainImage(mainWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2530,11 +2528,36 @@ VkPipeline VulkanRenderer::backbufferBlit_createGraphicsPipeline(VkDescriptorSet
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::AcquireNextSwapchainImage(bool mainWindow)
|
bool VulkanRenderer::AcquireNextSwapchainImage(bool mainWindow)
|
||||||
{
|
{
|
||||||
|
if(!IsSwapchainInfoValid(mainWindow))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!mainWindow && m_destroyPadSwapchainNextAcquire)
|
||||||
|
{
|
||||||
|
RecreateSwapchain(mainWindow, true);
|
||||||
|
m_destroyPadSwapchainNextAcquire = false;
|
||||||
|
m_padCloseReadySemaphore.notify();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto& chainInfo = GetChainInfo(mainWindow);
|
auto& chainInfo = GetChainInfo(mainWindow);
|
||||||
|
|
||||||
|
UpdateVSyncState(mainWindow);
|
||||||
|
|
||||||
|
const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB;
|
||||||
|
if (chainInfo.sizeOutOfDate || chainInfo.m_usesSRGB != latteBufferUsesSRGB)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RecreateSwapchain(mainWindow);
|
||||||
|
chainInfo.m_usesSRGB = latteBufferUsesSRGB;
|
||||||
|
}
|
||||||
|
catch (std::exception&) { cemu_assert_debug(false); }
|
||||||
|
}
|
||||||
|
|
||||||
if (chainInfo.swapchainImageIndex != -1)
|
if (chainInfo.swapchainImageIndex != -1)
|
||||||
return; // image already reserved
|
return true; // image already reserved
|
||||||
|
|
||||||
vkWaitForFences(m_logicalDevice, 1, &chainInfo.m_imageAvailableFence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
vkWaitForFences(m_logicalDevice, 1, &chainInfo.m_imageAvailableFence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||||
vkResetFences(m_logicalDevice, 1, &chainInfo.m_imageAvailableFence);
|
vkResetFences(m_logicalDevice, 1, &chainInfo.m_imageAvailableFence);
|
||||||
@ -2553,7 +2576,7 @@ void VulkanRenderer::AcquireNextSwapchainImage(bool mainWindow)
|
|||||||
vkResetFences(m_logicalDevice, 1, &chainInfo.m_imageAvailableFence);
|
vkResetFences(m_logicalDevice, 1, &chainInfo.m_imageAvailableFence);
|
||||||
result = vkAcquireNextImageKHR(m_logicalDevice, chainInfo.swapchain, std::numeric_limits<uint64_t>::max(), acquireSemaphore, chainInfo.m_imageAvailableFence, &chainInfo.swapchainImageIndex);
|
result = vkAcquireNextImageKHR(m_logicalDevice, chainInfo.swapchain, std::numeric_limits<uint64_t>::max(), acquireSemaphore, chainInfo.m_imageAvailableFence, &chainInfo.swapchainImageIndex);
|
||||||
if (result == VK_SUCCESS)
|
if (result == VK_SUCCESS)
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
catch (std::exception&) {}
|
catch (std::exception&) {}
|
||||||
|
|
||||||
@ -2565,11 +2588,11 @@ void VulkanRenderer::AcquireNextSwapchainImage(bool mainWindow)
|
|||||||
}
|
}
|
||||||
|
|
||||||
chainInfo.m_acquireIndex = (chainInfo.m_acquireIndex + 1) % chainInfo.m_acquireSemaphores.size();
|
chainInfo.m_acquireIndex = (chainInfo.m_acquireIndex + 1) % chainInfo.m_acquireSemaphores.size();
|
||||||
|
|
||||||
SubmitCommandBuffer(nullptr, &acquireSemaphore);
|
SubmitCommandBuffer(nullptr, &acquireSemaphore);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::RecreateSwapchain(bool mainWindow)
|
void VulkanRenderer::RecreateSwapchain(bool mainWindow, bool skipCreate)
|
||||||
{
|
{
|
||||||
SubmitCommandBuffer();
|
SubmitCommandBuffer();
|
||||||
WaitDeviceIdle();
|
WaitDeviceIdle();
|
||||||
@ -2591,7 +2614,10 @@ void VulkanRenderer::RecreateSwapchain(bool mainWindow)
|
|||||||
|
|
||||||
chainInfo.Cleanup();
|
chainInfo.Cleanup();
|
||||||
chainInfo.setSize(size);
|
chainInfo.setSize(size);
|
||||||
chainInfo.Create(m_physicalDevice, m_logicalDevice);
|
if(!skipCreate)
|
||||||
|
{
|
||||||
|
chainInfo.Create(m_physicalDevice, m_logicalDevice);
|
||||||
|
}
|
||||||
chainInfo.swapchainImageIndex = -1;
|
chainInfo.swapchainImageIndex = -1;
|
||||||
|
|
||||||
if (mainWindow)
|
if (mainWindow)
|
||||||
@ -2610,23 +2636,10 @@ void VulkanRenderer::UpdateVSyncState(bool mainWindow)
|
|||||||
|
|
||||||
void VulkanRenderer::SwapBuffer(bool mainWindow)
|
void VulkanRenderer::SwapBuffer(bool mainWindow)
|
||||||
{
|
{
|
||||||
auto& chainInfo = GetChainInfo(mainWindow);
|
if(!AcquireNextSwapchainImage(mainWindow))
|
||||||
|
|
||||||
const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB;
|
|
||||||
if (chainInfo.sizeOutOfDate || chainInfo.m_usesSRGB != latteBufferUsesSRGB)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
RecreateSwapchain(mainWindow);
|
|
||||||
chainInfo.m_usesSRGB = latteBufferUsesSRGB;
|
|
||||||
}
|
|
||||||
catch (std::exception&) { cemu_assert_debug(false); }
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
UpdateVSyncState(mainWindow);
|
auto& chainInfo = GetChainInfo(mainWindow);
|
||||||
|
|
||||||
AcquireNextSwapchainImage(mainWindow);
|
|
||||||
|
|
||||||
if (!chainInfo.hasDefinedSwapchainImage)
|
if (!chainInfo.hasDefinedSwapchainImage)
|
||||||
{
|
{
|
||||||
@ -2818,7 +2831,7 @@ void VulkanRenderer::CreateBackbufferIndexBuffer()
|
|||||||
|
|
||||||
void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter, sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight, bool padView, bool clearBackground)
|
void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter, sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight, bool padView, bool clearBackground)
|
||||||
{
|
{
|
||||||
if (!IsSwapchainInfoValid(!padView))
|
if(!AcquireNextSwapchainImage(!padView))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& chainInfo = GetChainInfo(!padView);
|
auto& chainInfo = GetChainInfo(!padView);
|
||||||
@ -2828,8 +2841,6 @@ void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||||||
if (clearBackground)
|
if (clearBackground)
|
||||||
ClearColorbuffer(padView);
|
ClearColorbuffer(padView);
|
||||||
|
|
||||||
AcquireNextSwapchainImage(!padView);
|
|
||||||
|
|
||||||
// barrier for input texture
|
// barrier for input texture
|
||||||
VkMemoryBarrier memoryBarrier{};
|
VkMemoryBarrier memoryBarrier{};
|
||||||
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||||
|
@ -187,6 +187,7 @@ public:
|
|||||||
const std::unique_ptr<SwapchainInfoVk>& GetChainInfoPtr(bool mainWindow) const;
|
const std::unique_ptr<SwapchainInfoVk>& GetChainInfoPtr(bool mainWindow) const;
|
||||||
SwapchainInfoVk& GetChainInfo(bool mainWindow) const;
|
SwapchainInfoVk& GetChainInfo(bool mainWindow) const;
|
||||||
|
|
||||||
|
void StopUsingPadAndWait();
|
||||||
bool IsPadWindowActive() override;
|
bool IsPadWindowActive() override;
|
||||||
|
|
||||||
void HandleScreenshotRequest(LatteTextureView* texView, bool padView) override;
|
void HandleScreenshotRequest(LatteTextureView* texView, bool padView) override;
|
||||||
@ -432,6 +433,8 @@ private:
|
|||||||
}m_state;
|
}m_state;
|
||||||
|
|
||||||
std::unique_ptr<SwapchainInfoVk> m_mainSwapchainInfo{}, m_padSwapchainInfo{};
|
std::unique_ptr<SwapchainInfoVk> m_mainSwapchainInfo{}, m_padSwapchainInfo{};
|
||||||
|
Semaphore m_padCloseReadySemaphore;
|
||||||
|
bool m_destroyPadSwapchainNextAcquire = false;
|
||||||
bool IsSwapchainInfoValid(bool mainWindow) const;
|
bool IsSwapchainInfoValid(bool mainWindow) const;
|
||||||
|
|
||||||
VkRenderPass m_imguiRenderPass = nullptr;
|
VkRenderPass m_imguiRenderPass = nullptr;
|
||||||
@ -555,8 +558,8 @@ private:
|
|||||||
void CreatePipelineCache();
|
void CreatePipelineCache();
|
||||||
VkPipelineShaderStageCreateInfo CreatePipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule& module, const char* entryName) const;
|
VkPipelineShaderStageCreateInfo CreatePipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule& module, const char* entryName) const;
|
||||||
VkPipeline backbufferBlit_createGraphicsPipeline(VkDescriptorSetLayout descriptorLayout, bool padView, RendererOutputShader* shader);
|
VkPipeline backbufferBlit_createGraphicsPipeline(VkDescriptorSetLayout descriptorLayout, bool padView, RendererOutputShader* shader);
|
||||||
void AcquireNextSwapchainImage(bool mainWindow);
|
bool AcquireNextSwapchainImage(bool mainWindow);
|
||||||
void RecreateSwapchain(bool mainWindow);
|
void RecreateSwapchain(bool mainWindow, bool skipCreate = false);
|
||||||
|
|
||||||
// streamout
|
// streamout
|
||||||
void streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) override;
|
void streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) override;
|
||||||
|
@ -41,6 +41,12 @@ VulkanCanvas::~VulkanCanvas()
|
|||||||
{
|
{
|
||||||
Unbind(wxEVT_PAINT, &VulkanCanvas::OnPaint, this);
|
Unbind(wxEVT_PAINT, &VulkanCanvas::OnPaint, this);
|
||||||
Unbind(wxEVT_SIZE, &VulkanCanvas::OnResize, this);
|
Unbind(wxEVT_SIZE, &VulkanCanvas::OnResize, this);
|
||||||
|
|
||||||
|
if(!m_is_main_window)
|
||||||
|
{
|
||||||
|
if(auto vulkan_renderer = VulkanRenderer::GetInstance())
|
||||||
|
vulkan_renderer->StopUsingPadAndWait();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanCanvas::OnPaint(wxPaintEvent& event)
|
void VulkanCanvas::OnPaint(wxPaintEvent& event)
|
||||||
|
Loading…
Reference in New Issue
Block a user