Browse Source

Backends: Vulkan: amends for docking. Add PipelineInfoForViewports and SwapChainImageUsage. (#8946, #8110, #8111, #8686)

ocornut 2 weeks ago
parent
commit
e4e3c2cc23
3 changed files with 30 additions and 18 deletions
  1. 17 17
      backends/imgui_impl_vulkan.cpp
  2. 5 1
      backends/imgui_impl_vulkan.h
  3. 8 0
      docs/CHANGELOG.txt

+ 17 - 17
backends/imgui_impl_vulkan.cpp

@@ -1321,7 +1321,9 @@ bool    ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
     else
     else
         IM_ASSERT(info->DescriptorPoolSize > 0);
         IM_ASSERT(info->DescriptorPoolSize > 0);
     if (info->UseDynamicRendering)
     if (info->UseDynamicRendering)
-        IM_ASSERT(info->PipelineInfoMain.RenderPass == VK_NULL_HANDLE);
+        IM_ASSERT(info->PipelineInfoMain.RenderPass == VK_NULL_HANDLE && info->PipelineInfoForViewports.RenderPass == VK_NULL_HANDLE);
+    else if (info->PipelineInfoForViewports.RenderPass == NULL)
+        info->PipelineInfoForViewports.RenderPass = info->PipelineInfoMain.RenderPass;
 
 
     bd->VulkanInitInfo = *info;
     bd->VulkanInitInfo = *info;
 
 
@@ -1975,10 +1977,11 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
     }
     }
 
 
     // Select Surface Format
     // Select Surface Format
+    ImGui_ImplVulkan_PipelineInfo* pipeline_info = &v->PipelineInfoForViewports;
     ImVector<VkFormat> requestSurfaceImageFormats;
     ImVector<VkFormat> requestSurfaceImageFormats;
 #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
 #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
-    for (uint32_t n = 0; n < v->PipelineRenderingCreateInfo.colorAttachmentCount; n++)
-        requestSurfaceImageFormats.push_back(v->PipelineRenderingCreateInfo.pColorAttachmentFormats[n]);
+    for (uint32_t n = 0; n < pipeline_info->PipelineRenderingCreateInfo.colorAttachmentCount; n++)
+        requestSurfaceImageFormats.push_back(pipeline_info->PipelineRenderingCreateInfo.pColorAttachmentFormats[n]);
 #endif
 #endif
     const VkFormat defaultFormats[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
     const VkFormat defaultFormats[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
     for (VkFormat format : defaultFormats)
     for (VkFormat format : defaultFormats)
@@ -1996,28 +1999,25 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
     // Create SwapChain, RenderPass, Framebuffer, etc.
     // Create SwapChain, RenderPass, Framebuffer, etc.
     wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
     wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
     wd->UseDynamicRendering = v->UseDynamicRendering;
     wd->UseDynamicRendering = v->UseDynamicRendering;
-    ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
+    ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount, pipeline_info->SwapChainImageUsage);
     vd->WindowOwned = true;
     vd->WindowOwned = true;
 
 
     // Create pipeline (shared by all secondary viewports)
     // Create pipeline (shared by all secondary viewports)
     if (bd->PipelineForViewports == VK_NULL_HANDLE)
     if (bd->PipelineForViewports == VK_NULL_HANDLE)
     {
     {
-        VkPipelineRenderingCreateInfoKHR* p_rendering_info = nullptr;
 #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
 #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
-        VkPipelineRenderingCreateInfoKHR rendering_info = {};
         if (wd->UseDynamicRendering)
         if (wd->UseDynamicRendering)
         {
         {
-            rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
-            rendering_info.pNext = nullptr;
-            rendering_info.viewMask = 0;
-            rendering_info.colorAttachmentCount = 1;
-            rendering_info.pColorAttachmentFormats = &wd->SurfaceFormat.format;
-            rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
-            rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED;
-            p_rendering_info = &rendering_info;
+            pipeline_info->PipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
+            pipeline_info->PipelineRenderingCreateInfo.colorAttachmentCount = 1;
+            pipeline_info->PipelineRenderingCreateInfo.pColorAttachmentFormats = &wd->SurfaceFormat.format;
+        }
+        else
+        {
+            IM_ASSERT(pipeline_info->RenderPass != VK_NULL_HANDLE && "Did you set ImGui_ImplVulkan_InitInfo::PipelineInfoForViewports.RenderPass?"); // Since 1.92.4 it is required.
         }
         }
 #endif
 #endif
-        bd->PipelineForViewports = ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, VK_NULL_HANDLE, wd->UseDynamicRendering ? VK_NULL_HANDLE : wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, 0, p_rendering_info);
+        bd->PipelineForViewports = ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, VK_NULL_HANDLE, &v->PipelineInfoForViewports);
     }
     }
 }
 }
 
 
@@ -2044,7 +2044,7 @@ static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
         return;
         return;
     ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
     ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
     vd->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
     vd->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
-    ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount);
+    ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount, v->PipelineInfoForViewports.SwapChainImageUsage);
 }
 }
 
 
 static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
 static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
