mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 07:35:41 +00:00
VulkanHostDisplay: Handle surface loss gracefully
Also skips a full swap chain recreate on resize.
This commit is contained in:
parent
0342d0a26e
commit
19ca102b40
|
@ -723,13 +723,15 @@ void SwapChain::DestroySwapChain()
|
||||||
|
|
||||||
VkResult SwapChain::AcquireNextImage()
|
VkResult SwapChain::AcquireNextImage()
|
||||||
{
|
{
|
||||||
|
if (!m_swap_chain)
|
||||||
|
return VK_ERROR_SURFACE_LOST_KHR;
|
||||||
|
|
||||||
return vkAcquireNextImageKHR(g_vulkan_context->GetDevice(), m_swap_chain, UINT64_MAX, m_image_available_semaphore,
|
return vkAcquireNextImageKHR(g_vulkan_context->GetDevice(), m_swap_chain, UINT64_MAX, m_image_available_semaphore,
|
||||||
VK_NULL_HANDLE, &m_current_image);
|
VK_NULL_HANDLE, &m_current_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwapChain::ResizeSwapChain(u32 new_width /* = 0 */, u32 new_height /* = 0 */)
|
bool SwapChain::ResizeSwapChain(u32 new_width /* = 0 */, u32 new_height /* = 0 */)
|
||||||
{
|
{
|
||||||
DestroySemaphores();
|
|
||||||
DestroySwapChainImages();
|
DestroySwapChainImages();
|
||||||
|
|
||||||
if (new_width != 0 && new_height != 0)
|
if (new_width != 0 && new_height != 0)
|
||||||
|
@ -738,7 +740,7 @@ bool SwapChain::ResizeSwapChain(u32 new_width /* = 0 */, u32 new_height /* = 0 *
|
||||||
m_window_info.surface_height = new_height;
|
m_window_info.surface_height = new_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateSwapChain() || !SetupSwapChainImages() || !CreateSemaphores())
|
if (!CreateSwapChain() || !SetupSwapChainImages())
|
||||||
{
|
{
|
||||||
Panic("Failed to re-configure swap chain images, this is fatal (for now)");
|
Panic("Failed to re-configure swap chain images, this is fatal (for now)");
|
||||||
return false;
|
return false;
|
||||||
|
@ -749,10 +751,9 @@ bool SwapChain::ResizeSwapChain(u32 new_width /* = 0 */, u32 new_height /* = 0 *
|
||||||
|
|
||||||
bool SwapChain::RecreateSwapChain()
|
bool SwapChain::RecreateSwapChain()
|
||||||
{
|
{
|
||||||
DestroySemaphores();
|
|
||||||
DestroySwapChainImages();
|
DestroySwapChainImages();
|
||||||
DestroySwapChain();
|
|
||||||
if (!CreateSwapChain() || !SetupSwapChainImages() || !CreateSemaphores())
|
if (!CreateSwapChain() || !SetupSwapChainImages())
|
||||||
{
|
{
|
||||||
Panic("Failed to re-configure swap chain images, this is fatal (for now)");
|
Panic("Failed to re-configure swap chain images, this is fatal (for now)");
|
||||||
return false;
|
return false;
|
||||||
|
@ -774,7 +775,6 @@ bool SwapChain::SetVSync(bool enabled)
|
||||||
bool SwapChain::RecreateSurface(const WindowInfo& new_wi)
|
bool SwapChain::RecreateSurface(const WindowInfo& new_wi)
|
||||||
{
|
{
|
||||||
// Destroy the old swap chain, images, and surface.
|
// Destroy the old swap chain, images, and surface.
|
||||||
DestroySemaphores();
|
|
||||||
DestroySwapChainImages();
|
DestroySwapChainImages();
|
||||||
DestroySwapChain();
|
DestroySwapChain();
|
||||||
DestroySurface();
|
DestroySurface();
|
||||||
|
@ -803,7 +803,7 @@ bool SwapChain::RecreateSurface(const WindowInfo& new_wi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally re-create the swap chain
|
// Finally re-create the swap chain
|
||||||
if (!CreateSwapChain() || !SetupSwapChainImages() || !CreateSemaphores())
|
if (!CreateSwapChain() || !SetupSwapChainImages())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -811,6 +811,9 @@ bool SwapChain::RecreateSurface(const WindowInfo& new_wi)
|
||||||
|
|
||||||
void SwapChain::DestroySurface()
|
void SwapChain::DestroySurface()
|
||||||
{
|
{
|
||||||
|
if (m_surface == VK_NULL_HANDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
DestroyVulkanSurface(g_vulkan_context->GetVulkanInstance(), &m_window_info, m_surface);
|
DestroyVulkanSurface(g_vulkan_context->GetVulkanInstance(), &m_window_info, m_surface);
|
||||||
m_surface = VK_NULL_HANDLE;
|
m_surface = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -580,6 +580,18 @@ bool VulkanHostDisplay::Render()
|
||||||
ResizeRenderWindow(0, 0);
|
ResizeRenderWindow(0, 0);
|
||||||
res = m_swap_chain->AcquireNextImage();
|
res = m_swap_chain->AcquireNextImage();
|
||||||
}
|
}
|
||||||
|
else if (res == VK_ERROR_SURFACE_LOST_KHR)
|
||||||
|
{
|
||||||
|
Log_WarningPrint("Surface lost, attempting to recreate");
|
||||||
|
if (!m_swap_chain->RecreateSurface(m_window_info))
|
||||||
|
{
|
||||||
|
Log_ErrorPrint("Failed to recreate surface after loss");
|
||||||
|
g_vulkan_context->ExecuteCommandBuffer(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = m_swap_chain->AcquireNextImage();
|
||||||
|
}
|
||||||
|
|
||||||
// This can happen when multiple resize events happen in quick succession.
|
// This can happen when multiple resize events happen in quick succession.
|
||||||
// In this case, just wait until the next frame to try again.
|
// In this case, just wait until the next frame to try again.
|
||||||
|
|
Loading…
Reference in a new issue