Hello Triangle MSAA with Dynamic Rendering¶
This example shows modern Vulkan dynamic rendering which eliminates the need for VkRenderPass and VkFramebuffer objects. Dynamic rendering (Vulkan 1.3 core) simplifies rendering by specifying attachments directly in command buffers rather than pre-creating render pass objects. This reduces boilerplate, improves flexibility, and better matches modern GPU architectures. Compare with Hello Triangle MSAA to see the differences.
The example uses the KDGpuExample helper API for simplified setup.
Overview¶
What this example demonstrates:
- Enabling VK_KHR_dynamic_rendering extension
- Creating pipelines compatible with dynamic rendering
- Specifying attachments per command buffer (not pre-created)
- Manual layout transitions (no implicit conversions)
- MSAA with dynamic rendering
Use cases:
- Simplified rendering setup
- Dynamic attachment configurations
- Modern Vulkan 1.3+ applications
- Reducing object creation overhead
Vulkan Requirements¶
- Vulkan Version: 1.3+ (dynamic rendering core) or 1.2+ with extension
- Extensions: VK_KHR_dynamic_rendering (if Vulkan < 1.3)
- Features:
dynamicRendering
Key Concepts¶
Traditional Render Passes:
1 2 3 4 5 6 7 8 | |
Problems:
- Render passes are complex to create
- Framebuffers tie attachments to render passes
- Poor flexibility for dynamic scenarios
Dynamic Rendering:
1 2 3 4 5 6 7 8 | |
Benefits:
- No VkRenderPass/VkFramebuffer objects
- Attachments specified when needed
- Better for dynamic/procedural rendering
- Less validation overhead
Spec: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_dynamic_rendering.html
The first place to look is mkPipelineOptions, where the dynamicRendering flag is set. This function is called when the GraphicsPipeline are created and tells our pipeline will be using dynamic rendering.
1 2 3 4 5 6 | |
Filename: hello_triangle_msaa_dynamic_rendering/hello_triangle_msaa_dynamic_rendering.cpp
Next, we create the texture and a view with the correct multisampling configuration and new dimensions, which we will attach to the render pass option struct. Note that we use the type KDGpu::RenderPassCommandRecorderWithDynamicRenderingOptions instead of KDGpu::RenderPassCommandRecorderOptions. Whilst using RenderPassCommandRecorderOptions would lead to an internal implicit RenderPass being created to hold the attachment specifications, using KDGpu::RenderPassCommandRecorderWithDynamicRenderingOptions will use Vulkan's dynamic rendering extension to more efficiently and conveniently specify these information. Internally this means we don't have to maintain RenderPasses, Framebuffers ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Filename: hello_triangle_msaa_dynamic_rendering/hello_triangle_msaa_dynamic_rendering.cpp
The rendering submission itself doesn't change much. The noticeable change is we call renderImGuiOverlayDynamic instead of renderImGuiOverlay to render the ImGui overlay. That is so that we use a version that has a pipeline compatible with dynamic rendering.
1 2 3 4 5 6 7 8 9 | |
Filename: hello_triangle_msaa_dynamic_rendering/hello_triangle_msaa_dynamic_rendering.cpp
Notice that with dynamic rendering, there is no implicit initial and final layout conversions of the attachments. This means we have to take care of doing this part ourselves.
Prior to rendering:
1 2 3 4 5 6 7 8 9 10 11 12 | |
Filename: hello_triangle_msaa_dynamic_rendering/hello_triangle_msaa_dynamic_rendering.cpp
and after rendering, prior to presenting:
1 2 3 4 5 6 7 8 9 10 11 12 | |
Filename: hello_triangle_msaa_dynamic_rendering/hello_triangle_msaa_dynamic_rendering.cpp
Updated on 2026-03-31 at 00:02:07 +0000