@@ -2057,7 +2057,7 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
 
 
     if (vd->SwapChainNeedRebuild || vd->SwapChainSuboptimal)
     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);
+        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->PipelineInfoForViewports.SwapChainImageUsage);
         vd->SwapChainNeedRebuild = vd->SwapChainSuboptimal = false;
         vd->SwapChainNeedRebuild = vd->SwapChainSuboptimal = false;
     }
     }
 
 

+ 5 - 1
backends/imgui_impl_vulkan.h

@@ -76,6 +76,9 @@ struct ImGui_ImplVulkan_PipelineInfo
 #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
 #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
     VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;   // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
     VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;   // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
 #endif
 #endif
+
+    // For Secondary viewports only (created/managed by backend)
+    VkImageUsageFlags               SwapChainImageUsage;            // 0 defaults to VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT. Add e.g. VK_IMAGE_USAGE_TRANSFER_SRC_BIT if you need to capture from viewports.
 };
 };
 
 
 // Initialization data, for ImGui_ImplVulkan_Init()
 // Initialization data, for ImGui_ImplVulkan_Init()
@@ -102,13 +105,14 @@ struct ImGui_ImplVulkan_InitInfo
 
 
     // Pipeline
     // Pipeline
     ImGui_ImplVulkan_PipelineInfo   PipelineInfoMain;           // Infos for Main Viewport (created by app/user)
     ImGui_ImplVulkan_PipelineInfo   PipelineInfoMain;           // Infos for Main Viewport (created by app/user)
+    ImGui_ImplVulkan_PipelineInfo   PipelineInfoForViewports;   // Infos for Secondary Viewports (created by backend)
     //VkRenderPass                  RenderPass;                 // --> Since 2025/09/26: set 'PipelineInfoMain.RenderPass' instead
     //VkRenderPass                  RenderPass;                 // --> Since 2025/09/26: set 'PipelineInfoMain.RenderPass' instead
     //uint32_t                      Subpass;                    // --> Since 2025/09/26: set 'PipelineInfoMain.Subpass' instead
     //uint32_t                      Subpass;                    // --> Since 2025/09/26: set 'PipelineInfoMain.Subpass' instead
     //VkSampleCountFlagBits         MSAASamples;                // --> Since 2025/09/26: set 'PipelineInfoMain.MSAASamples' instead
     //VkSampleCountFlagBits         MSAASamples;                // --> Since 2025/09/26: set 'PipelineInfoMain.MSAASamples' instead
     //VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Since 2025/09/26: set 'PipelineInfoMain.PipelineRenderingCreateInfo' instead
     //VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Since 2025/09/26: set 'PipelineInfoMain.PipelineRenderingCreateInfo' instead
 
 
     // (Optional) Dynamic Rendering
     // (Optional) Dynamic Rendering
-    // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3 + setup PipelineInfoMain.PipelineRenderingCreateInfo.
+    // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3 + setup PipelineInfoMain.PipelineRenderingCreateInfo and PipelineInfoViewports.PipelineRenderingCreateInfo.
     bool                            UseDynamicRendering;
     bool                            UseDynamicRendering;
 
 
     // (Optional) Allocation, Debugging
     // (Optional) Allocation, Debugging

+ 8 - 0
docs/CHANGELOG.txt

@@ -109,6 +109,14 @@ Docking+Viewports Branch:
   backends have been shutdown since 1.90.4. Changed into asserts. (#7175, #8945)
   backends have been shutdown since 1.90.4. Changed into asserts. (#7175, #8945)
 - Backends: DX10, DX11, DX12: Disabled DXGI's Alt+Enter default behavior on secondary
 - Backends: DX10, DX11, DX12: Disabled DXGI's Alt+Enter default behavior on secondary
   viewports managed by the backend. (#4350) [@PathogenDavid]
   viewports managed by the backend. (#4350) [@PathogenDavid]
+- Backends: Vulkan: Added a way to configure secondary viewport pipelinen creation
+  by setting init_info.PipelineInfoForViewports fields. (#8946, #8110, #8111, #8686)
+- Backends: Vulkan: Added a way to configure secondary viewport swapchain VkImageUsageFlags
+  to e.g. capture rendering. (#8946, #8940) [@olivier-gerard, @ocornut]
+  Usage example:
+    `init_info.PipelineInfoForViewports.SwapChainImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;`
+- Backends: Vulkan: pipeline created for secondary viewport automatically match
+  surface format. (#8686) [@sylmroz]
 - Backends: Vulkan: Added ImGui_ImplVulkanH_GetWindowDataFromViewport() accessor/helper.
 - Backends: Vulkan: Added ImGui_ImplVulkanH_GetWindowDataFromViewport() accessor/helper.
   (#8946, #8940) [@olivier-gerard]
   (#8946, #8940) [@olivier-gerard]
 - Examples: DX10, DX11: Disabled DXGI's Alt+Enter default behavior in examples.
 - Examples: DX10, DX11: Disabled DXGI's Alt+Enter default behavior in examples.