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
This commit is contained in:
sean 2022-02-19 20:15:58 +01:00 committed by ocornut
parent dcdb145713
commit 7812e836e4
2 changed files with 45 additions and 3 deletions

View File

@ -212,6 +212,11 @@ IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
#undef IMGUI_VULKAN_FUNC_DEF #undef IMGUI_VULKAN_FUNC_DEF
#endif // VK_NO_PROTOTYPES #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 // SHADERS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -840,6 +845,19 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
info.layout = bd->PipelineLayout; info.layout = bd->PipelineLayout;
info.renderPass = renderPass; info.renderPass = renderPass;
info.subpass = subpass; 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); VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, allocator, pipeline);
check_vk_result(err); check_vk_result(err);
} }
@ -952,10 +970,16 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
return false; return false;
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD) IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
#undef 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 #else
IM_UNUSED(loader_func); IM_UNUSED(loader_func);
IM_UNUSED(user_data); IM_UNUSED(user_data);
#endif #endif
g_FunctionsLoaded = true; g_FunctionsLoaded = true;
return true; return true;
} }
@ -964,6 +988,20 @@ 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!"); 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(); ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
@ -980,6 +1018,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE); IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
IM_ASSERT(info->MinImageCount >= 2); IM_ASSERT(info->MinImageCount >= 2);
IM_ASSERT(info->ImageCount >= info->MinImageCount); IM_ASSERT(info->ImageCount >= info->MinImageCount);
if (!info->UseDynamicRendering)
IM_ASSERT(render_pass != VK_NULL_HANDLE); IM_ASSERT(render_pass != VK_NULL_HANDLE);
bd->VulkanInitInfo = *info; bd->VulkanInitInfo = *info;
@ -1297,7 +1336,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
vkDestroySwapchainKHR(device, old_swapchain, allocator); vkDestroySwapchainKHR(device, old_swapchain, allocator);
// Create the Render Pass // Create the Render Pass
{ if (!wd->UseDynamicRendering) {
VkAttachmentDescription attachment = {}; VkAttachmentDescription attachment = {};
attachment.format = wd->SurfaceFormat.format; attachment.format = wd->SurfaceFormat.format;
attachment.samples = VK_SAMPLE_COUNT_1_BIT; attachment.samples = VK_SAMPLE_COUNT_1_BIT;
@ -1359,7 +1398,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
} }
// Create Framebuffer // Create Framebuffer
{ if (!wd->UseDynamicRendering) {
VkImageView attachment[1]; VkImageView attachment[1];
VkFramebufferCreateInfo info = {}; VkFramebufferCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;

View File

@ -61,6 +61,8 @@ struct ImGui_ImplVulkan_InitInfo
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT) VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
const VkAllocationCallbacks* Allocator; const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err); 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 // Called by user code
@ -139,6 +141,7 @@ struct ImGui_ImplVulkanH_Window
VkPresentModeKHR PresentMode; VkPresentModeKHR PresentMode;
VkRenderPass RenderPass; VkRenderPass RenderPass;
VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo
bool UseDynamicRendering;
bool ClearEnable; bool ClearEnable;
VkClearValue ClearValue; VkClearValue ClearValue;
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount) uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)