diff options
| author | Stenzek <stenzek@users.noreply.github.com> | 2017-10-11 23:02:48 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-10-11 23:02:48 +1000 |
| commit | 90ca2e8042ce2d119dc4723f6ce82b1a60372aaa (patch) | |
| tree | d5c966ddb1bfa0576af9883ac30ba22a849c1e1d /Source/Core/VideoBackends/Vulkan/Renderer.cpp | |
| parent | d26eda3023a0d896f1992d9deffbbcc47195c2a3 (diff) | |
| parent | 4301b8538df2d2728e624cfc2576758272dbb0c9 (diff) | |
Merge pull request #6066 from stenzek/vulkan-resize
Vulkan: Fixes for window resizing
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/Renderer.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/Renderer.cpp | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 2a90da6f9a..3a4907b88c 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -325,10 +325,6 @@ void Renderer::BeginFrame() // Activate a new command list, and restore state ready for the next draw g_command_buffer_mgr->ActivateCommandBuffer(); - // Restore the EFB color texture to color attachment ready for rendering the next frame. - FramebufferManager::GetInstance()->GetEFBColorTexture()->TransitionToLayout( - g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - // Ensure that the state tracker rebinds everything, and allocates a new set // of descriptors out of the next pool. StateTracker::GetInstance()->InvalidateDescriptorSets(); @@ -575,6 +571,10 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height // Prep for the next frame (get command buffer ready) before doing anything else. BeginFrame(); + // Restore the EFB color texture to color attachment ready for rendering the next frame. + FramebufferManager::GetInstance()->GetEFBColorTexture()->TransitionToLayout( + g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + // Determine what (if anything) has changed in the config. CheckForConfigChanges(); @@ -718,8 +718,18 @@ void Renderer::DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr, const XFBSourceBase* const* xfb_sources, u32 xfb_count, u32 fb_width, u32 fb_stride, u32 fb_height) { - // Grab the next image from the swap chain in preparation for drawing the window. - VkResult res = m_swap_chain->AcquireNextImage(m_image_available_semaphore); + VkResult res; + 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); + } + else + { + // If the last present failed, we need to recreate the swap chain. + res = VK_ERROR_OUT_OF_DATE_KHR; + } + if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) { // There's an issue here. We can't resize the swap chain while the GPU is still busy with it, @@ -729,7 +739,8 @@ 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); } @@ -1065,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(); @@ -1081,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) { @@ -1122,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() @@ -1191,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) @@ -1237,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() { } |
