@@ -296,6 +296,7 @@ struct ImGui_ImplVulkan_Data
296296 ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
297297
298298 // Viewports common data
299+ VkSurfaceFormatKHR ViewportsFormat; // Common for all viewports, may differ from VulkanInitInfo.SecondaryViewportsInfo.DesiredFormat
299300 // Filled during ImGui_ImplVulkan_PrepareViewportsRendering() based on ViewportsFormat and VulkanInitInfo->SecondaryViewportsInfo
300301 ImGui_ImplVulkan_PipelineInfo PipelineInfoForViewports;
301302 VkPipeline PipelineForViewports; // pipeline for secondary viewports (created by backend)
@@ -1219,8 +1220,15 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
12191220 if (bd->DescriptorSetLayout ) { vkDestroyDescriptorSetLayout (v->Device , bd->DescriptorSetLayout , v->Allocator ); bd->DescriptorSetLayout = VK_NULL_HANDLE; }
12201221 if (bd->PipelineLayout ) { vkDestroyPipelineLayout (v->Device , bd->PipelineLayout , v->Allocator ); bd->PipelineLayout = VK_NULL_HANDLE; }
12211222 if (bd->Pipeline ) { vkDestroyPipeline (v->Device , bd->Pipeline , v->Allocator ); bd->Pipeline = VK_NULL_HANDLE; }
1222- if (bd->PipelineForViewports ) { vkDestroyPipeline (v->Device , bd->PipelineForViewports , v->Allocator ); bd->PipelineForViewports = VK_NULL_HANDLE; }
12231223 if (bd->DescriptorPool ) { vkDestroyDescriptorPool (v->Device , bd->DescriptorPool , v->Allocator ); bd->DescriptorPool = VK_NULL_HANDLE; }
1224+
1225+ // Destroy viewports common objects
1226+ if (bd->PipelineForViewports ) { vkDestroyPipeline (v->Device , bd->PipelineForViewports , v->Allocator ); bd->PipelineForViewports = VK_NULL_HANDLE; }
1227+ if (bd->PipelineInfoForViewports .RenderPass )
1228+ {
1229+ vkDestroyRenderPass (v->Device , bd->PipelineInfoForViewports .RenderPass , v->Allocator );
1230+ bd->PipelineInfoForViewports .RenderPass = VK_NULL_HANDLE;
1231+ }
12241232}
12251233
12261234#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
@@ -1980,28 +1988,15 @@ static void ImGui_ImplVulkan_SelectPresentMode(ImGuiViewport* viewport)
19801988 // printf("[vulkan] Secondary window selected PresentMode = %d\n", wd->PresentMode);
19811989}
19821990
1983- static void ImGui_ImplVulkan_CreateWindow (ImGuiViewport* viewport)
1991+ // Prepare common viewports rendering objects.
1992+ // Requires a sample surface (assuming any viewport surface behaves the same).
1993+ // - Select a surface format
1994+ // - Create the common RenderPass and Pipeline
1995+ static void ImGui_ImplVulkan_PrepareViewportsRendering (VkSurfaceKHR surface)
19841996{
19851997 ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData ();
1986- ImGui_ImplVulkan_ViewportData* vd = IM_NEW (ImGui_ImplVulkan_ViewportData)();
1987- viewport->RendererUserData = vd;
1988- ImGui_ImplVulkanH_Window* wd = &vd->Window ;
19891998 ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo ;
19901999
1991- // Create surface
1992- ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO ();
1993- VkResult err = (VkResult)platform_io.Platform_CreateVkSurface (viewport, (ImU64)v->Instance , (const void *)v->Allocator , (ImU64*)&wd->Surface );
1994- check_vk_result (err);
1995-
1996- // Check for WSI support
1997- VkBool32 res;
1998- vkGetPhysicalDeviceSurfaceSupportKHR (v->PhysicalDevice , v->QueueFamily , wd->Surface , &res);
1999- if (res != VK_TRUE)
2000- {
2001- IM_ASSERT (0 ); // Error: no WSI support on physical device
2002- return ;
2003- }
2004-
20052000 // Select Surface Format
20062001 ImGui_ImplVulkan_PipelineInfo* pipeline_info = &bd->PipelineInfoForViewports ;
20072002 const VkFormat requestSurfaceImageFormats[] = { v->SecondaryViewportsInfo .DesiredFormat .format , VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
@@ -2014,36 +2009,68 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
20142009 }
20152010
20162011 const VkColorSpaceKHR requestSurfaceColorSpace = v->SecondaryViewportsInfo .DesiredFormat .colorSpace ;
2017- wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat (v->PhysicalDevice , wd->Surface , pRequestSurfaceImageFormats, requestSurfaceImageFormatsCount, requestSurfaceColorSpace);
2018-
2019- // Select Present Mode
2020- ImGui_ImplVulkan_SelectPresentMode (viewport);
2021-
2022- // Create SwapChain, RenderPass, Framebuffer, etc.
2023- wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true ;
2024- wd->UseDynamicRendering = v->UseDynamicRendering ;
2025- ImGui_ImplVulkanH_CreateOrResizeWindow (v->Instance , v->PhysicalDevice , v->Device , wd, v->QueueFamily , v->Allocator , (int )viewport->Size .x , (int )viewport->Size .y , v->MinImageCount , v->SecondaryViewportsInfo .SwapChainImageUsage );
2026- vd->WindowOwned = true ;
2012+ bd->ViewportsFormat = ImGui_ImplVulkanH_SelectSurfaceFormat (v->PhysicalDevice , surface, pRequestSurfaceImageFormats, requestSurfaceImageFormatsCount, requestSurfaceColorSpace);
20272013
20282014 // Create pipeline (shared by all secondary viewports)
20292015 if (bd->PipelineForViewports == VK_NULL_HANDLE)
20302016 {
20312017#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
2032- if (wd ->UseDynamicRendering )
2018+ if (v ->UseDynamicRendering )
20332019 {
20342020 pipeline_info->PipelineRenderingCreateInfo .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
20352021 pipeline_info->PipelineRenderingCreateInfo .colorAttachmentCount = 1 ;
2036- pipeline_info->PipelineRenderingCreateInfo .pColorAttachmentFormats = &wd-> SurfaceFormat .format ;
2022+ pipeline_info->PipelineRenderingCreateInfo .pColorAttachmentFormats = &bd-> ViewportsFormat .format ;
20372023 }
20382024 else
20392025 {
2040- pipeline_info->RenderPass = wd->RenderPass ;
2026+ // Create a reference RenderPass (needed for the Pipeline creation)
2027+ // Viewports will create their own RenderPass, compatible with this one (same format, different clear option)
2028+ pipeline_info->RenderPass = ImGui_ImplVulkanH_CreateRenderPass (v->Device , v->Allocator , bd->ViewportsFormat .format , true );
2029+ pipeline_info->Subpass = 0 ;
20412030 }
20422031#endif
20432032 bd->PipelineForViewports = ImGui_ImplVulkan_CreatePipeline (v->Device , v->Allocator , VK_NULL_HANDLE, pipeline_info);
20442033 }
20452034}
20462035
2036+ static void ImGui_ImplVulkan_CreateWindow (ImGuiViewport* viewport)
2037+ {
2038+ ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData ();
2039+ ImGui_ImplVulkan_ViewportData* vd = IM_NEW (ImGui_ImplVulkan_ViewportData)();
2040+ viewport->RendererUserData = vd;
2041+ ImGui_ImplVulkanH_Window* wd = &vd->Window ;
2042+ ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo ;
2043+
2044+ // Create surface
2045+ ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO ();
2046+ VkResult err = (VkResult)platform_io.Platform_CreateVkSurface (viewport, (ImU64)v->Instance , (const void *)v->Allocator , (ImU64*)&wd->Surface );
2047+ check_vk_result (err);
2048+
2049+ // Check for WSI support
2050+ VkBool32 res;
2051+ vkGetPhysicalDeviceSurfaceSupportKHR (v->PhysicalDevice , v->QueueFamily , wd->Surface , &res);
2052+ if (res != VK_TRUE)
2053+ {
2054+ IM_ASSERT (0 ); // Error: no WSI support on physical device
2055+ return ;
2056+ }
2057+
2058+ // Select Present Mode
2059+ ImGui_ImplVulkan_SelectPresentMode (viewport);
2060+
2061+ if (bd->ViewportsFormat .format == VK_FORMAT_UNDEFINED)
2062+ {
2063+ ImGui_ImplVulkan_PrepareViewportsRendering (wd->Surface );
2064+ }
2065+ wd->SurfaceFormat = bd->ViewportsFormat ;
2066+
2067+ // Create SwapChain, RenderPass, Framebuffer, etc.
2068+ wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true ;
2069+ wd->UseDynamicRendering = v->UseDynamicRendering ;
2070+ ImGui_ImplVulkanH_CreateOrResizeWindow (v->Instance , v->PhysicalDevice , v->Device , wd, v->QueueFamily , v->Allocator , (int )viewport->Size .x , (int )viewport->Size .y , v->MinImageCount , v->SecondaryViewportsInfo .SwapChainImageUsage );
2071+ vd->WindowOwned = true ;
2072+ }
2073+
20472074static void ImGui_ImplVulkan_DestroyWindow (ImGuiViewport* viewport)
20482075{
20492076 // The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
0 commit comments