Skip to content

Commit 3470e61

Browse files
committed
(Breaking) Backends: Vulkan: moved fields in ImGui_ImplVulkan_InitInfo: RenderPass, Subpass, MSAASamples, PipelineRenderingCreateInfo. (#8946, #8110, #8111, #8686)
1 parent e312b99 commit 3470e61

File tree

8 files changed

+67
-72
lines changed

8 files changed

+67
-72
lines changed

backends/imgui_impl_vulkan.cpp

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
// CHANGELOG
2929
// (minor and older changes stripped away, please see git history for details)
30+
// 2025-09-26: *BREAKING CHANGE*: moved some fields in ImGui_ImplVulkan_InitInfo: init_info.RenderPass --> init_info.PipelineInfoMain.RenderPass, init_info.Subpass --> init_info.PipelineInfoMain.Subpass, init_info.MSAASamples --> init_info.PipelineInfoMain.MSAASamples, init_info.PipelineRenderingCreateInfo --> init_info.PipelineInfoMain.PipelineRenderingCreateInfo.
3031
// 2025-09-26: *BREAKING CHANGE*: renamed ImGui_ImplVulkan_MainPipelineCreateInfo to ImGui_ImplVulkan_PipelineInfo. Introduced very recently so shouldn't affect many users.
3132
// 2025-09-26: *BREAKING CHANGE*: helper ImGui_ImplVulkanH_CreateOrResizeWindow() added a VkImageUsageFlags image_usage` argument, default to VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT if 0.
3233
// 2025-09-26: Vulkan: Added a way to customize shaders by filling ImGui_ImplVulkan_InitInfo::CustomShaderVertCreateInfo/CustomShaderFragCreateInfo. (#8585)
@@ -918,7 +919,7 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca
918919
typedef void VkPipelineRenderingCreateInfoKHR;
919920
#endif
920921

921-
static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, uint32_t subpass, const VkPipelineRenderingCreateInfoKHR* pipeline_rendering_create_info)
922+
static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, const ImGui_ImplVulkan_PipelineInfo* info)
922923
{
923924
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
924925
ImGui_ImplVulkan_CreateShaderModules(device, allocator);
@@ -976,7 +977,7 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
976977

977978
VkPipelineMultisampleStateCreateInfo ms_info = {};
978979
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
979-
ms_info.rasterizationSamples = (MSAASamples != 0) ? MSAASamples : VK_SAMPLE_COUNT_1_BIT;
980+
ms_info.rasterizationSamples = (info->MSAASamples != 0) ? info->MSAASamples : VK_SAMPLE_COUNT_1_BIT;
980981

981982
VkPipelineColorBlendAttachmentState color_attachment[1] = {};
982983
color_attachment[0].blendEnable = VK_TRUE;
@@ -1016,20 +1017,17 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
10161017
create_info.pColorBlendState = &blend_info;
10171018
create_info.pDynamicState = &dynamic_state;
10181019
create_info.layout = bd->PipelineLayout;
1019-
create_info.renderPass = renderPass;
1020-
create_info.subpass = subpass;
1020+
create_info.renderPass = info->RenderPass;
1021+
create_info.subpass = info->Subpass;
10211022

10221023
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
10231024
if (bd->VulkanInitInfo.UseDynamicRendering)
10241025
{
1025-
IM_ASSERT(pipeline_rendering_create_info && "PipelineRenderingCreateInfo must not be nullptr when using dynamic rendering");
1026-
IM_ASSERT(pipeline_rendering_create_info->sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo::sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
1027-
IM_ASSERT(pipeline_rendering_create_info->pNext == nullptr && "PipelineRenderingCreateInfo::pNext must be nullptr");
1028-
create_info.pNext = pipeline_rendering_create_info;
1026+
IM_ASSERT(info->PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo::sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
1027+
IM_ASSERT(info->PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo::pNext must be nullptr");
1028+
create_info.pNext = &info->PipelineRenderingCreateInfo;
10291029
create_info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
10301030
}
1031-
#else
1032-
IM_ASSERT(pipeline_rendering_create_info == nullptr);
10331031
#endif
10341032
VkPipeline pipeline;
10351033
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &create_info, allocator, &pipeline);
@@ -1109,21 +1107,12 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
11091107
}
11101108

11111109
// Create pipeline
1112-
bool create_main_pipeline = (v->RenderPass != VK_NULL_HANDLE);
1110+
bool create_main_pipeline = (v->PipelineInfoMain.RenderPass != VK_NULL_HANDLE);
11131111
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
1114-
create_main_pipeline |= (v->UseDynamicRendering && v->PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR);
1112+
create_main_pipeline |= (v->UseDynamicRendering && v->PipelineInfoMain.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR);
11151113
#endif
11161114
if (create_main_pipeline)
1117-
{
1118-
ImGui_ImplVulkan_PipelineInfo mp_info = {};
1119-
mp_info.RenderPass = v->RenderPass;
1120-
mp_info.Subpass = v->Subpass;
1121-
mp_info.MSAASamples = v->MSAASamples;
1122-
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
1123-
mp_info.PipelineRenderingCreateInfo = v->PipelineRenderingCreateInfo;
1124-
#endif
1125-
ImGui_ImplVulkan_CreateMainPipeline(mp_info);
1126-
}
1115+
ImGui_ImplVulkan_CreateMainPipeline(&v->PipelineInfoMain);
11271116

11281117
// Create command pool/buffer for texture upload
11291118
if (!bd->TexCommandPool)
@@ -1148,7 +1137,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
11481137
return true;
11491138
}
11501139

1151-
void ImGui_ImplVulkan_CreateMainPipeline(const ImGui_ImplVulkan_PipelineInfo& info)
1140+
void ImGui_ImplVulkan_CreateMainPipeline(const ImGui_ImplVulkan_PipelineInfo* pipeline_info_in)
11521141
{
11531142
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
11541143
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
@@ -1157,28 +1146,23 @@ void ImGui_ImplVulkan_CreateMainPipeline(const ImGui_ImplVulkan_PipelineInfo& in
11571146
vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator);
11581147
bd->Pipeline = VK_NULL_HANDLE;
11591148
}
1160-
v->RenderPass = info.RenderPass;
1161-
v->MSAASamples = info.MSAASamples;
1162-
v->Subpass = info.Subpass;
1149+
ImGui_ImplVulkan_PipelineInfo* pipeline_info = &v->PipelineInfoMain;
1150+
if (pipeline_info != pipeline_info_in)
1151+
*pipeline_info = *pipeline_info_in;
11631152

1164-
const VkPipelineRenderingCreateInfoKHR* pipeline_rendering_create_info = nullptr;
11651153
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
1166-
if (v->UseDynamicRendering)
1154+
VkPipelineRenderingCreateInfoKHR* pipeline_rendering_create_info = &pipeline_info->PipelineRenderingCreateInfo;
1155+
if (v->UseDynamicRendering && pipeline_rendering_create_info->pColorAttachmentFormats != NULL)
11671156
{
1168-
v->PipelineRenderingCreateInfo = info.PipelineRenderingCreateInfo;
1169-
pipeline_rendering_create_info = &v->PipelineRenderingCreateInfo;
1170-
if (v->PipelineRenderingCreateInfo.pColorAttachmentFormats != NULL)
1171-
{
1172-
// Deep copy buffer to reduce error-rate for end user (#8282)
1173-
ImVector<VkFormat> formats;
1174-
formats.resize((int)v->PipelineRenderingCreateInfo.colorAttachmentCount);
1175-
memcpy(formats.Data, v->PipelineRenderingCreateInfo.pColorAttachmentFormats, (size_t)formats.size_in_bytes());
1176-
formats.swap(bd->PipelineRenderingCreateInfoColorAttachmentFormats);
1177-
v->PipelineRenderingCreateInfo.pColorAttachmentFormats = bd->PipelineRenderingCreateInfoColorAttachmentFormats.Data;
1178-
}
1157+
// Deep copy buffer to reduce error-rate for end user (#8282)
1158+
ImVector<VkFormat> formats;
1159+
formats.resize((int)pipeline_rendering_create_info->colorAttachmentCount);
1160+
memcpy(formats.Data, pipeline_rendering_create_info->pColorAttachmentFormats, (size_t)formats.size_in_bytes());
1161+
formats.swap(bd->PipelineRenderingCreateInfoColorAttachmentFormats);
1162+
pipeline_rendering_create_info->pColorAttachmentFormats = bd->PipelineRenderingCreateInfoColorAttachmentFormats.Data;
11791163
}
11801164
#endif
1181-
bd->Pipeline = ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, v->RenderPass, v->MSAASamples, v->Subpass, pipeline_rendering_create_info);
1165+
bd->Pipeline = ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, pipeline_info);
11821166
}
11831167

