# Render Passes

The Vulkan runtime code in Mesa provides several helpful utilities to make managing render passes easier.

## VK_KHR_create_renderpass2

It is strongly recommended that drivers implement VK_KHR_create_renderpass2 directly and not bother implementing the old Vulkan 1.0 entrypoints. If a driver does not implement them, the following will be implemented in common code in terms of their VK_KHR_create_renderpass2 counterparts:

> - `vkCreateRenderPass()`

> - `vkCmdBeginRenderPass()`

> - `vkCmdNextSubpass()`

> - `vkCmdEndRenderPass()`

## Common VkRenderPass implementation

The Vulkan runtime code in Mesa provides a common implementation of `VkRenderPass` called `vk_render_pass` which drivers can optionally use. Unlike most Vulkan runtime structs, it’s not really designed to be used as a base for a driver-specific struct. It does, however, contain all the information passed to `vkCreateRenderPass2()` so it can be used in a driver so long as that driver doesn’t need to do any additional compilation at `vkCreateRenderPass2()` time. If a driver chooses to use `vk_render_pass`, the Vulkan runtime provides implementations of `vkCreateRenderPass2()` and `vkDestroyRenderPass()`.

## VK_KHR_dynamic_rendering

For drivers which don’t need to do subpass combining, it is recommended that they skip implementing render passes entirely and implement VK_KHR_dynamic_rendering instead. If they choose to do so, the runtime will provide the following, implemented in terms of `vkCmdBeginRendering()` and `vkCmdEndRendering()`:

> - `vkCmdBeginRenderPass2()`

> - `vkCmdNextSubpass2()`

> - `vkCmdEndRenderPass2()`

We also provide a no-op implementation of `vkGetRenderAreaGranularity()` which returns a render area granularity of 1x1.

Drivers which wish to use the common render pass implementation in this way must also support a Mesa-specific pseudo-extension which optionally provides an initial image layout for each attachment at `vkCmdBeginRendering()` time. This is required for us to combine render pass clears with layout transitions, often from `VK_IMAGE_LAYOUT_UNDEFINED`. On at least Intel and AMD, combining these transitions with clears is important for performance.

struct VkRenderingAttachmentInitialLayoutInfoMESA

  Pseudo-extension struct that may be chained into VkRenderingAttachmentInfo to indicate an initial layout for the attachment. This is only allowed if all of the following conditions are met:

  > 1. VkRenderingAttachmentInfo::loadOp == LOAD_OP_CLEAR

  > 2. VkRenderingInfo::renderArea is the entire image view LOD

  > 3. For 3D image attachments, VkRenderingInfo::viewMask == 0 AND VkRenderingInfo::layerCount references the entire bound image view OR VkRenderingInfo::viewMask is dense (no holes) and references the entire bound image view. (2D and 2D array images have no such requirement.)

  If this struct is included in the pNext chain of a VkRenderingAttachmentInfo, the driver is responsible for transitioning the bound region of the image from VkRenderingAttachmentInitialLayoutInfoMESA::initialLayout to VkRenderingAttachmentInfo::imageLayout prior to rendering.

  VkImageLayout initialLayout

    Initial layout of the attachment

Because render passes and subpass indices are also passed into `vkCmdCreateGraphicsPipelines()` and `vkCmdExecuteCommands()` which we can’t implement on the driver’s behalf, we provide a couple of helpers for getting the render pass information in terms of the relevant VK_KHR_dynamic_rendering:

const VkPipelineRenderingCreateInfo *vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info)

  Returns the VkPipelineRenderingCreateInfo for a graphics pipeline

  For render-pass-free drivers, this can be used in the implementation of vkCreateGraphicsPipelines to get the VkPipelineRenderingCreateInfo. If VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will return a representation of the specified subpass as a VkPipelineRenderingCreateInfo. If VkGraphicsPipelineCreateInfo::renderPass is VK_NULL_HANDLE and there is a VkPipelineRenderingCreateInfo in the pNext chain of VkGraphicsPipelineCreateInfo, it will return that.

  Parameters:

    - info – [in] One of the pCreateInfos from vkCreateGraphicsPipelines

