3636#endif
3737
3838// #define APP_USE_UNLIMITED_FRAME_RATE
39+ // #define APP_USE_DYNAMIC_RENDERING
3940#ifdef _DEBUG
4041#define APP_USE_VULKAN_DEBUG_REPORT
4142static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
@@ -158,7 +159,14 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
158159 // Create Logical Device (with 1 queue)
159160 {
160161 ImVector<const char *> device_extensions;
161- device_extensions.push_back (" VK_KHR_swapchain" );
162+ device_extensions.push_back (VK_KHR_SWAPCHAIN_EXTENSION_NAME);
163+ #ifdef APP_USE_DYNAMIC_RENDERING
164+ device_extensions.push_back (VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
165+ device_extensions.push_back (VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME);
166+ device_extensions.push_back (VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
167+ device_extensions.push_back (VK_KHR_MAINTENANCE2_EXTENSION_NAME);
168+ device_extensions.push_back (VK_KHR_MULTIVIEW_EXTENSION_NAME);
169+ #endif
162170
163171 // Enumerate physical device extension
164172 uint32_t properties_count;
@@ -179,6 +187,13 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
179187 queue_info[0 ].pQueuePriorities = queue_priority;
180188 VkDeviceCreateInfo create_info = {};
181189 create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
190+ #ifdef APP_USE_DYNAMIC_RENDERING
191+ VkPhysicalDeviceDynamicRenderingFeaturesKHR physicalDeviceDynamicRenderingFeaturesKHR{};
192+ physicalDeviceDynamicRenderingFeaturesKHR.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR;
193+ physicalDeviceDynamicRenderingFeaturesKHR.pNext = nullptr ;
194+ physicalDeviceDynamicRenderingFeaturesKHR.dynamicRendering = VK_TRUE;
195+ create_info.pNext = &physicalDeviceDynamicRenderingFeaturesKHR;
196+ #endif
182197 create_info.queueCreateInfoCount = sizeof (queue_info) / sizeof (queue_info[0 ]);
183198 create_info.pQueueCreateInfos = queue_info;
184199 create_info.enabledExtensionCount = (uint32_t )device_extensions.Size ;
@@ -238,6 +253,9 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
238253
239254 // Create SwapChain, RenderPass, Framebuffer, etc.
240255 IM_ASSERT (g_MinImageCount >= 2 );
256+ #ifdef APP_USE_DYNAMIC_RENDERING
257+ wd->UseDynamicRendering = true ;
258+ #endif
241259 ImGui_ImplVulkanH_CreateOrResizeWindow (g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, 0 );
242260}
243261
@@ -290,6 +308,41 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
290308 err = vkBeginCommandBuffer (fd->CommandBuffer , &info);
291309 check_vk_result (err);
292310 }
311+
312+ // Begin rendering
313+ #ifdef APP_USE_DYNAMIC_RENDERING
314+ {
315+ VkImageMemoryBarrier barrier = {};
316+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
317+ barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
318+ barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
319+ barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
320+ barrier.image = fd->Backbuffer ;
321+ barrier.subresourceRange .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
322+ barrier.subresourceRange .levelCount = 1 ;
323+ barrier.subresourceRange .layerCount = 1 ;
324+ vkCmdPipelineBarrier (fd->CommandBuffer , VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0 , 0 , nullptr , 0 , nullptr , 1 , &barrier);
325+
326+ VkRenderingAttachmentInfoKHR attach_info = {};
327+ attach_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
328+ attach_info.imageView = fd->BackbufferView ;
329+ attach_info.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
330+ attach_info.loadOp = wd->AttachmentDesc .loadOp ;
331+ attach_info.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
332+ attach_info.clearValue = wd->ClearValue ;
333+
334+ VkRenderingInfoKHR info = {};
335+ info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR;
336+ info.renderArea .extent .width = wd->Width ;
337+ info.renderArea .extent .height = wd->Height ;
338+ info.layerCount = 1 ;
339+ info.colorAttachmentCount = 1 ;
340+ info.pColorAttachments = &attach_info;
341+
342+ static auto fn_vkCmdBeginRenderingKHR = reinterpret_cast <PFN_vkCmdBeginRenderingKHR>(vkGetDeviceProcAddr (g_Device, " vkCmdBeginRenderingKHR" ));
343+ fn_vkCmdBeginRenderingKHR (fd->CommandBuffer , &info);
344+ }
345+ #else
293346 {
294347 VkRenderPassBeginInfo info = {};
295348 info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@@ -301,12 +354,33 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
301354 info.pClearValues = &wd->ClearValue ;
302355 vkCmdBeginRenderPass (fd->CommandBuffer , &info, VK_SUBPASS_CONTENTS_INLINE);
303356 }
357+ #endif
304358
305359 // Record dear imgui primitives into command buffer
306360 ImGui_ImplVulkan_RenderDrawData (draw_data, fd->CommandBuffer );
307361
308- // Submit command buffer
309- vkCmdEndRenderPass (fd->CommandBuffer );
362+ // End rendering
363+ #ifdef APP_USE_DYNAMIC_RENDERING
364+ {
365+ static auto fn_vkCmdEndRenderingKHR = reinterpret_cast <PFN_vkCmdEndRenderingKHR>(vkGetDeviceProcAddr (g_Device, " vkCmdEndRenderingKHR" ));
366+ fn_vkCmdEndRenderingKHR (fd->CommandBuffer );
367+
368+ VkImageMemoryBarrier barrier = {};
369+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
370+ barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
371+ barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
372+ barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
373+ barrier.image = fd->Backbuffer ;
374+ barrier.subresourceRange .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
375+ barrier.subresourceRange .levelCount = 1 ;
376+ barrier.subresourceRange .layerCount = 1 ;
377+ vkCmdPipelineBarrier (fd->CommandBuffer , VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0 , 0 , nullptr , 0 , nullptr , 1 , &barrier);
378+ }
379+ #else
380+ {
381+ vkCmdEndRenderPass (fd->CommandBuffer );
382+ }
383+ #endif
310384 {
311385 VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
312386 VkSubmitInfo info = {};
@@ -426,9 +500,16 @@ int main(int, char**)
426500 init_info.MinImageCount = g_MinImageCount;
427501 init_info.ImageCount = wd->ImageCount ;
428502 init_info.Allocator = g_Allocator;
429- init_info.PipelineInfoMain .RenderPass = wd->RenderPass ;
430503 init_info.PipelineInfoMain .Subpass = 0 ;
431504 init_info.PipelineInfoMain .MSAASamples = VK_SAMPLE_COUNT_1_BIT;
505+ #ifdef APP_USE_DYNAMIC_RENDERING
506+ init_info.UseDynamicRendering = true ;
507+ init_info.PipelineInfoMain .PipelineRenderingCreateInfo .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
508+ init_info.PipelineInfoMain .PipelineRenderingCreateInfo .colorAttachmentCount = 1 ;
509+ init_info.PipelineInfoMain .PipelineRenderingCreateInfo .pColorAttachmentFormats = &wd->SurfaceFormat .format ;
510+ #else
511+ init_info.PipelineInfoMain .RenderPass = wd->RenderPass ;
512+ #endif
432513 init_info.CheckVkResultFn = check_vk_result;
433514 ImGui_ImplVulkan_Init (&init_info);
434515
0 commit comments