Skip to main content

Khronos Blog

Streamlining Render Passes

When we were designing Vulkan 1.0, we had an idea to embed a task-graph-like object into Vulkan in the form of the render pass object. We knew the first version would be kind of restricted because we had an API to ship, and not long to do the work - but we had plans to extend the initial version, and those extensions would eventually provide significant flexibility to the API. Eventually, render passes would support all kinds of bells and whistles, including larger regions on input attachments, resolve shaders, and compute shaders! The idea was that these features would provide enough motivation to move all rendering to render pass objects and make the small amount of pain setting them up always worth it.

Fast forward to 2021, and the situation is not quite what we'd envisioned. On tiling GPUs, subpasses provide optimisation opportunities that can translate to impressive performance and efficiency wins. However, for many developers, subpasses either remain too restrictive to use or simply don't provide any practical benefit. For developers not using subpasses, render pass objects largely just get in the way.

It's time we addressed this.

Dynamic Rendering

So today we’re announcing VK_KHR_dynamic_rendering. With this extension you can tell the API to start rendering, and it will just do it - no render pass objects!

VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR(
    VkCommandBuffer               commandBuffer,
    const VkRenderingInfoKHR*     pRenderingInfo);

typedef struct VkRenderingInfoKHR {
    VkStructureType                     sType;
    const void*                         pNext;
    VkRenderingFlagsKHR                 flags;
VkRect2D renderArea;     uint32_t layerCount;     uint32_t viewMask;
uint32_t colorAttachmentCount;     const VkRenderingAttachmentInfoKHR* pColorAttachments;     const VkRenderingAttachmentInfoKHR* pDepthAttachment;
    const VkRenderingAttachmentInfoKHR* pStencilAttachment;
} VkRenderingInfoKHR;

And bonus: no framebuffer object either, just tell us the attachments. Move over VK_KHR_imageless_framebuffer, we don’t need you anymore!

Some of you are probably thinking: What about tiling GPUs?

If your renderer can make use of multiple subpasses or input attachments, we recommend you use the existing APIs - these remain the preferred way to get the best performance out of a tiling GPU. We are working on bringing more tiling features like framebuffer fetch and pixel local storage to dynamic rendering in the future, and will continue to update the community as we move forward.

If you’re not using multiple subpasses or input attachments though, go ahead, rip those render pass objects right out! Dynamic rendering offers similar rendering performance to a single pass render pass object but with a much simpler interface on all implementations. Hopefully this extension will make writing future Vulkan renderers just a bit more enjoyable.

We’re tracking the release of this extension in this public issue. Please refer to that tracker to find out when/how various components become available, including driver availability for some vendors.

If you do have any feedback on this extension, please let us know by either commenting on the tracker (while it remains open), or raising a separate issue on the Vulkan-Docs GitHub repository.

We’re Listening

We serve a large and diverse community of developers with different requirements and needs - and not just in terms of API specifications. While we can't prioritise every single request we get (there are a lot!), we do listen. With lively feedback from the Vulkan developer community pushing us forward, we’ve been steadily addressing many of the issues people have had with Vulkan since its inception. Many of the earlier fixes were "low hanging fruit", but we’re now gearing up to tackle some of the more challenging issues (like this one!).

We aim to ensure that any extension we develop and recommend is designed for everyone that interacts with it:

  • It has to address a real developer problem, and actually solve that problem when applied to real world codebases.
  • It not only has to be supported by all relevant hardware vendors, but has to be efficient and provide excellent performance.
  • Tooling (such as RenderDoc and the validation layers) must be able to function properly when the feature is enabled.

Getting to that point with this particular extension has taken a lot of care and patience, and meant overcoming some serious technical challenges for some hardware vendors (to whom we're extremely grateful). This is true for a few more things we've been working on as well. Over the next year you should start to see some of the more ambitious projects we’ve been undertaking being released; and we’re excited to show you what we’ve been working on!