VideoBackends:Vulkan: Use external dimensions if driver doesn't give us any

This commit is contained in:
TellowKrinkle 2023-06-25 20:10:18 -05:00 committed by BeezBumba
parent f545b49d12
commit d38c20cc16
3 changed files with 30 additions and 23 deletions

View File

@ -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)

View File

@ -132,8 +132,11 @@ std::unique_ptr<SwapChain> SwapChain::Create(const WindowSystemInfo& wsi, VkSurf
bool vsync)
{
std::unique_ptr<SwapChain> swap_chain = std::make_unique<SwapChain>(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;

View File

@ -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();