From 121072cfe6df7f6478b098ad79d66b85dec76132 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 3 Jul 2023 17:48:28 +0200 Subject: [PATCH] Backends: Vulkan: Amend for support for dynamic_rendering (#5446, #5037) Simplified for master branch. # Conflicts: # backends/imgui_impl_vulkan.cpp --- backends/imgui_impl_vulkan.cpp | 43 +++++++++++++++++++--------------- backends/imgui_impl_vulkan.h | 8 +++++-- docs/CHANGELOG.txt | 3 +++ 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 57a68345..88872896 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -30,6 +30,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2023-07-04: Vulkan: Added optional support for VK_KHR_dynamic_rendering. User needs to set init_info->UseDynamicRendering = true and init_info->ColorAttachmentFormat. // 2023-01-02: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored + removed a bunch of duplicate code. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-04: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symetry. (#914, #5738). @@ -213,8 +214,9 @@ IMGUI_VULKAN_FUNC_MAP(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; +#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING +static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR; +static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR; #endif //----------------------------------------------------------------------------- @@ -846,13 +848,13 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC info.renderPass = renderPass; info.subpass = subpass; -#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering) +#ifdef IMGUI_IMPL_VULKAN_HAS_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) { + if (bd->VulkanInitInfo.UseDynamicRendering) + { info.pNext = &pipelineRenderingCreateInfo; info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr. } @@ -971,9 +973,10 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch 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(loader_func("vkCmdBeginRenderingKHR", user_data)); - imgui_vkCmdEndRenderingKHR = reinterpret_cast(loader_func("vkCmdEndRenderingKHR", user_data)); +#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING + // Manually load those two (see #5446) + ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast(loader_func("vkCmdBeginRenderingKHR", user_data)); + ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast(loader_func("vkCmdEndRenderingKHR", user_data)); #endif #else IM_UNUSED(loader_func); @@ -988,17 +991,17 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend { 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) + if (info->UseDynamicRendering) + { +#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING #ifndef VK_NO_PROTOTYPES - imgui_vkCmdBeginRenderingKHR = reinterpret_cast(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR")); - imgui_vkCmdEndRenderingKHR = reinterpret_cast(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR")); + ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR")); + ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR")); #endif - - IM_ASSERT(imgui_vkCmdBeginRenderingKHR != nullptr); - IM_ASSERT(imgui_vkCmdEndRenderingKHR != nullptr); + IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR != nullptr); + IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR != nullptr); #else - IM_ASSERT(!"Can't use dynamic rendering when neither VK_VERSION_1_3 or VK_KHR_dynamic_rendering is defined."); + IM_ASSERT(0 && "Can't use dynamic rendering when neither VK_VERSION_1_3 or VK_KHR_dynamic_rendering is defined."); #endif } @@ -1018,7 +1021,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE); IM_ASSERT(info->MinImageCount >= 2); IM_ASSERT(info->ImageCount >= info->MinImageCount); - if (!info->UseDynamicRendering) + if (info->UseDynamicRendering == false) IM_ASSERT(render_pass != VK_NULL_HANDLE); bd->VulkanInitInfo = *info; @@ -1336,7 +1339,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V vkDestroySwapchainKHR(device, old_swapchain, allocator); // Create the Render Pass - if (!wd->UseDynamicRendering) { + if (wd->UseDynamicRendering == false) + { VkAttachmentDescription attachment = {}; attachment.format = wd->SurfaceFormat.format; attachment.samples = VK_SAMPLE_COUNT_1_BIT; @@ -1398,7 +1402,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V } // Create Framebuffer - if (!wd->UseDynamicRendering) { + if (wd->UseDynamicRendering == false) + { 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 363c130c..56bfe309 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -59,10 +59,14 @@ struct ImGui_ImplVulkan_InitInfo uint32_t MinImageCount; // >= 2 uint32_t ImageCount; // >= MinImageCount VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT) + + // Dynamic Rendering (Optional) + bool UseDynamicRendering; // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3. + VkFormat ColorAttachmentFormat; // Required for dynamic rendering + + // Allocation, Debugging 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 diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a4e7acce..e79869ab 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -107,6 +107,9 @@ Other changes: - Backends: OpenGL3: Fixed support for glBindSampler() backup/restore on ES3. (#6375, #6508) [@jsm174] - Backends: OpenGL3: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333) [@krumelmonster] +- Backends: Vulkan: Added optional support for VK_KHR_dynamic_rendering (Vulkan 1.3+) in the + backend for applications using it. User needs to set 'init_info->UseDynamicRendering = true' + and 'init_info->ColorAttachmentFormat'. RenderPass becomes unused. (#5446, #5037) [@spnda, @cmarcelo] - Backends: GLFW: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser+Emscripten. Matches similar 1.89.4 fix in SDL backend. (#6491)