From d95e7f14386127801a0168285eb319fb91a48878 Mon Sep 17 00:00:00 2001 From: Nemirtingas Date: Sat, 1 Aug 2026 14:44:40 +0200 Subject: [PATCH] Fix Vulkan example hang When vkQueuePresentKHR or vkAcquireNextImageKHR return VK_SUBOPTIMAL_KHR, FramePresent will not be called because of if (g_SwapChainRebuild) return; Making vkQueuePresentKHR never called and never releasing the current frame, hanging the app. --- examples/example_win32_vulkan/main.cpp | 28 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/examples/example_win32_vulkan/main.cpp b/examples/example_win32_vulkan/main.cpp index cbdbdb830..1a95ea4d9 100644 --- a/examples/example_win32_vulkan/main.cpp +++ b/examples/example_win32_vulkan/main.cpp @@ -47,6 +47,8 @@ static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; static ImGui_ImplVulkanH_Window g_MainWindowData; static uint32_t g_MinImageCount = 2; static bool g_SwapChainRebuild = false; +static int g_FrameBufferWidth = 0; +static int g_FrameBufferHeight = 0; static void check_vk_result(VkResult err) { @@ -200,6 +202,20 @@ static void SetupVulkan(ImVector instance_extensions) // All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo. // Your real engine/app may not use them. +static void RebuildVulkanSwapchain(int fb_width, int fb_height) +{ + if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height)) + { + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, 0); + g_MainWindowData.FrameIndex = 0; + g_SwapChainRebuild = false; + + g_FrameBufferWidth = fb_width; + g_FrameBufferHeight = fb_height; + } +} + static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height) { // Check for WSI support @@ -453,6 +469,8 @@ int main(int, char**) if (done) break; + RebuildVulkanSwapchain(g_FrameBufferWidth, g_FrameBufferHeight); + // Start the Dear ImGui frame ImGui_ImplVulkan_NewFrame(); ImGui_ImplWin32_NewFrame(); @@ -547,15 +565,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) if (g_Device != VK_NULL_HANDLE && wParam != SIZE_MINIMIZED) { // Resize swap chain - int fb_width = (UINT)LOWORD(lParam); - int fb_height = (UINT)HIWORD(lParam); - if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height)) - { - ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); - ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, 0); - g_MainWindowData.FrameIndex = 0; - g_SwapChainRebuild = false; - } + RebuildVulkanSwapchain((UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); } return 0; case WM_SYSCOMMAND: