mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
VideoBackends:Vulkan: Don't try to present if swapchain acquire failed
This commit is contained in:
@ -300,7 +300,7 @@ void CommandBufferManager::WaitForCommandBufferCompletion(u32 index)
|
||||
}
|
||||
|
||||
void CommandBufferManager::SubmitCommandBuffer(bool submit_on_worker_thread,
|
||||
bool wait_for_completion,
|
||||
bool wait_for_completion, bool advance_to_next_frame,
|
||||
VkSwapchainKHR present_swap_chain,
|
||||
uint32_t present_image_index)
|
||||
{
|
||||
@ -334,7 +334,7 @@ void CommandBufferManager::SubmitCommandBuffer(bool submit_on_worker_thread,
|
||||
WaitForCommandBufferCompletion(m_current_cmd_buffer);
|
||||
}
|
||||
|
||||
if (present_swap_chain != VK_NULL_HANDLE)
|
||||
if (advance_to_next_frame)
|
||||
{
|
||||
m_current_frame = (m_current_frame + 1) % NUM_FRAMES_IN_FLIGHT;
|
||||
|
||||
|
@ -78,6 +78,7 @@ public:
|
||||
void WaitForFenceCounter(u64 fence_counter);
|
||||
|
||||
void SubmitCommandBuffer(bool submit_on_worker_thread, bool wait_for_completion,
|
||||
bool advance_to_next_frame = false,
|
||||
VkSwapchainKHR present_swap_chain = VK_NULL_HANDLE,
|
||||
uint32_t present_image_index = 0xFFFFFFFF);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) override;
|
||||
void DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x, u32 groupsize_y,
|
||||
u32 groupsize_z, u32 groups_x, u32 groups_y, u32 groups_z) override;
|
||||
void BindBackbuffer(const ClearColor& clear_color = {}) override;
|
||||
bool BindBackbuffer(const ClearColor& clear_color = {}) override;
|
||||
void PresentBackbuffer() override;
|
||||
void SetFullscreen(bool enable_fullscreen) override;
|
||||
bool IsFullscreen() const override;
|
||||
|
@ -497,6 +497,7 @@ VkResult SwapChain::AcquireNextImage()
|
||||
VkResult res = vkAcquireNextImageKHR(g_vulkan_context->GetDevice(), m_swap_chain, UINT64_MAX,
|
||||
g_command_buffer_mgr->GetCurrentCommandBufferSemaphore(),
|
||||
VK_NULL_HANDLE, &m_current_swap_chain_image_index);
|
||||
m_current_swap_chain_image_is_valid = res >= 0;
|
||||
if (res != VK_SUCCESS && res != VK_ERROR_OUT_OF_DATE_KHR && res != VK_SUBOPTIMAL_KHR)
|
||||
LOG_VULKAN_ERROR(res, "vkAcquireNextImageKHR failed: ");
|
||||
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
u32 GetWidth() const { return m_width; }
|
||||
u32 GetHeight() const { return m_height; }
|
||||
u32 GetCurrentImageIndex() const { return m_current_swap_chain_image_index; }
|
||||
bool IsCurrentImageValid() const { return m_current_swap_chain_image_is_valid; }
|
||||
VkImage GetCurrentImage() const
|
||||
{
|
||||
return m_swap_chain_images[m_current_swap_chain_image_index].image;
|
||||
@ -98,6 +99,7 @@ private:
|
||||
bool m_fullscreen_supported = false;
|
||||
bool m_current_fullscreen_state = false;
|
||||
bool m_next_fullscreen_state = false;
|
||||
bool m_current_swap_chain_image_is_valid = false;
|
||||
|
||||
VkSwapchainKHR m_swap_chain = VK_NULL_HANDLE;
|
||||
std::vector<SwapChainImage> m_swap_chain_images;
|
||||
|
Reference in New Issue
Block a user