11841168
void ImGui_ImplVulkan_DestroyDeviceObjects()
@@ -1298,12 +1282,14 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
12981282
IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE);
12991283
IM_ASSERT(info->Device != VK_NULL_HANDLE);
13001284
IM_ASSERT(info->Queue != VK_NULL_HANDLE);
1285+
IM_ASSERT(info->MinImageCount >= 2);
1286+
IM_ASSERT(info->ImageCount >= info->MinImageCount);
13011287
if (info->DescriptorPool != VK_NULL_HANDLE) // Either DescriptorPool or DescriptorPoolSize must be set, not both!
13021288
IM_ASSERT(info->DescriptorPoolSize == 0);
13031289
else
13041290
IM_ASSERT(info->DescriptorPoolSize > 0);
1305-
IM_ASSERT(info->MinImageCount >= 2);
1306-
IM_ASSERT(info->ImageCount >= info->MinImageCount);
1291+
if (info->UseDynamicRendering)
1292+
IM_ASSERT(info->PipelineInfoMain.RenderPass == VK_NULL_HANDLE);
13071293

13081294
bd->VulkanInitInfo = *info;
13091295

backends/imgui_impl_vulkan.h

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@
6565
// Backend uses a small number of descriptors per font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
6666
#define IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE (8) // Minimum per atlas
6767

