From 7e58ac5bcf412f358374f03a5c2895d798bd5a5e Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Fri, 27 Mar 2026 18:02:44 +0100 Subject: [PATCH] android: Handle surface lost during swapchain creation --- .../renderer_vulkan/vk_swapchain.cpp | 34 ++++++++++++++++--- src/video_core/renderer_vulkan/vk_swapchain.h | 2 +- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 56e4cf429..3fc025a30 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -38,7 +38,14 @@ void Swapchain::Create(u32 width_, u32 height_, vk::SurfaceKHR surface_, bool lo Destroy(); SetPresentMode(); + if (needs_recreation) { + return; + } + SetSurfaceProperties(); + if (needs_recreation) { + return; + } const std::array queue_family_indices = { instance.GetGraphicsQueueFamilyIndex(), @@ -70,9 +77,13 @@ void Swapchain::Create(u32 width_, u32 height_, vk::SurfaceKHR surface_, bool lo try { swapchain = instance.GetDevice().createSwapchainKHR(swapchain_info); + } catch (vk::SurfaceLostKHRError&) { + LOG_ERROR(Render_Vulkan, "Surface lost during swapchain creation"); + needs_recreation = true; + return; } catch (vk::SystemError& err) { LOG_CRITICAL(Render_Vulkan, "{}", err.what()); - UNREACHABLE(); + throw; } SetupImages(); @@ -160,7 +171,15 @@ void Swapchain::FindPresentFormat() { } void Swapchain::SetPresentMode() { - const auto modes = instance.GetPhysicalDevice().getSurfacePresentModesKHR(surface); + std::vector modes; + try { + modes = instance.GetPhysicalDevice().getSurfacePresentModesKHR(surface); + } catch (vk::SurfaceLostKHRError&) { + LOG_ERROR(Render_Vulkan, "Surface lost during swapchain creation"); + needs_recreation = true; + return; + } + const bool use_vsync = Settings::values.use_vsync.GetValue(); const auto find_mode = [&modes](vk::PresentModeKHR requested) { const auto it = @@ -203,8 +222,14 @@ void Swapchain::SetPresentMode() { } void Swapchain::SetSurfaceProperties() { - const vk::SurfaceCapabilitiesKHR capabilities = - instance.GetPhysicalDevice().getSurfaceCapabilitiesKHR(surface); + vk::SurfaceCapabilitiesKHR capabilities; + try { + capabilities = instance.GetPhysicalDevice().getSurfaceCapabilitiesKHR(surface); + } catch (vk::SurfaceLostKHRError&) { + LOG_ERROR(Render_Vulkan, "Surface lost during swapchain creation"); + needs_recreation = true; + return; + } extent = capabilities.currentExtent; if (capabilities.currentExtent.width == std::numeric_limits::max()) { @@ -237,6 +262,7 @@ void Swapchain::Destroy() { vk::Device device = instance.GetDevice(); if (swapchain) { device.destroySwapchainKHR(swapchain); + swapchain = VK_NULL_HANDLE; } for (u32 i = 0; i < image_count; i++) { device.destroySemaphore(image_acquired[i]); diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index 4f885727a..9492c0743 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h @@ -90,7 +90,7 @@ private: private: const Instance& instance; - vk::SwapchainKHR swapchain{}; + vk::SwapchainKHR swapchain{VK_NULL_HANDLE}; vk::SurfaceKHR surface{}; vk::SurfaceFormatKHR surface_format; vk::PresentModeKHR present_mode;