diff --git a/src/common/vulkan/swap_chain.cpp b/src/common/vulkan/swap_chain.cpp
index 810b6b64e..f5009ea56 100644
--- a/src/common/vulkan/swap_chain.cpp
+++ b/src/common/vulkan/swap_chain.cpp
@@ -723,13 +723,15 @@ void SwapChain::DestroySwapChain()
 
 VkResult SwapChain::AcquireNextImage()
 {
+  if (!m_swap_chain)
+    return VK_ERROR_SURFACE_LOST_KHR;
+
   return vkAcquireNextImageKHR(g_vulkan_context->GetDevice(), m_swap_chain, UINT64_MAX, m_image_available_semaphore,
                                VK_NULL_HANDLE, &m_current_image);
 }
 
 bool SwapChain::ResizeSwapChain(u32 new_width /* = 0 */, u32 new_height /* = 0 */)
 {
-  DestroySemaphores();
   DestroySwapChainImages();
 
   if (new_width != 0 && new_height != 0)
@@ -738,7 +740,7 @@ bool SwapChain::ResizeSwapChain(u32 new_width /* = 0 */, u32 new_height /* = 0 *
     m_window_info.surface_height = new_height;
   }
 
-  if (!CreateSwapChain() || !SetupSwapChainImages() || !CreateSemaphores())
+  if (!CreateSwapChain() || !SetupSwapChainImages())
   {
     Panic("Failed to re-configure swap chain images, this is fatal (for now)");
     return false;
@@ -749,10 +751,9 @@ bool SwapChain::ResizeSwapChain(u32 new_width /* = 0 */, u32 new_height /* = 0 *
 
 bool SwapChain::RecreateSwapChain()
 {
-  DestroySemaphores();
   DestroySwapChainImages();
-  DestroySwapChain();
-  if (!CreateSwapChain() || !SetupSwapChainImages() || !CreateSemaphores())
+
+  if (!CreateSwapChain() || !SetupSwapChainImages())
   {
     Panic("Failed to re-configure swap chain images, this is fatal (for now)");
     return false;
@@ -774,7 +775,6 @@ bool SwapChain::SetVSync(bool enabled)
 bool SwapChain::RecreateSurface(const WindowInfo& new_wi)
 {
   // Destroy the old swap chain, images, and surface.
-  DestroySemaphores();
   DestroySwapChainImages();
   DestroySwapChain();
   DestroySurface();
@@ -803,7 +803,7 @@ bool SwapChain::RecreateSurface(const WindowInfo& new_wi)
   }
 
   // Finally re-create the swap chain
-  if (!CreateSwapChain() || !SetupSwapChainImages() || !CreateSemaphores())
+  if (!CreateSwapChain() || !SetupSwapChainImages())
     return false;
 
   return true;
@@ -811,6 +811,9 @@ bool SwapChain::RecreateSurface(const WindowInfo& new_wi)
 
 void SwapChain::DestroySurface()
 {
+  if (m_surface == VK_NULL_HANDLE)
+    return;
+
   DestroyVulkanSurface(g_vulkan_context->GetVulkanInstance(), &m_window_info, m_surface);
   m_surface = VK_NULL_HANDLE;
 }
diff --git a/src/frontend-common/vulkan_host_display.cpp b/src/frontend-common/vulkan_host_display.cpp
index 493cf601d..a2e7cec3f 100644
--- a/src/frontend-common/vulkan_host_display.cpp
+++ b/src/frontend-common/vulkan_host_display.cpp
@@ -580,6 +580,18 @@ bool VulkanHostDisplay::Render()
       ResizeRenderWindow(0, 0);
       res = m_swap_chain->AcquireNextImage();
     }
+    else if (res == VK_ERROR_SURFACE_LOST_KHR)
+    {
+      Log_WarningPrint("Surface lost, attempting to recreate");
+      if (!m_swap_chain->RecreateSurface(m_window_info))
+      {
+        Log_ErrorPrint("Failed to recreate surface after loss");
+        g_vulkan_context->ExecuteCommandBuffer(false);
+        return false;
+      }
+
+      res = m_swap_chain->AcquireNextImage();
+    }
 
     // This can happen when multiple resize events happen in quick succession.
     // In this case, just wait until the next frame to try again.