68+
// Specify settings to create pipeline and swapchain
69+
struct ImGui_ImplVulkan_PipelineInfo
70+
{
71+
// For Main and Secondary viewports
72+
VkRenderPass RenderPass; // Ignored if using dynamic rendering
73+
uint32_t Subpass; //
74+
VkSampleCountFlagBits MSAASamples = {}; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
75+
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
76+
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
77+
#endif
78+
};
79+
6880
// Initialization data, for ImGui_ImplVulkan_Init()
6981
// [Please zero-clear before use!]
7082
// - About descriptor pool:
@@ -88,16 +100,15 @@ struct ImGui_ImplVulkan_InitInfo
88100
VkPipelineCache PipelineCache; // Optional
89101

90102
// Pipeline
91-
VkRenderPass RenderPass; // Ignored if using dynamic rendering
92-
uint32_t Subpass;
93-
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
103+
ImGui_ImplVulkan_PipelineInfo PipelineInfoMain; // Infos for Main Viewport (created by app/user)
104+
//VkRenderPass RenderPass; // --> Since 2025/09/26: set 'PipelineInfoMain.RenderPass' instead
105+
//uint32_t Subpass; // --> Since 2025/09/26: set 'PipelineInfoMain.Subpass' instead
106+
//VkSampleCountFlagBits MSAASamples; // --> Since 2025/09/26: set 'PipelineInfoMain.MSAASamples' instead
107+
//VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Since 2025/09/26: set 'PipelineInfoMain.PipelineRenderingCreateInfo' instead
94108

95109
// (Optional) Dynamic Rendering
96-
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3 + setup PipelineRenderingCreateInfo.
110+
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3 + setup PipelineInfoMain.PipelineRenderingCreateInfo.
97111
bool UseDynamicRendering;
98-
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
99-
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
100-
#endif
101112

102113
// (Optional) Allocation, Debugging
103114
const VkAllocationCallbacks* Allocator;
@@ -121,16 +132,7 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_i
121132
// (Advanced) Use e.g. if you need to recreate pipeline without reinitializing the backend (see #8110, #8111)
122133
// The main window pipeline will be created by ImGui_ImplVulkan_Init() if possible (== RenderPass xor (UseDynamicRendering && PipelineRenderingCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR))
123134
// Else, the pipeline can be created, or re-created, using ImGui_ImplVulkan_CreateMainPipeline() before rendering.
124-
struct ImGui_ImplVulkan_PipelineInfo
125-
{
126-
VkRenderPass RenderPass = VK_NULL_HANDLE;
127-
uint32_t Subpass = 0;
128-
VkSampleCountFlagBits MSAASamples = {};
129-
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
130-
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
131-
#endif
132-
};
133-
IMGUI_IMPL_API void ImGui_ImplVulkan_CreateMainPipeline(const ImGui_ImplVulkan_PipelineInfo& info); // (render_pass xor (p_dynamic_rendering && p_dynamic_rendering is correct (sType and pNext)))
135+
IMGUI_IMPL_API void ImGui_ImplVulkan_CreateMainPipeline(const ImGui_ImplVulkan_PipelineInfo* info);
134136

