From edbec2f2cc3dea67f7c53f1378b823a35bc77633 Mon Sep 17 00:00:00 2001 From: Francis De Brabandere Date: Wed, 17 Jun 2026 05:56:24 +0200 Subject: [PATCH] Vulkan: recreate window swap chains flagged for recreation (#3751) When acquiring a window frame buffer swap chain returns VK_SUBOPTIMAL_KHR or VK_ERROR_OUT_OF_DATE_KHR it is flagged with m_needToRecreateSwapchain and acquire then refuses forever: only the main back buffer is recreated (by updateResolution), so the window permanently stops updating (easily triggered by moving the window to a display with a different scale). Recreate flagged window swap chains when acquiring them. --- src/renderer_vk.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index fee9e316f..ae58f8a76 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -8691,6 +8691,19 @@ VK_DESTROY BX_ASSERT(NULL != m_nwh, "FrameBufferVK::acquire is only valid for swap-chain framebuffers."); BGFX_PROFILER_SCOPE("FrameBufferVK::acquire", kColorFrame); + // Window frame buffers are not recreated by updateResolution like the main back + // buffer is, so recreate here when the swap chain was flagged, e.g. with + // VK_SUBOPTIMAL_KHR after the window moved to another display. + if (this != &s_renderVK->m_backBuffer + && VK_NULL_HANDLE != m_swapChain.m_swapChain + && (m_swapChain.m_needToRecreateSwapchain || m_swapChain.m_needToRecreateSurface) ) + { + update(_commandBuffer, m_swapChain.m_resolution); + + // update may kick the queue and rotate the command buffer, refresh the local handle + _commandBuffer = s_renderVK->m_commandBuffer; + } + const bool acquired = m_swapChain.acquire(_commandBuffer); m_needPresent = m_swapChain.m_needPresent; m_currentFramebuffer = m_swapChain.m_backBufferFrameBuffer[m_swapChain.m_backBufferColorIdx];