diff --git a/Source/Core/VideoBackends/Vulkan/VKGfx.cpp b/Source/Core/VideoBackends/Vulkan/VKGfx.cpp index 09aaced21c..42b7e52965 100644 --- a/Source/Core/VideoBackends/Vulkan/VKGfx.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKGfx.cpp @@ -262,18 +262,18 @@ bool VKGfx::BindBackbuffer(const ClearColor& clear_color) { // The present keeps returning exclusive mode lost unless we re-create the swap chain. INFO_LOG_FMT(VIDEO, "Lost exclusive fullscreen."); - m_swap_chain->RecreateSwapChain(); + m_swap_chain->RecreateSwapChain(0, 0); } else if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) { INFO_LOG_FMT(VIDEO, "Resizing swap chain due to suboptimal/out-of-date"); - m_swap_chain->ResizeSwapChain(); + m_swap_chain->ResizeSwapChain(0, 0); } else { ERROR_LOG_FMT(VIDEO, "Unknown present error {:#010X} {}, please report.", - std::to_underlying(res), VkResultToString(res)); - m_swap_chain->RecreateSwapChain(); + Common::ToUnderlying(res), VkResultToString(res)); + m_swap_chain->RecreateSwapChain(0, 0); } res = m_swap_chain->AcquireNextImage(); @@ -370,13 +370,17 @@ void VKGfx::CheckForSurfaceChange() if (change_info->new_handle) { // Recreate the surface. If this fails we're in trouble. - if (!m_swap_chain->RecreateSurface(change_info->new_handle)) + if (!m_swap_chain->RecreateSurface(change_info->new_handle, // + change_info->new_width, change_info->new_height)) + { PanicAlertFmt("Failed to recreate Vulkan surface. Cannot continue."); + } } else { - m_swap_chain->RecreateSwapChain(); + m_swap_chain->RecreateSwapChain(change_info->new_width, change_info->new_height); } + m_backbuffer_scale = change_info->new_scale; // Handle case where the dimensions are now different. OnSwapChainResized(); @@ -400,7 +404,7 @@ void VKGfx::OnConfigChanged(u32 bits) if (m_swap_chain && ((bits & CONFIG_CHANGE_BIT_STEREO_MODE) || (bits & CONFIG_CHANGE_BIT_HDR))) { ExecuteCommandBuffer(false, true); - m_swap_chain->RecreateSwapChain(); + m_swap_chain->RecreateSwapChain(0, 0); } // Wipe sampler cache if force texture filtering or anisotropy changes. @@ -413,7 +417,7 @@ void VKGfx::OnConfigChanged(u32 bits) void VKGfx::OnSwapChainResized() { - g_presenter->SetBackbuffer(m_swap_chain->GetWidth(), m_swap_chain->GetHeight()); + g_presenter->SetBackbuffer(GetSurfaceInfo()); } void VKGfx::BindFramebuffer(VKFramebuffer* fb) diff --git a/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp b/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp index 370e22d15c..e4944ad5fb 100644 --- a/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp @@ -132,8 +132,11 @@ std::unique_ptr SwapChain::Create(const WindowSystemInfo& wsi, VkSurf bool vsync) { std::unique_ptr swap_chain = std::make_unique(wsi, surface, vsync); - if (!swap_chain->CreateSwapChain() || !swap_chain->SetupSwapChainImages()) + if (!swap_chain->CreateSwapChain(wsi.render_surface_width, wsi.render_surface_height) + || !swap_chain->SetupSwapChainImages()) + { return nullptr; + } return swap_chain; } @@ -271,7 +274,7 @@ bool SwapChain::SelectPresentMode() return true; } -bool SwapChain::CreateSwapChain() +bool SwapChain::CreateSwapChain(u32 width, u32 height) { // Look up surface properties to determine image count and dimensions VkSurfaceCapabilitiesKHR surface_capabilities; @@ -299,8 +302,8 @@ bool SwapChain::CreateSwapChain() VkExtent2D size = surface_capabilities.currentExtent; if (size.width == UINT32_MAX) { - size.width = std::max(g_presenter->GetBackbufferWidth(), 1); - size.height = std::max(g_presenter->GetBackbufferHeight(), 1); + size.width = width == 0 ? m_width : width; + size.height = height == 0 ? m_height : height; } size.width = std::clamp(size.width, surface_capabilities.minImageExtent.width, surface_capabilities.maxImageExtent.width); @@ -500,10 +503,10 @@ VkResult SwapChain::AcquireNextImage() return res; } -bool SwapChain::ResizeSwapChain() +bool SwapChain::ResizeSwapChain(u32 width, u32 height) { DestroySwapChainImages(); - if (!CreateSwapChain() || !SetupSwapChainImages()) + if (!CreateSwapChain(width, height) || !SetupSwapChainImages()) { PanicAlertFmt("Failed to re-configure swap chain images, this is fatal (for now)"); return false; @@ -512,11 +515,11 @@ bool SwapChain::ResizeSwapChain() return true; } -bool SwapChain::RecreateSwapChain() +bool SwapChain::RecreateSwapChain(u32 width, u32 height) { DestroySwapChainImages(); DestroySwapChain(); - if (!CreateSwapChain() || !SetupSwapChainImages()) + if (!CreateSwapChain(width, height) || !SetupSwapChainImages()) { PanicAlertFmt("Failed to re-configure swap chain images, this is fatal (for now)"); return false; @@ -532,7 +535,7 @@ bool SwapChain::SetVSync(bool enabled) // Recreate the swap chain with the new present mode. m_vsync_enabled = enabled; - return RecreateSwapChain(); + return RecreateSwapChain(m_width, m_height); } bool SwapChain::SetFullscreenState(bool state) @@ -568,7 +571,7 @@ bool SwapChain::SetFullscreenState(bool state) #endif } -bool SwapChain::RecreateSurface(void* native_handle) +bool SwapChain::RecreateSurface(void* native_handle, u32 width, u32 height) { // Destroy the old swap chain, images, and surface. DestroySwapChainImages(); @@ -604,7 +607,7 @@ bool SwapChain::RecreateSurface(void* native_handle) m_next_fullscreen_state = false; // Finally re-create the swap chain - if (!CreateSwapChain() || !SetupSwapChainImages()) + if (!CreateSwapChain(width, height) || !SetupSwapChainImages()) return false; return true; diff --git a/Source/Core/VideoBackends/Vulkan/VKSwapChain.h b/Source/Core/VideoBackends/Vulkan/VKSwapChain.h index 17334dbf97..99d39f8261 100644 --- a/Source/Core/VideoBackends/Vulkan/VKSwapChain.h +++ b/Source/Core/VideoBackends/Vulkan/VKSwapChain.h @@ -54,9 +54,9 @@ public: } VkResult AcquireNextImage(); - bool RecreateSurface(void* native_handle); - bool ResizeSwapChain(); - bool RecreateSwapChain(); + bool RecreateSurface(void* native_handle, u32 width, u32 height); + bool ResizeSwapChain(u32 width, u32 height); + bool RecreateSwapChain(u32 width, u32 height); // Change vsync enabled state. This may fail as it causes a swapchain recreation. bool SetVSync(bool enabled); @@ -76,7 +76,7 @@ private: bool SelectSurfaceFormat(); bool SelectPresentMode(); - bool CreateSwapChain(); + bool CreateSwapChain(u32 width, u32 height); void DestroySwapChain(); bool SetupSwapChainImages();