Vulkan: Only use oldSwapchain in response to VK_ERROR_OUT_OF_DATE_KHR
Seems to be required on the latest NV driver, otherwise the presented images are never shown.
This commit is contained in:
parent
cdf34a79f7
commit
4301b8538d
|
@ -80,7 +80,7 @@ public:
|
|||
void ExecuteCommandBuffer(bool submit_off_thread, bool wait_for_completion);
|
||||
|
||||
// Was the last present submitted to the queue a failure? If so, we must recreate our swapchain.
|
||||
bool DidLastPresentFail() { return m_present_failed_flag.TestAndClear(); }
|
||||
bool CheckLastPresentFail() { return m_present_failed_flag.TestAndClear(); }
|
||||
// Schedule a vulkan resource for destruction later on. This will occur when the command buffer
|
||||
// is next re-used, and the GPU has finished working with the specified resource.
|
||||
void DeferBufferDestruction(VkBuffer object);
|
||||
|
|
|
@ -719,7 +719,7 @@ void Renderer::DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr,
|
|||
u32 fb_stride, u32 fb_height)
|
||||
{
|
||||
VkResult res;
|
||||
if (!g_command_buffer_mgr->DidLastPresentFail())
|
||||
if (!g_command_buffer_mgr->CheckLastPresentFail())
|
||||
{
|
||||
// Grab the next image from the swap chain in preparation for drawing the window.
|
||||
res = m_swap_chain->AcquireNextImage(m_image_available_semaphore);
|
||||
|
@ -739,7 +739,7 @@ void Renderer::DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr,
|
|||
// command buffer, resize the swap chain (which calls WaitForGPUIdle), and then finally call
|
||||
// PrepareToSubmitCommandBuffer to return to the state that the caller expects.
|
||||
g_command_buffer_mgr->SubmitCommandBuffer(false);
|
||||
ResizeSwapChain();
|
||||
m_swap_chain->ResizeSwapChain();
|
||||
BeginFrame();
|
||||
g_command_buffer_mgr->PrepareToSubmitCommandBuffer();
|
||||
res = m_swap_chain->AcquireNextImage(m_image_available_semaphore);
|
||||
|
@ -1076,14 +1076,17 @@ void Renderer::CheckForSurfaceChange()
|
|||
if (!m_surface_needs_change.IsSet())
|
||||
return;
|
||||
|
||||
u32 old_width = m_swap_chain ? m_swap_chain->GetWidth() : 0;
|
||||
u32 old_height = m_swap_chain ? m_swap_chain->GetHeight() : 0;
|
||||
// Wait for the GPU to catch up since we're going to destroy the swap chain.
|
||||
g_command_buffer_mgr->WaitForGPUIdle();
|
||||
|
||||
// Clear the present failed flag, since we don't want to resize after recreating.
|
||||
g_command_buffer_mgr->CheckLastPresentFail();
|
||||
|
||||
// Fast path, if the surface handle is the same, the window has just been resized.
|
||||
if (m_swap_chain && m_new_surface_handle == m_swap_chain->GetNativeHandle())
|
||||
{
|
||||
INFO_LOG(VIDEO, "Detected window resize.");
|
||||
ResizeSwapChain();
|
||||
m_swap_chain->RecreateSwapChain();
|
||||
|
||||
// Notify the main thread we are done.
|
||||
m_surface_needs_change.Clear();
|
||||
|
@ -1092,9 +1095,6 @@ void Renderer::CheckForSurfaceChange()
|
|||
}
|
||||
else
|
||||
{
|
||||
// Wait for the GPU to catch up since we're going to destroy the swap chain.
|
||||
g_command_buffer_mgr->WaitForGPUIdle();
|
||||
|
||||
// Did we previously have a swap chain?
|
||||
if (m_swap_chain)
|
||||
{
|
||||
|
@ -1133,12 +1133,8 @@ void Renderer::CheckForSurfaceChange()
|
|||
m_surface_changed.Set();
|
||||
}
|
||||
|
||||
if (m_swap_chain)
|
||||
{
|
||||
// Handle case where the dimensions are now different
|
||||
if (old_width != m_swap_chain->GetWidth() || old_height != m_swap_chain->GetHeight())
|
||||
OnSwapChainResized();
|
||||
}
|
||||
// Handle case where the dimensions are now different.
|
||||
OnSwapChainResized();
|
||||
}
|
||||
|
||||
void Renderer::CheckForConfigChanges()
|
||||
|
@ -1202,7 +1198,10 @@ void Renderer::CheckForConfigChanges()
|
|||
// For quad-buffered stereo we need to change the layer count, so recreate the swap chain.
|
||||
if (m_swap_chain &&
|
||||
(g_ActiveConfig.iStereoMode == STEREO_QUADBUFFER) != m_swap_chain->IsStereoEnabled())
|
||||
ResizeSwapChain();
|
||||
{
|
||||
g_command_buffer_mgr->WaitForGPUIdle();
|
||||
m_swap_chain->RecreateSwapChain();
|
||||
}
|
||||
|
||||
// Wipe sampler cache if force texture filtering or anisotropy changes.
|
||||
if (anisotropy_changed || force_texture_filtering_changed)
|
||||
|
@ -1248,18 +1247,6 @@ void Renderer::ResizeEFBTextures()
|
|||
BPFunctions::SetScissor();
|
||||
}
|
||||
|
||||
void Renderer::ResizeSwapChain()
|
||||
{
|
||||
// The worker thread may still be submitting a present on this swap chain.
|
||||
g_command_buffer_mgr->WaitForGPUIdle();
|
||||
|
||||
// It's now safe to resize the swap chain.
|
||||
if (!m_swap_chain->ResizeSwapChain())
|
||||
PanicAlert("Failed to resize swap chain.");
|
||||
|
||||
OnSwapChainResized();
|
||||
}
|
||||
|
||||
void Renderer::ApplyState()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -81,7 +81,6 @@ private:
|
|||
void OnSwapChainResized();
|
||||
void BindEFBToStateTracker();
|
||||
void ResizeEFBTextures();
|
||||
void ResizeSwapChain();
|
||||
|
||||
void RecompileShaders();
|
||||
bool CompileShaders();
|
||||
|
|
|
@ -472,14 +472,27 @@ bool SwapChain::ResizeSwapChain()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SwapChain::RecreateSwapChain()
|
||||
{
|
||||
DestroySwapChainImages();
|
||||
DestroySwapChain();
|
||||
if (!CreateSwapChain() || !SetupSwapChainImages())
|
||||
{
|
||||
PanicAlert("Failed to re-configure swap chain images, this is fatal (for now)");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SwapChain::SetVSync(bool enabled)
|
||||
{
|
||||
if (m_vsync_enabled == enabled)
|
||||
return true;
|
||||
|
||||
// Resizing recreates the swap chain with the new present mode.
|
||||
// Recreate the swap chain with the new present mode.
|
||||
m_vsync_enabled = enabled;
|
||||
return ResizeSwapChain();
|
||||
return RecreateSwapChain();
|
||||
}
|
||||
|
||||
bool SwapChain::RecreateSurface(void* native_handle)
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
|
||||
bool RecreateSurface(void* native_handle);
|
||||
bool ResizeSwapChain();
|
||||
bool RecreateSwapChain();
|
||||
|
||||
// Change vsync enabled state. This may fail as it causes a swapchain recreation.
|
||||
bool SetVSync(bool enabled);
|
||||
|
|
Loading…
Reference in New Issue