Skip to content

Commit 03dd1a7

Browse files
committed
Merge branch 'feature/vk_re_create_pipeline_2' into feature/docking_vk_re_create_pipeline_2
2 parents 646df39 + 148060f commit 03dd1a7

File tree

2 files changed

+138
-24
lines changed

2 files changed

+138
-24
lines changed

backends/imgui_impl_vulkan.cpp

Lines changed: 116 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -887,10 +887,21 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca
887887
}
888888
}
889889

890-
static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline, uint32_t subpass)
890+
struct ImGui_ImplVulkan_PipelineCreateInfo
891+
{
892+
VkDevice Device = VK_NULL_HANDLE;
893+
const VkAllocationCallbacks* Allocator = nullptr;
894+
VkPipelineCache PipelineCache = VK_NULL_HANDLE;
895+
VkRenderPass RenderPass = VK_NULL_HANDLE;
896+
uint32_t Subpass = 0;
897+
VkSampleCountFlagBits MSAASamples = {};
898+
const ImGui_ImplVulkan_PipelineRenderingInfo* pRenderingInfo = nullptr;
899+
};
900+
901+
static VkPipeline ImGui_ImplVulkan_CreatePipeline(ImGui_ImplVulkan_PipelineCreateInfo const& pci)
891902
{
892903
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
893-
ImGui_ImplVulkan_CreateShaderModules(device, allocator);
904+
ImGui_ImplVulkan_CreateShaderModules(pci.Device, pci.Allocator);
894905

895906
VkPipelineShaderStageCreateInfo stage[2] = {};
896907
stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@@ -945,7 +956,7 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
945956

946957
VkPipelineMultisampleStateCreateInfo ms_info = {};
947958
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
948-
ms_info.rasterizationSamples = (MSAASamples != 0) ? MSAASamples : VK_SAMPLE_COUNT_1_BIT;
959+
ms_info.rasterizationSamples = (pci.MSAASamples != 0) ? pci.MSAASamples : VK_SAMPLE_COUNT_1_BIT;
949960

950961
VkPipelineColorBlendAttachmentState color_attachment[1] = {};
951962
color_attachment[0].blendEnable = VK_TRUE;
@@ -985,21 +996,22 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
985996
info.pColorBlendState = &blend_info;
986997
info.pDynamicState = &dynamic_state;
987998
info.layout = bd->PipelineLayout;
988-
info.renderPass = renderPass;
989-
info.subpass = subpass;
999+
info.renderPass = pci.RenderPass;
1000+
info.subpass = pci.Subpass;
9901001

9911002
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
9921003
if (bd->VulkanInitInfo.UseDynamicRendering)
9931004
{
994-
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
995-
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo pNext must be NULL");
996-
info.pNext = &bd->VulkanInitInfo.PipelineRenderingCreateInfo;
9971005
info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
1006+
IM_ASSERT(pci.pRenderingInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo::sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
1007+
IM_ASSERT(pci.pRenderingInfo->pNext == nullptr && "PipelineRenderingCreateInfo::pNext must be NULL");
1008+
info.pNext = pci.pRenderingInfo;
9981009
}
9991010
#endif
1000-
1001-
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, allocator, pipeline);
1011+
VkPipeline res;
1012+
VkResult err = vkCreateGraphicsPipelines(pci.Device, pci.PipelineCache, 1, &info, pci.Allocator, &res);
10021013
check_vk_result(err);
1014+
return res;
10031015
}
10041016

10051017
bool ImGui_ImplVulkan_CreateDeviceObjects()
@@ -1058,11 +1070,43 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
10581070
check_vk_result(err);
10591071
}
10601072

1061-
ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, v->RenderPass, v->MSAASamples, &bd->Pipeline, v->Subpass);
1062-
10631073
return true;
10641074
}
10651075

