diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index d553e7e8c..faa4646de 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -247,8 +247,9 @@ struct ImGui_ImplVulkan_ViewportData ImGui_ImplVulkan_WindowRenderBuffers RenderBuffers; // Used by all viewports bool WindowOwned; bool SwapChainNeedRebuild; // Flag when viewport swapchain resized in the middle of processing a frame + bool SwapChainSuboptimal; // Flag when VK_SUBOPTIMAL_KHR was returned. - ImGui_ImplVulkan_ViewportData() { WindowOwned = SwapChainNeedRebuild = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); } + ImGui_ImplVulkan_ViewportData() { WindowOwned = SwapChainNeedRebuild = SwapChainSuboptimal = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); } ~ImGui_ImplVulkan_ViewportData() { } }; @@ -1808,10 +1809,10 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*) ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; VkResult err; - if (vd->SwapChainNeedRebuild) + if (vd->SwapChainNeedRebuild || vd->SwapChainSuboptimal) { ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount); - vd->SwapChainNeedRebuild = false; + vd->SwapChainNeedRebuild = vd->SwapChainSuboptimal = false; } ImGui_ImplVulkanH_Frame* fd = nullptr; @@ -1821,11 +1822,13 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*) err = vkAcquireNextImageKHR(v->Device, wd->Swapchain, UINT64_MAX, fsd->ImageAcquiredSemaphore, VK_NULL_HANDLE, &wd->FrameIndex); if (err == VK_ERROR_OUT_OF_DATE_KHR) { - // Since we are not going to swap this frame anyway, it's ok that recreation happens on next frame. - vd->SwapChainNeedRebuild = true; + vd->SwapChainNeedRebuild = true; // Since we are not going to swap this frame anyway, it's ok that recreation happens on next frame. return; } - check_vk_result(err); + if (err == VK_SUBOPTIMAL_KHR) + vd->SwapChainSuboptimal = true; + else + check_vk_result(err); fd = &wd->Frames[wd->FrameIndex]; } for (;;) @@ -1967,11 +1970,14 @@ static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*) info.pSwapchains = &wd->Swapchain; info.pImageIndices = &present_index; err = vkQueuePresentKHR(v->Queue, &info); - if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) - vd->SwapChainNeedRebuild = true; if (err == VK_ERROR_OUT_OF_DATE_KHR) + { + vd->SwapChainNeedRebuild = true; return; - if (err != VK_SUBOPTIMAL_KHR) + } + if (err == VK_SUBOPTIMAL_KHR) + vd->SwapChainSuboptimal = true; + else check_vk_result(err); wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores } diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 23de4b32c..3061055d8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -46,11 +46,13 @@ Other changes: - ImDrawList: texture baked storage for thick line reduced from ~64x64 to ~32x32. (#3245) - Examples: DirectX12: Reduced number of frame in flight from 3 to 2 in provided example, to reduce latency. -- Examples: Vulkan: better handle VK_SUBOPTIMAL_KHR being returned by +- Backends+Examples: Vulkan: better handle VK_SUBOPTIMAL_KHR being returned by vkAcquireNextImageKHR() or vkQueuePresentKHR(). (#7825, #7831) [@NostraMagister] - Backends: DirectX12: Texture upload use the command queue provided in ImGui_ImplDX12_InitInfo instead of creating its own. +Docking+Viewports Branch: + ----------------------------------------------------------------------- VERSION 1.91.7 (Released 2025-01-14)