const VkCommandBufferInheritanceRenderingInfo *vk_get_command_buffer_inheritance_rendering_info(VkCommandBufferLevel level, const VkCommandBufferBeginInfo *pBeginInfo)

  Returns the VkCommandBufferInheritanceRenderingInfo for secondary command buffer execution

  For render-pass-free drivers, this can be used in the implementation of vkCmdExecuteCommands to get the VkCommandBufferInheritanceRenderingInfo. If VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE, it will return a representation of the specified subpass as a VkCommandBufferInheritanceRenderingInfo. If VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE and there is a VkCommandBufferInheritanceRenderingInfo in the pNext chain of VkCommandBufferBeginInfo, it will return that.

  Parameters:

    - level – [in] The nesting level of this command buffer

    - pBeginInfo – [in] The pBeginInfo from vkBeginCommandBuffer

Apart from handling layout transitions, the common render pass implementation mostly ignores input attachments. It is expected that the driver call `nir_lower_input_attachments()` to turn them into texturing operations. The driver must support texturing from an input attachment at the same time as rendering to it in order to support Vulkan subpass self-dependencies. `VK_EXT_attachment_feedback_loop_layout` provides information on when these self dependencies are present.

## vk_render_pass reference

The following is a reference for the `vk_render_pass` structure and its substructures.

struct vk_render_pass
  bool is_multiview

    True if this render pass uses multiview

    This is true if all subpasses have viewMask != 0.

  uint32_t view_mask

    Views used by this render pass or 1 for non-multiview

  uint32_t attachment_count

    VkRenderPassCreateInfo2::attachmentCount

  struct vk_render_pass_attachment *attachments

    VkRenderPassCreateInfo2::pAttachments

  uint32_t subpass_count

    VkRenderPassCreateInfo2::subpassCount

  struct vk_subpass *subpasses

    VkRenderPassCreateInfo2::subpasses

  uint32_t dependency_count

    VkRenderPassCreateInfo2::dependencyCount

  VkAttachmentReference fragment_density_map

    VkRenderPassFragmentDensityMapCreateInfoEXT::fragmentDensityMapAttachment

  struct vk_subpass_dependency *dependencies

    VkRenderPassCreateInfo2::pDependencies

struct vk_render_pass_attachment
  VkFormat format

    VkAttachmentDescription2::format

  VkImageAspectFlags aspects

    Aspects contained in format

  uint32_t samples

    VkAttachmentDescription2::samples

  uint32_t view_mask

    Views in which this attachment is used, 0 for unused

    For non-multiview, this will be 1 if the attachment is used.

  VkAttachmentLoadOp load_op

    VkAttachmentDescription2::loadOp

  VkAttachmentStoreOp store_op

    VkAttachmentDescription2::storeOp

  VkAttachmentLoadOp stencil_load_op

    VkAttachmentDescription2::stencilLoadOp

  VkAttachmentStoreOp stencil_store_op

    VkAttachmentDescription2::stencilStoreOp

  VkImageLayout initial_layout

    VkAttachmentDescription2::initialLayout

  VkImageLayout final_layout

    VkAttachmentDescription2::finalLayout

  VkImageLayout initial_stencil_layout

    VkAttachmentDescriptionStencilLayout::stencilInitialLayout

    If VK_KHR_separate_depth_stencil_layouts is not used, this will be initial_layout if format contains stencil and VK_IMAGE_LAYOUT_UNDEFINED otherwise.

  VkImageLayout final_stencil_layout

    VkAttachmentDescriptionStencilLayout::stencilFinalLayout

    If VK_KHR_separate_depth_stencil_layouts is not used, this will be final_layout if format contains stencil and VK_IMAGE_LAYOUT_UNDEFINED otherwise.

  bool has_external_format

    Whether VkExternalFormatANDROID is part of this render pass

