Skip to content

Commit e6750fc

Browse files
Body428qiyuewuyi2333
authored andcommitted
examples/vulkan: add optional dynamic rendering support (APP_USE_DYNAMIC_RENDERING)
Add opt-in dynamic rendering support to all four Vulkan examples (glfw, sdl2, sdl3, win32) via a commented-out macro at the top of each main.cpp: //#define APP_USE_DYNAMIC_RENDERING
1 parent bbcc83e commit e6750fc

4 files changed

Lines changed: 331 additions & 10 deletions

File tree

examples/example_glfw_vulkan/main.cpp

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
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
4142
static 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

examples/example_sdl2_vulkan/main.cpp

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#endif
3232

3333
//#define APP_USE_UNLIMITED_FRAME_RATE
34+
//#define APP_USE_DYNAMIC_RENDERING
3435
#ifdef _DEBUG
3536
#define APP_USE_VULKAN_DEBUG_REPORT
3637
static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
@@ -150,6 +151,13 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
150151
{
151152
ImVector<const char*> device_extensions;
152153
device_extensions.push_back("VK_KHR_swapchain");
154+
#ifdef APP_USE_DYNAMIC_RENDERING
155+
device_extensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
156+
device_extensions.push_back(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME);
157+
device_extensions.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
158+
device_extensions.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
159+
device_extensions.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
160+
#endif
153161

154162
// Enumerate physical device extension
155163
uint32_t properties_count;
@@ -170,6 +178,13 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
170178
queue_info[0].pQueuePriorities = queue_priority;
171179
VkDeviceCreateInfo create_info = {};
172180
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
181+
#ifdef APP_USE_DYNAMIC_RENDERING
182+
VkPhysicalDeviceDynamicRenderingFeaturesKHR physicalDeviceDynamicRenderingFeaturesKHR{};
183+
physicalDeviceDynamicRenderingFeaturesKHR.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR;
184+
physicalDeviceDynamicRenderingFeaturesKHR.pNext = nullptr;
185+
physicalDeviceDynamicRenderingFeaturesKHR.dynamicRendering = VK_TRUE;
186+
create_info.pNext = &physicalDeviceDynamicRenderingFeaturesKHR;
187+
#endif
173188
create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]);
174189
create_info.pQueueCreateInfos = queue_info;
175190
create_info.enabledExtensionCount = (uint32_t)device_extensions.Size;
@@ -229,6 +244,9 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
229244

230245
// Create SwapChain, RenderPass, Framebuffer, etc.
231246
IM_ASSERT(g_MinImageCount >= 2);
247+
#ifdef APP_USE_DYNAMIC_RENDERING
248+
wd->UseDynamicRendering = true;
249+
#endif
232250
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, 0);
233251
}
234252

@@ -281,6 +299,41 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
281299
err = vkBeginCommandBuffer(fd->CommandBuffer, &info);
282300
check_vk_result(err);
283301
}
302+
303+
// Begin rendering
304+
#ifdef APP_USE_DYNAMIC_RENDERING
305+
{
306+
VkImageMemoryBarrier barrier = {};
307+
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
308+
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
309+
barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
310+
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
311+
barrier.image = fd->Backbuffer;
312+
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
313+
barrier.subresourceRange.levelCount = 1;
314+
barrier.subresourceRange.layerCount = 1;
315+
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
316+
317+
VkRenderingAttachmentInfoKHR attach_info = {};
318+
attach_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
319+
attach_info.imageView = fd->BackbufferView;
320+
attach_info.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
321+
attach_info.loadOp = wd->AttachmentDesc.loadOp;
322+
attach_info.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
323+
attach_info.clearValue = wd->ClearValue;
324+
325+
VkRenderingInfoKHR info = {};
326+
info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR;
327+
info.renderArea.extent.width = wd->Width;
328+
info.renderArea.extent.height = wd->Height;
329+
info.layerCount = 1;
330+
info.colorAttachmentCount = 1;
331+
info.pColorAttachments = &attach_info;
332+
333+
static auto fn_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetDeviceProcAddr(g_Device, "vkCmdBeginRenderingKHR"));
334+
fn_vkCmdBeginRenderingKHR(fd->CommandBuffer, &info);
335+
}
336+
#else
284337
{
285338
VkRenderPassBeginInfo info = {};
286339
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@@ -292,12 +345,33 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
292345
info.pClearValues = &wd->ClearValue;
293346
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
294347
}
348+
#endif
295349

296350
// Record dear imgui primitives into command buffer
297351
ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer);
298352

299-
// Submit command buffer
300-
vkCmdEndRenderPass(fd->CommandBuffer);
353+
// End rendering
354+
#ifdef APP_USE_DYNAMIC_RENDERING
355+
{
356+
static auto fn_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetDeviceProcAddr(g_Device, "vkCmdEndRenderingKHR"));
357+
fn_vkCmdEndRenderingKHR(fd->CommandBuffer);
358+
359+
VkImageMemoryBarrier barrier = {};
360+
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
361+
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
362+
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
363+
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
364+
barrier.image = fd->Backbuffer;
365+
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
366+
barrier.subresourceRange.levelCount = 1;
367+
barrier.subresourceRange.layerCount = 1;
368+
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
369+
}
370+
#else
371+
{
372+
vkCmdEndRenderPass(fd->CommandBuffer);
373+
}
374+
#endif
301375
{
302376
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
303377
VkSubmitInfo info = {};
@@ -435,6 +509,12 @@ int main(int, char**)
435509
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
436510
init_info.PipelineInfoMain.Subpass = 0;
437511
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
512+
#ifdef APP_USE_DYNAMIC_RENDERING
513+
init_info.UseDynamicRendering = true;
514+
init_info.PipelineInfoMain.PipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
515+
init_info.PipelineInfoMain.PipelineRenderingCreateInfo.colorAttachmentCount = 1;
516+
init_info.PipelineInfoMain.PipelineRenderingCreateInfo.pColorAttachmentFormats = &wd->SurfaceFormat.format;
517+
#endif
438518
init_info.CheckVkResultFn = check_vk_result;
439519
ImGui_ImplVulkan_Init(&init_info);
440520

0 commit comments

Comments
 (0)