Backends: Vulkan: Support for dynamic_rendering (#5446, #5037)
Co-authored-by: Caio Oliveira <cmarcelo@gmail.com>
Simplified for master branch.
# Conflicts:
# backends/imgui_impl_vulkan.cpp
diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp
index c5ee279..57a6834 100644
--- a/backends/imgui_impl_vulkan.cpp
+++ b/backends/imgui_impl_vulkan.cpp
@@ -212,6 +212,11 @@
#undef IMGUI_VULKAN_FUNC_DEF
#endif // VK_NO_PROTOTYPES
+#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
+static PFN_vkCmdBeginRenderingKHR imgui_vkCmdBeginRenderingKHR;
+static PFN_vkCmdEndRenderingKHR imgui_vkCmdEndRenderingKHR;
+#endif
+
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------
@@ -840,6 +845,19 @@
info.layout = bd->PipelineLayout;
info.renderPass = renderPass;
info.subpass = subpass;
+
+#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
+ VkPipelineRenderingCreateInfoKHR pipelineRenderingCreateInfo = {};
+ pipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
+ pipelineRenderingCreateInfo.colorAttachmentCount = 1;
+ pipelineRenderingCreateInfo.pColorAttachmentFormats = &bd->VulkanInitInfo.ColorAttachmentFormat;
+
+ if (bd->VulkanInitInfo.UseDynamicRendering) {
+ info.pNext = &pipelineRenderingCreateInfo;
+ info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
+ }
+#endif
+
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, allocator, pipeline);
check_vk_result(err);
}
@@ -952,10 +970,16 @@
return false;
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
#undef IMGUI_VULKAN_FUNC_LOAD
+
+#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
+ imgui_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(loader_func("vkCmdBeginRenderingKHR", user_data));
+ imgui_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(loader_func("vkCmdEndRenderingKHR", user_data));
+#endif
#else
IM_UNUSED(loader_func);
IM_UNUSED(user_data);
#endif
+
g_FunctionsLoaded = true;
return true;
}
@@ -964,6 +988,20 @@
{
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
+ if (info->UseDynamicRendering) {
+#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
+#ifndef VK_NO_PROTOTYPES
+ imgui_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR"));
+ imgui_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR"));
+#endif
+
+ IM_ASSERT(imgui_vkCmdBeginRenderingKHR != nullptr);
+ IM_ASSERT(imgui_vkCmdEndRenderingKHR != nullptr);
+#else
+ IM_ASSERT(!"Can't use dynamic rendering when neither VK_VERSION_1_3 or VK_KHR_dynamic_rendering is defined.");
+#endif
+ }
+
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
@@ -980,7 +1018,8 @@
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
IM_ASSERT(info->MinImageCount >= 2);
IM_ASSERT(info->ImageCount >= info->MinImageCount);
- IM_ASSERT(render_pass != VK_NULL_HANDLE);
+ if (!info->UseDynamicRendering)
+ IM_ASSERT(render_pass != VK_NULL_HANDLE);
bd->VulkanInitInfo = *info;
bd->RenderPass = render_pass;
@@ -1297,7 +1336,7 @@
vkDestroySwapchainKHR(device, old_swapchain, allocator);
// Create the Render Pass
- {
+ if (!wd->UseDynamicRendering) {
VkAttachmentDescription attachment = {};
attachment.format = wd->SurfaceFormat.format;
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
@@ -1359,7 +1398,7 @@
}
// Create Framebuffer
- {
+ if (!wd->UseDynamicRendering) {
VkImageView attachment[1];
VkFramebufferCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h
index 64cc887..363c130 100644
--- a/backends/imgui_impl_vulkan.h
+++ b/backends/imgui_impl_vulkan.h
@@ -61,6 +61,8 @@
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err);
+ bool UseDynamicRendering; // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
+ VkFormat ColorAttachmentFormat;
};
// Called by user code
@@ -139,6 +141,7 @@
VkPresentModeKHR PresentMode;
VkRenderPass RenderPass;
VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo
+ bool UseDynamicRendering;
bool ClearEnable;
VkClearValue ClearValue;
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)