struct vk_subpass
  uint32_t attachment_count

    Count of all attachments referenced by this subpass

  struct vk_subpass_attachment *attachments

    Array of all attachments referenced by this subpass

  uint32_t input_count

    VkSubpassDescription2::inputAttachmentCount

  struct vk_subpass_attachment *input_attachments

    VkSubpassDescription2::pInputAttachments

  uint32_t color_count

    VkSubpassDescription2::colorAttachmentCount

  struct vk_subpass_attachment *color_attachments

    VkSubpassDescription2::pColorAttachments

  uint32_t color_resolve_count

    VkSubpassDescription2::colorAttachmentCount or zero

  struct vk_subpass_attachment *color_resolve_attachments

    VkSubpassDescription2::pResolveAttachments

  struct vk_subpass_attachment *depth_stencil_attachment

    VkSubpassDescription2::pDepthStencilAttachment

  struct vk_subpass_attachment *depth_stencil_resolve_attachment

    VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment

  struct vk_subpass_attachment *fragment_shading_rate_attachment

    VkFragmentShadingRateAttachmentInfoKHR::pFragmentShadingRateAttachment

  uint32_t view_mask

    VkSubpassDescription2::viewMask or 1 for non-multiview

    For all view masks in the vk_render_pass data structure, we use a mask of 1 for non-multiview instead of a mask of 0. To determine if the render pass is multiview or not, see vk_render_pass::is_multiview.

  VkResolveModeFlagBits depth_resolve_mode

    VkSubpassDescriptionDepthStencilResolve::depthResolveMode

  VkResolveModeFlagBits stencil_resolve_mode

    VkSubpassDescriptionDepthStencilResolve::stencilResolveMode

  VkExtent2D fragment_shading_rate_attachment_texel_size

    VkFragmentShadingRateAttachmentInfoKHR::shadingRateAttachmentTexelSize

  VkPipelineCreateFlagBits2KHR pipeline_flags

    Extra VkPipelineCreateFlags for this subpass

  VkAttachmentSampleCountInfoAMD sample_count_info_amd

    VkAttachmentSampleCountInfoAMD for this subpass

    This is in the pNext chain of pipeline_info and inheritance_info.

  struct [anonymous]

    VkRenderingInputAttachmentIndexInfo for this subpass

    This is in the pNext chain of pipeline_info and inheritance_info.

    Also returned by vk_get_pipeline_rendering_ial_info() if VkGraphicsPipelineCreateInfo::renderPass != VK_NULL_HANDLE.

  VkPipelineRenderingCreateInfo pipeline_info

    VkPipelineRenderingCreateInfo for this subpass

    Returned by vk_get_pipeline_rendering_create_info() if VkGraphicsPipelineCreateInfo::renderPass != VK_NULL_HANDLE.

  VkCommandBufferInheritanceRenderingInfo inheritance_info

    VkCommandBufferInheritanceRenderingInfo for this subpass

    Returned by vk_get_command_buffer_inheritance_rendering_info() if VkCommandBufferInheritanceInfo::renderPass != VK_NULL_HANDLE.

  VkMultisampledRenderToSingleSampledInfoEXT mrtss

    VkMultisampledRenderToSingleSampledInfoEXT for this subpass

  bool legacy_dithering_enabled

    True if legacy dithering is enabled for this subpass.

struct vk_subpass_attachment
  uint32_t attachment

    VkAttachmentReference2::attachment

  VkImageAspectFlags aspects

    Aspects referenced by this attachment

    For an input attachment, this is VkAttachmentReference2::aspectMask. For all others, it’s equal to the vk_render_pass_attachment::aspects.

  VkImageUsageFlagBits usage

    Usage for this attachment

    This is a single VK_IMAGE_USAGE_* describing the usage of this subpass attachment. Resolve attachments are VK_IMAGE_USAGE_TRANSFER_DST_BIT.

  VkImageLayout layout

    VkAttachmentReference2::layout

  VkImageLayout stencil_layout

    VkAttachmentReferenceStencilLayout::stencilLayout

    If VK_KHR_separate_depth_stencil_layouts is not used, this will be layout if the attachment contains stencil and VK_IMAGE_LAYOUT_UNDEFINED otherwise.

  uint32_t first_subpass

    A per-view mask for if this is the first or last use of this attachment

    If the same render pass attachment is used multiple ways within a subpass, corresponding first/last_subpass bits will be set in all of them. For the non-multiview case, only the first bit is used.

  struct vk_subpass_attachment *resolve

    Resolve attachment, if any

struct vk_subpass_dependency
  VkDependencyFlags flags

    VkSubpassDependency2::dependencyFlags

  uint32_t src_subpass

    VkSubpassDependency2::srcSubpass

  uint32_t dst_subpass

    VkSubpassDependency2::dstSubpass

  VkPipelineStageFlags2 src_stage_mask

    VkSubpassDependency2::srcStageMask

  VkPipelineStageFlags2 dst_stage_mask

    VkSubpassDependency2::dstStageMask

  VkAccessFlags2 src_access_mask

    VkSubpassDependency2::srcAccessMask

  VkAccessFlags2 dst_access_mask

    VkSubpassDependency2::dstAccessMask

  int32_t view_offset

    VkSubpassDependency2::viewOffset