@@ -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