1076+
void ImGui_ImplVulkan_ReCreateMainPipeline(ImGui_ImplVulkan_MainPipelineCreateInfo const& info)
1077+
{
1078+
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
1079+
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
1080+
if (bd->Pipeline)
1081+
{
1082+
vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator);
1083+
bd->Pipeline = VK_NULL_HANDLE;
1084+
}
1085+
v->RenderPass = info.RenderPass;
1086+
v->MSAASamples = info.MSAASamples;
1087+
v->Subpass = info.Subpass;
1088+
1089+
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
1090+
if (info.pDynamicRendering)
1091+
{
1092+
v->PipelineRenderingCreateInfo = *info.pDynamicRendering;
1093+
}
1094+
#else
1095+
IM_ASSERT(p_dynamic_rendering == nullptr);
1096+
#endif
1097+
1098+
ImGui_ImplVulkan_PipelineCreateInfo pci;
1099+
pci.Device = v->Device;
1100+
pci.Allocator = v->Allocator;
1101+
pci.PipelineCache = v->PipelineCache;
1102+
pci.RenderPass = v->RenderPass;
1103+
pci.Subpass = v->Subpass;
1104+
pci.MSAASamples = v->MSAASamples;
1105+
pci.pRenderingInfo = info.pDynamicRendering;
1106+
1107+
bd->Pipeline = ImGui_ImplVulkan_CreatePipeline(pci);
1108+
}
1109+
10661110
void ImGui_ImplVulkan_DestroyDeviceObjects()
10671111
{
10681112
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
@@ -1145,10 +1189,11 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
11451189
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
11461190
IM_ASSERT(info->MinImageCount >= 2);
11471191
IM_ASSERT(info->ImageCount >= info->MinImageCount);
1148-
if (info->UseDynamicRendering == false)
1149-
IM_ASSERT(info->RenderPass != VK_NULL_HANDLE);
1192+
//if (info->UseDynamicRendering == false)
1193+
// IM_ASSERT(info->RenderPass != VK_NULL_HANDLE);
11501194

1151-
bd->VulkanInitInfo = *info;
1195+
ImGui_ImplVulkan_InitInfo * v = &bd->VulkanInitInfo;
1196+
*v = *info;
11521197

11531198
ImGui_ImplVulkan_CreateDeviceObjects();
11541199

@@ -1158,6 +1203,35 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
11581203

11591204
ImGui_ImplVulkan_InitMultiViewportSupport();
11601205

1206+
{
1207+
bool create_pipeline = false;
1208+
const ImGui_ImplVulkan_PipelineRenderingInfo * p_dynamic_rendering = nullptr;
1209+
if (v->RenderPass)
1210+
{
1211+
create_pipeline = true;
1212+
}
1213+
else
1214+
{
1215+
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
1216+
if (v->UseDynamicRendering && v->PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR)
1217+
{
1218+
p_dynamic_rendering = &v->PipelineRenderingCreateInfo;
1219+
create_pipeline = true;
1220+
}
1221+
#endif
1222+
}
1223+
if (create_pipeline)
1224+
{
1225+
ImGui_ImplVulkan_MainPipelineCreateInfo mp_info = {};
1226+
mp_info.RenderPass = v->RenderPass;
1227+
mp_info.Subpass = v->Subpass;
1228+
mp_info.MSAASamples = info->MSAASamples;
1229+
mp_info.pDynamicRendering = p_dynamic_rendering;
1230+
1231+
ImGui_ImplVulkan_ReCreateMainPipeline(mp_info);
1232+
}
1233+
}
1234+
11611235
return true;
11621236
}
11631237

@@ -1699,8 +1773,33 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
16991773
vd->WindowOwned = true;
17001774

17011775
// Create pipeline (shared by all secondary viewports)
1702-
if (bd->PipelineForViewports == VK_NULL_HANDLE)
1703-
ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &bd->PipelineForViewports, 0);
1776+
if (bd->PipelineForViewports == VK_NULL_HANDLE)
1777+
{
1778+
ImGui_ImplVulkan_PipelineCreateInfo pci;
1779+
pci.Device = v->Device;
1780+
pci.Allocator = v->Allocator;
1781+
pci.PipelineCache = VK_NULL_HANDLE;
1782+
pci.RenderPass = wd->RenderPass;
1783+
pci.Subpass = 0;
1784+
pci.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
1785+
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
1786+
VkPipelineRenderingCreateInfoKHR rendering_info = {};
1787+
if (wd->UseDynamicRendering)
1788+
{
1789+
rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
1790+
rendering_info.pNext = nullptr;
1791+
rendering_info.viewMask = 0;
1792+
rendering_info.colorAttachmentCount = 1;
1793+
rendering_info.pColorAttachmentFormats = &wd->SurfaceFormat.format;
1794+
rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
1795+
rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED;
1796+
pci.RenderPass = VK_NULL_HANDLE;
1797+
pci.pRenderingInfo = &rendering_info;
1798+
}
1799+
#endif
1800+
bd->PipelineForViewports = ImGui_ImplVulkan_CreatePipeline(pci);
1801+
1802+
}
17041803
}
17051804

17061805
static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport)

backends/imgui_impl_vulkan.h

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@
6262
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
6363
#endif
6464

65+
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
66+
typedef VkPipelineRenderingCreateInfoKHR ImGui_ImplVulkan_PipelineRenderingInfo;
67+
#else
68+
typedef void ImGui_ImplVulkan_PipelineRenderingInfo;
69+
#endif
70+
6571
// Initialization data, for ImGui_ImplVulkan_Init()
6672
// - VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
6773
// and must contain a pool size large enough to hold an ImGui VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor.
@@ -98,13 +104,22 @@ struct ImGui_ImplVulkan_InitInfo
98104
};
99105

100106
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
101-
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
102-
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
103-
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
104-
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
105-
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
106-
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
107-
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
107+
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info); // The main pipeline will be created if possible (RenderPass xor (UseDynamicRendering && PipelineRenderingCreateInfo->sType is correct))
108+
#define IMGUI_IMPL_VULKAN_HAS_MAIN_PIPELINE_RE_CREATION 1
109+
struct ImGui_ImplVulkan_MainPipelineCreateInfo
110+
{
111+
VkRenderPass RenderPass = VK_NULL_HANDLE;
112+
uint32_t Subpass = 0;
113+
VkSampleCountFlagBits MSAASamples = {};
114+
const ImGui_ImplVulkan_PipelineRenderingInfo* pDynamicRendering = nullptr;
115+
};
116+
IMGUI_IMPL_API void ImGui_ImplVulkan_ReCreateMainPipeline(ImGui_ImplVulkan_MainPipelineCreateInfo const& info); // (render_pass xor (p_dynamic_rendering && p_dynamic_rendering is correct (sType and pNext))
117+
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
118+
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
119+
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
120+
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
121+
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
122+
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
108123

109124
// Register a texture (VkDescriptorSet == ImTextureID)
110125
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem

0 commit comments

Comments
 (0)