135137
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
136138
IMGUI_IMPL_API void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex);

docs/CHANGELOG.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ HOW TO UPDATE?
4141

4242
Breaking Changes:
4343

44+
- Backends: Vulkan: moved some fields in ImGui_ImplVulkan_InitInfo:
45+
init_info.RenderPass --> init_info.PipelineInfoMain.RenderPass
46+
init_info.Subpass --> init_info.PipelineInfoMain.Subpass
47+
init_info.MSAASamples --> init_info.PipelineInfoMain.MSAASamples
48+
init_info.PipelineRenderingCreateInfo --> init_info.PipelineInfoMain.PipelineRenderingCreateInfo
49+
It makes things more consistent and was desirable to introduce new settings for
50+
secondary viewports. (#8946, #8110, #8111, #8686) [@ocornut, @SuperRonan, @sylmroz]
4451
- Backends: Vulkan: renamed ImGui_ImplVulkan_MainPipelineCreateInfo --> ImGui_ImplVulkan_PipelineInfo
4552
(introduced very recently and only used by `ImGui_ImplVulkan_CreateMainPipeline()`
4653
so it should not affect many users). (#8110, #8111)

examples/example_glfw_vulkan/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,12 @@ int main(int, char**)
411411
init_info.Queue = g_Queue;
412412
init_info.PipelineCache = g_PipelineCache;
413413
init_info.DescriptorPool = g_DescriptorPool;
414-
init_info.RenderPass = wd->RenderPass;
415-
init_info.Subpass = 0;
416414
init_info.MinImageCount = g_MinImageCount;
417415
init_info.ImageCount = wd->ImageCount;
418-
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
419416
init_info.Allocator = g_Allocator;
417+
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
418+
init_info.PipelineInfoMain.Subpass = 0;
419+
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
420420
init_info.CheckVkResultFn = check_vk_result;
421421
ImGui_ImplVulkan_Init(&init_info);
422422

examples/example_sdl2_vulkan/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,12 @@ int main(int, char**)
417417
init_info.Queue = g_Queue;
418418
init_info.PipelineCache = g_PipelineCache;
419419
init_info.DescriptorPool = g_DescriptorPool;
420-
init_info.RenderPass = wd->RenderPass;
421-
init_info.Subpass = 0;
422420
init_info.MinImageCount = g_MinImageCount;
423421
init_info.ImageCount = wd->ImageCount;
424-
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
425422
init_info.Allocator = g_Allocator;
423+
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
424+
init_info.PipelineInfoMain.Subpass = 0;
425+
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
426426
init_info.CheckVkResultFn = check_vk_result;
427427
ImGui_ImplVulkan_Init(&init_info);
428428

examples/example_sdl3_vulkan/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,12 +416,12 @@ int main(int, char**)
416416
init_info.Queue = g_Queue;
417417
init_info.PipelineCache = g_PipelineCache;
418418
init_info.DescriptorPool = g_DescriptorPool;
419-
init_info.RenderPass = wd->RenderPass;
420-
init_info.Subpass = 0;
421419
init_info.MinImageCount = g_MinImageCount;
422420
init_info.ImageCount = wd->ImageCount;
423-
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
424421
init_info.Allocator = g_Allocator;
422+
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
423+
init_info.PipelineInfoMain.Subpass = 0;
424+
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
425425
init_info.CheckVkResultFn = check_vk_result;
426426
ImGui_ImplVulkan_Init(&init_info);
427427

examples/example_win32_vulkan/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,12 @@ int main(int, char**)
404404
init_info.Queue = g_Queue;
405405
init_info.PipelineCache = g_PipelineCache;
406406
init_info.DescriptorPool = g_DescriptorPool;
407-
init_info.RenderPass = wd->RenderPass;
408-
init_info.Subpass = 0;
409407
init_info.MinImageCount = g_MinImageCount;
410408
init_info.ImageCount = wd->ImageCount;
411-
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
412409
init_info.Allocator = g_Allocator;
410+
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
411+
init_info.PipelineInfoMain.Subpass = 0;
412+
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
413413
init_info.CheckVkResultFn = check_vk_result;
414414
ImGui_ImplVulkan_Init(&init_info);
415415

imgui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
// Library Version
3030
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
3131
#define IMGUI_VERSION "1.92.4 WIP"
32-
#define IMGUI_VERSION_NUM 19232
32+
#define IMGUI_VERSION_NUM 19233
3333
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
3434
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
3535

0 commit comments

Comments
 (0)