VideoBackends:Vulkan: Don't try to present if swapchain acquire failed

This commit is contained in:
TellowKrinkle
2024-09-30 18:29:38 -05:00
parent c7cbac538a
commit 7e1a9490c0
18 changed files with 64 additions and 31 deletions

View File

@ -221,7 +221,7 @@ void VKGfx::WaitForGPUIdle()
ExecuteCommandBuffer(false, true);
}
void VKGfx::BindBackbuffer(const ClearColor& clear_color)
bool VKGfx::BindBackbuffer(const ClearColor& clear_color)
{
StateTracker::GetInstance()->EndRenderPass();
@ -284,10 +284,22 @@ void VKGfx::BindBackbuffer(const ClearColor& clear_color)
res = m_swap_chain->AcquireNextImage();
if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR)
PanicAlertFmt("Failed to grab image from swap chain: {:#010X} {}", Common::ToUnderlying(res),
VkResultToString(res));
{
if (res == VK_ERROR_OUT_OF_DATE_KHR)
{
INFO_LOG_FMT(VIDEO, "Swapchain still out of date, will try again next frame...");
}
else
{
PanicAlertFmt("Failed to grab image from swap chain: {:#010X} {}",
Common::ToUnderlying(res), VkResultToString(res));
}
}
}
if (!m_swap_chain->IsCurrentImageValid())
return false;
// Transition from undefined (or present src, but it can be substituted) to
// color attachment ready for writing. These transitions must occur outside
// a render pass, unless the render pass declares a self-dependency.
@ -296,6 +308,7 @@ void VKGfx::BindBackbuffer(const ClearColor& clear_color)
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
SetAndClearFramebuffer(m_swap_chain->GetCurrentFramebuffer(),
ClearColor{{0.0f, 0.0f, 0.0f, 1.0f}});
return true;
}
void VKGfx::PresentBackbuffer()
@ -303,17 +316,24 @@ void VKGfx::PresentBackbuffer()
// End drawing to backbuffer
StateTracker::GetInstance()->EndRenderPass();
// Transition the backbuffer to PRESENT_SRC to ensure all commands drawing
// to it have finished before present.
m_swap_chain->GetCurrentTexture()->TransitionToLayout(
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
if (m_swap_chain->IsCurrentImageValid())
{
// Transition the backbuffer to PRESENT_SRC to ensure all commands drawing
// to it have finished before present.
m_swap_chain->GetCurrentTexture()->TransitionToLayout(
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
// Submit the current command buffer, signaling rendering finished semaphore when it's done
// Because this final command buffer is rendering to the swap chain, we need to wait for
// the available semaphore to be signaled before executing the buffer. This final submission
// can happen off-thread in the background while we're preparing the next frame.
g_command_buffer_mgr->SubmitCommandBuffer(true, false, m_swap_chain->GetSwapChain(),
m_swap_chain->GetCurrentImageIndex());
// Submit the current command buffer, signaling rendering finished semaphore when it's done
// Because this final command buffer is rendering to the swap chain, we need to wait for
// the available semaphore to be signaled before executing the buffer. This final submission
// can happen off-thread in the background while we're preparing the next frame.
g_command_buffer_mgr->SubmitCommandBuffer(true, false, true, m_swap_chain->GetSwapChain(),
m_swap_chain->GetCurrentImageIndex());
}
else
{
g_command_buffer_mgr->SubmitCommandBuffer(true, false, true);
}
// New cmdbuffer, so invalidate state.
StateTracker::GetInstance()->InvalidateCachedState();