Render Pass

Draw commands must be recorded within a render pass instance. Each render pass instance defines a set of image resources, referred to as attachments, used during rendering.

vkCmdBeginRenderingBegin a dynamic render pass instance
VkRenderingInfoStructure specifying render pass instance begin info
VkRenderingFlagBitsBitmask specifying additional properties of a dynamic render pass instance
VkRenderingFlagsBitmask of VkRenderingFlagBits
VkRenderingAttachmentInfoStructure specifying attachment information
VkRenderingFragmentShadingRateAttachmentInfoKHRStructure specifying fragment shading rate attachment information
VkRenderingFragmentDensityMapAttachmentInfoEXTStructure specifying fragment shading rate attachment information
vkGetRenderingAreaGranularityKHRReturns the granularity for dynamic rendering optimal render area
VkRenderingAreaInfoKHRStructure describing rendering area granularity query info
VkRenderPassStripeBeginInfoARMStructure specifying striped rendering information
VkRenderPassStripeInfoARMStructure specifying per rendering stripe information
vkCmdEndRenderingEnd a dynamic render pass instance

For more complex rendering graphs, it is possible to pre-define a static render pass object, which as well as allowing draw commands, allows the definition of framebuffer-local dependencies between multiple subpasses. These objects have a lot of setup cost compared to vkCmdBeginRendering, but use of subpass dependencies can confer important performance benefits on some devices.

VkTilePropertiesQCOMStructure holding available tile properties
vkGetDynamicRenderingTilePropertiesQCOMGet the properties when using dynamic rendering

Render Pass Objects

VkRenderPassOpaque handle to a render pass object

An attachment description describes the properties of an attachment including its format, sample count, and how its contents are treated at the beginning and end of each render pass instance.

A subpass represents a phase of rendering that reads and writes a subset of the attachments in a render pass. Rendering commands are recorded into a particular subpass of a render pass instance.

A subpass description describes the subset of attachments that is involved in the execution of a subpass. Each subpass can read from some attachments as input attachments, write to some as color attachments or depth/stencil attachments, perform shader resolve operations to color_attachments or depth/stencil_attachments, and perform multisample resolve operations to resolve attachments. A subpass description can also include a set of preserve attachments, which are attachments that are not read or written by the subpass but whose contents must be preserved throughout the subpass.

A subpass uses an attachment if the attachment is a color, depth/stencil, resolve, depth/stencil resolve, fragment shading rate, or input attachment for that subpass (as determined by the pColorAttachments, pDepthStencilAttachment, pResolveAttachments, VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment, VkFragmentShadingRateAttachmentInfoKHR::pFragmentShadingRateAttachment→attachment, and pInputAttachments members of VkSubpassDescription, respectively). A subpass does not use an attachment if that attachment is preserved by the subpass. The first use of an attachment is in the lowest numbered subpass that uses that attachment. Similarly, the last use of an attachment is in the highest numbered subpass that uses that attachment.

The subpasses in a render pass all render to the same dimensions, and fragments for pixel (x,y,layer) in one subpass can only read attachment contents written by previous subpasses at that same (x,y,layer) location. For multi-pixel fragments, the pixel read from an input attachment is selected from the pixels covered by that fragment in an implementation-dependent manner. However, this selection must be made consistently for any fragment with the same shading rate for the lifetime of the VkDevice.

By describing a complete set of subpasses in advance, render passes provide the implementation an opportunity to optimize the storage and transfer of attachment data between subpasses.

In practice, this means that subpasses with a simple framebuffer-space dependency may be merged into a single tiled rendering pass, keeping the attachment data on-chip for the duration of a render pass instance. However, it is also quite common for a render pass to only contain a single subpass.

Subpass dependencies describe execution and memory dependencies between subpasses.

A subpass dependency chain is a sequence of subpass dependencies in a render pass, where the source subpass of each subpass dependency (after the first) equals the destination subpass of the previous dependency.

Execution of subpasses may overlap or execute out of order with regards to other subpasses, unless otherwise enforced by an execution dependency. Each subpass only respects submission order for commands recorded in the same subpass, and the vkCmdBeginRenderPass and vkCmdEndRenderPass commands that delimit the render pass - commands within other subpasses are not included. This affects most other implicit ordering guarantees.

A render pass describes the structure of subpasses and attachments independent of any specific image views for the attachments. The specific image views that will be used for the attachments, and their dimensions, are specified in VkFramebuffer objects. Framebuffers are created with respect to a specific render pass that the framebuffer is compatible with (see Render Pass Compatibility). Collectively, a render pass and a framebuffer define the complete render target state for one or more subpasses as well as the algorithmic dependencies between the subpasses.

The various pipeline stages of the drawing commands for a given subpass may execute concurrently and/or out of order, both within and across drawing commands, whilst still respecting pipeline order. However for a given (x,y,layer,sample) sample location, certain per-sample operations are performed in rasterization order.

VK_ATTACHMENT_UNUSEDUnused attachment sentinel

Render Pass Creation

vkCreateRenderPassCreate a new render pass object
VkRenderPassCreateInfoStructure specifying parameters of a newly created render pass
VkRenderPassCreateFlagBitsBitmask specifying additional properties of a render pass
VkRenderPassCreateFlagsBitmask of VkRenderPassCreateFlagBits
VkRenderPassMultiviewCreateInfoStructure containing multiview information for all subpasses
VkMultiviewPerViewAttributesInfoNVXStructure specifying the multiview per-attribute properties
VkRenderPassFragmentDensityMapCreateInfoEXTStructure containing fragment density map attachment for render pass
VkAttachmentDescriptionStructure specifying an attachment description
VkAttachmentDescriptionFlagBitsBitmask specifying additional properties of an attachment
VkAttachmentDescriptionFlagsBitmask of VkAttachmentDescriptionFlagBits
VkRenderPassInputAttachmentAspectCreateInfoStructure specifying, for a given subpass/input attachment pair, which aspect can be read.
VkInputAttachmentAspectReferenceStructure specifying a subpass/input attachment pair and an aspect mask that can be read.
VkSubpassDescriptionStructure specifying a subpass description
VkSubpassDescriptionFlagBitsBitmask specifying usage of a subpass
VkSubpassDescriptionFlagsBitmask of VkSubpassDescriptionFlagBits
VkAttachmentReferenceStructure specifying an attachment reference
VK_SUBPASS_EXTERNALSubpass index sentinel expanding synchronization scope outside a subpass
VkSubpassDependencyStructure specifying a subpass dependency

When multiview is enabled, the execution of the multiple views of one subpass may not occur simultaneously or even back-to-back, and rather may be interleaved with the execution of other subpasses. The load and store operations apply to attachments on a per-view basis. For example, an attachment using VK_ATTACHMENT_LOAD_OP_CLEAR will have each view cleared on first use, but the first use of one view may be temporally distant from the first use of another view.

A good mental model for multiview is to think of a multiview subpass as if it were a collection of individual (per-view) subpasses that are logically grouped together and described as a single multiview subpass in the API. Similarly, a multiview attachment can be thought of like several individual attachments that happen to be layers in a single image. A view-local dependency between two multiview subpasses acts like a set of one-to-one dependencies between corresponding pairs of per-view subpasses. A view-global dependency between two multiview subpasses acts like a set of N × M dependencies between all pairs of per-view subpasses in the source and destination. Thus, it is a more compact representation which also makes clear the commonality and reuse that is present between views in a subpass. This interpretation motivates the answers to questions like when does the load op apply - it is on the first use of each view of an attachment, as if each view was a separate attachment.

The content of each view follows the description in attachment content behavior. In particular, if an attachment is preserved, all views within the attachment are preserved.

If any two subpasses of a render pass activate transform feedback to the same bound transform feedback buffers, a subpass dependency must be included (either directly or via some intermediate subpasses) between them.

If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the first subpass that uses an attachment, then an implicit subpass dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is used in. The implicit subpass dependency only exists if there exists an automatic layout transition away from initialLayout. The subpass dependency operates as if defined with the following parameters:

Similarly, if there is no subpass dependency from the last subpass that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit subpass dependency exists from the last subpass it is used in to VK_SUBPASS_EXTERNAL. The implicit subpass dependency only exists if there exists an automatic layout transition into finalLayout. The subpass dependency operates as if defined with the following parameters:

As subpasses may overlap or execute out of order with regards to other subpasses unless a subpass dependency chain describes otherwise, the layout transitions required between subpasses cannot be known to an application. Instead, an application provides the layout that each attachment must be in at the start and end of a render pass, and the layout it must be in during each subpass it is used in. The implementation then must execute layout transitions between subpasses in order to guarantee that the images are in the layouts required by each subpass, and in the final layout at the end of the render pass.

Automatic layout transitions apply to the entire image subresource attached to the framebuffer. If multiview is not enabled and the attachment is a view of a 1D or 2D image, the automatic layout transitions apply to the number of layers specified by VkFramebufferCreateInfo::layers. If multiview is enabled and the attachment is a view of a 1D or 2D image, the automatic layout transitions apply to the layers corresponding to views which are used by some subpass in the render pass, even if that subpass does not reference the given attachment. If the attachment view is a 2D or 2D array view of a 3D image, even if the attachment view only refers to a subset of the slices of the selected mip level of the 3D image, automatic layout transitions apply to the entire subresource referenced which is the entire mip level in this case.

Automatic layout transitions away from the layout used in a subpass happen-after the availability operations for all dependencies with that subpass as the srcSubpass.

Automatic layout transitions into the layout used in a subpass happen-before the visibility operations for all dependencies with that subpass as the dstSubpass.

Automatic layout transitions away from initialLayout happen-after the availability operations for all dependencies with a srcSubpass equal to VK_SUBPASS_EXTERNAL, where dstSubpass uses the attachment that will be transitioned. For attachments created with VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT, automatic layout transitions away from initialLayout happen-after the availability operations for all dependencies with a srcSubpass equal to VK_SUBPASS_EXTERNAL, where dstSubpass uses any aliased attachment.

Automatic layout transitions into finalLayout happen-before the visibility operations for all dependencies with a dstSubpass equal to VK_SUBPASS_EXTERNAL, where srcSubpass uses the attachment that will be transitioned. For attachments created with VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT, automatic layout transitions into finalLayout happen-before the visibility operations for all dependencies with a dstSubpass equal to VK_SUBPASS_EXTERNAL, where srcSubpass uses any aliased attachment.

The image layout of the depth aspect of a depth/stencil attachment referring to an image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT is dependent on the last sample locations used to render to the attachment, thus automatic layout transitions use the sample locations state specified in VkRenderPassSampleLocationsBeginInfoEXT.

Automatic layout transitions of an attachment referring to a depth/stencil image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT use the sample locations the image subresource range referenced by the attachment was last rendered with. If the current render pass does not use the attachment as a depth/stencil attachment in any subpass that happens-before, the automatic layout transition uses the sample locations state specified in the sampleLocationsInfo member of the element of the VkRenderPassSampleLocationsBeginInfoEXT::pAttachmentInitialSampleLocations array for which the attachmentIndex member equals the attachment index of the attachment, if one is specified. Otherwise, the automatic layout transition uses the sample locations state specified in the sampleLocationsInfo member of the element of the VkRenderPassSampleLocationsBeginInfoEXT::pPostSubpassSampleLocations array for which the subpassIndex member equals the index of the subpass that last used the attachment as a depth/stencil attachment, if one is specified.

If no sample locations state has been specified for an automatic layout transition performed on an attachment referring to a depth/stencil image created with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT the contents of the depth aspect of the depth/stencil attachment become undefined: as if the layout of the attachment was transitioned from the VK_IMAGE_LAYOUT_UNDEFINED layout.

If two subpasses use the same attachment, and both subpasses use the attachment in a read-only layout, no subpass dependency needs to be specified between those subpasses. If an implementation treats those layouts separately, it must insert an implicit subpass dependency between those subpasses to separate the uses in each layout. The subpass dependency operates as if defined with the following parameters:

When drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT set in VkPipelineDynamicStateCreateInfo::pDynamicStates, the application must specify which types of attachments that are written to during a render pass will also be accessed as non-attachments in the render pass.

vkCmdSetAttachmentFeedbackLoopEnableEXTSpecify whether attachment feedback loops are enabled dynamically on a command buffer

A more extensible version of render pass creation is also defined below.

vkCreateRenderPass2Create a new render pass object
VkRenderPassCreateInfo2Structure specifying parameters of a newly created render pass
VkAttachmentDescription2Structure specifying an attachment description
VkAttachmentDescriptionStencilLayoutStructure specifying an attachment description
VkSubpassDescription2Structure specifying a subpass description
VkSubpassDescriptionDepthStencilResolveStructure specifying depth/stencil resolve operations for a subpass
VkFragmentShadingRateAttachmentInfoKHRStructure specifying a fragment shading rate attachment for a subpass
VkMultisampledRenderToSingleSampledInfoEXTStructure containing info for multisampled rendering to single-sampled attachments in a subpass

If the pNext chain of VkSubpassDescription2 or VkRenderingInfo includes a VkMultisampledRenderToSingleSampledInfoEXT structure whose multisampledRenderToSingleSampledEnable field is VK_TRUE, the graphics pipelines must have VkGraphicsPipelineCreateInfo::rasterizationSamples equal to VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples, and the subpass attachments can have a sample count of VK_SAMPLE_COUNT_1_BIT. For attachments with a sample count of VK_SAMPLE_COUNT_1_BIT, multisampled rendering is performed to an intermediate multisampled image with VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples samples, implicitly allocated by the implementation for the duration of the subpass. For such attachments:

  • If loadOp equals to VK_ATTACHMENT_LOAD_OP_LOAD, samples of the implicit image are initialized by replicating the value from the corresponding pixel in the attachment.
  • If storeOp or stencilStoreOp is equal to VK_ATTACHMENT_STORE_OP_STORE, the implicit image is implicitly resolved prior to storage in the attachment.

Memory constraints due to high primitive counts may result in an implicit split of the subpass. This is the equivalent of partial rasterization of geometry in a render pass that ends in storeOp and stencilStoreOp equal to VK_ATTACHMENT_STORE_OP_STORE, followed by another render pass with loadOp and stencilLoadOp equal to VK_ATTACHMENT_LOAD_OP_LOAD with appropriate barriers in between. When VkMultisampledRenderToSingleSampledInfoEXT is used, the implementation is allowed to resolve attachments with a sample count of VK_SAMPLE_COUNT_1_BIT and lose multisampled data on such splits. The implementation may similarly split the render pass at subpass boundaries even if they use the same value for VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples.

VkAttachmentReference2Structure specifying an attachment reference
VkAttachmentReferenceStencilLayoutStructure specifying an attachment description
VkSubpassDependency2Structure specifying a subpass dependency
vkDestroyRenderPassDestroy a render pass object

Render Pass Compatibility

Framebuffers and graphics pipelines are created based on a specific render pass object. They must only be used with that render pass object, or one compatible with it.

Two attachment references are compatible if they have matching format and sample count, or are both VK_ATTACHMENT_UNUSED or the pointer that would contain the reference is NULL.

Two arrays of attachment references are compatible if all corresponding pairs of attachments are compatible. If the arrays are of different lengths, attachment references not present in the smaller array are treated as VK_ATTACHMENT_UNUSED.

Two render passes are compatible if their corresponding color, input, resolve, and depth/stencil attachment references are compatible and if they are otherwise identical except for:

  • Initial and final image layout in attachment descriptions
  • Load and store operations in attachment descriptions
  • Image layout in attachment references

As an additional special case, if two render passes have a single subpass, the resolve attachment reference and depth/stencil resolve mode compatibility requirements are ignored.

A framebuffer is compatible with a render pass if it was created using the same render pass or a compatible render pass.

Framebuffers

VkFramebufferOpaque handle to a framebuffer object
vkCreateFramebufferCreate a new framebuffer object
VkFramebufferCreateInfoStructure specifying parameters of a newly created framebuffer
VkFramebufferAttachmentsCreateInfoStructure specifying parameters of images that will be used with a framebuffer
VkFramebufferAttachmentImageInfoStructure specifying parameters of an image that will be used with a framebuffer
VkFramebufferCreateFlagBitsBitmask specifying framebuffer properties
VkFramebufferCreateFlagsBitmask of VkFramebufferCreateFlagBits
vkDestroyFramebufferDestroy a framebuffer object

Render Pass Load Operations

Render pass load operations define the initial values of an attachment during a render pass instance.

Load operations for attachments with a depth/stencil format execute in the VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT pipeline stage. Load operations for attachments with a color format execute in the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage. The load operation for each sample in an attachment happens-before any recorded command which accesses the sample in that render pass instance via that attachment or an alias.

Because load operations always happen first, external synchronization with attachment access only needs to synchronize the load operations with previous commands; not the operations within the render pass instance. This does not apply when using VK_ATTACHMENT_LOAD_OP_NONE_KHR.

Load operations only update values within the defined render area for the render pass instance. However, any writes performed by a load operation (as defined by its access masks) to a given attachment may read and write back any memory locations within the image subresource bound for that attachment. For depth/stencil images, writes to one aspect may also result in read-modify-write operations for the other aspect. If the subresource is in the VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT layout, implementations must not access pixels outside of the render area.

As entire subresources could be accessed by load operations, applications cannot safely access values outside of the render area during a render pass instance when a load operation that modifies values is used.

VkAttachmentLoadOpSpecify how contents of an attachment are initialized at the beginning of a subpass

During a render pass instance, input and color attachments with color formats that have a component size of 8, 16, or 32 bits must be represented in the attachment’s format throughout the instance. Attachments with other floating- or fixed-point color formats, or with depth components may be represented in a format with a precision higher than the attachment format, but must be represented with the same range. When such a component is loaded via the loadOp, it will be converted into an implementation-dependent format used by the render pass. Such components must be converted from the render pass format, to the format of the attachment, before they are resolved or stored at the end of a render pass instance via storeOp. Conversions occur as described in Numeric Representation and Computation and Fixed-Point Data Conversions.

Render Pass Store Operations

Render pass store operations define how values written to an attachment during a render pass instance are stored to memory.

Store operations for attachments with a depth/stencil format execute in the VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT pipeline stage. Store operations for attachments with a color format execute in the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage. The store operation for each sample in an attachment happens-after any recorded command which accesses the sample via that attachment or an alias.

Because store operations always happen after other accesses in a render pass instance, external synchronization with attachment access in an earlier render pass only needs to synchronize with the store operations; not the operations within the render pass instance. This does not apply when using VK_ATTACHMENT_STORE_OP_NONE.

Store operations only update values within the defined render area for the render pass instance. However, any writes performed by a store operation (as defined by its access masks) to a given attachment may read and write back any memory locations within the image subresource bound for that attachment. For depth/stencil images writes to one aspect may also result in read-modify-write operations for the other aspect. If the subresource is in the VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT layout, implementations must not access pixels outside of the render area.

As entire subresources could be accessed by store operations, applications cannot safely access values outside of the render area via aliased resources during a render pass instance when a store operation that modifies values is used.

VkAttachmentStoreOpSpecify how contents of an attachment are stored to memory at the end of a subpass

Render Pass Multisample Resolve Operations

Render pass multisample resolve operations combine sample values from a single pixel in a multisample attachment and store the result to the corresponding pixel in a single sample attachment.

Multisample resolve operations for attachments execute in the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage. A final resolve operation for all pixels in the render area happens-after any recorded command which writes a pixel via the multisample attachment to be resolved or an explicit alias of it in the subpass that it is specified. Any single sample attachment specified for use in a multisample resolve operation may have its contents modified at any point once rendering begins for the render pass instance. Reads from the multisample attachment can be synchronized with VK_ACCESS_COLOR_ATTACHMENT_READ_BIT. Access to the single sample attachment can be synchronized with VK_ACCESS_COLOR_ATTACHMENT_READ_BIT and VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT. These pipeline stage and access types are used whether the attachments are color or depth/stencil attachments.

When using render pass objects, a subpass dependency specified with the above pipeline stages and access flags will ensure synchronization with multisample resolve operations for any attachments that were last accessed by that subpass. This allows later subpasses to read resolved values as input attachments.

Resolve operations only update values within the defined render area for the render pass instance. However, any writes performed by a resolve operation (as defined by its access masks) to a given attachment may read and write back any memory locations within the image subresource bound for that attachment. For depth/stencil images writes to one aspect may also result in read-modify-write operations for the other aspect. If the subresource is in the VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT layout, implementations must not access pixels outside of the render area.

As entire subresources could be accessed by multisample resolve operations, applications cannot safely access values outside of the render area via aliased resources during a render pass instance when a multisample resolve operation is performed.

VkResolveModeFlagBitsBitmask indicating supported depth and stencil resolve modes
VkResolveModeFlagsBitmask of VkResolveModeFlagBits

Render Pass Commands

An application records the commands for a render pass instance one subpass at a time, by beginning a render pass instance, iterating over the subpasses to record commands for that subpass, and then ending the render pass instance.

vkCmdBeginRenderPassBegin a new render pass
vkCmdBeginRenderPass2Begin a new render pass
VkRenderPassBeginInfoStructure specifying render pass begin information
VkRenderPassSampleLocationsBeginInfoEXTStructure specifying sample locations to use for the layout transition of custom sample locations compatible depth/stencil attachments
VkAttachmentSampleLocationsEXTStructure specifying the sample locations state to use in the initial layout transition of attachments
VkSubpassSampleLocationsEXTStructure specifying the sample locations state to use for layout transitions of attachments performed after a given subpass
VkRenderPassTransformBeginInfoQCOMStructure describing transform parameters of a render pass instance
VkSubpassBeginInfoStructure specifying subpass begin information
VkSubpassContentsSpecify how commands in the first subpass of a render pass are provided
VkDeviceGroupRenderPassBeginInfoSet the initial device mask and render areas for a render pass instance
VkRenderPassAttachmentBeginInfoStructure specifying images to be used as framebuffer attachments
VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOMSet the multiview per view render areas for a render pass instance
vkGetRenderAreaGranularityReturns the granularity for optimal render area
vkCmdNextSubpassTransition to the next subpass of a render pass
vkCmdNextSubpass2Transition to the next subpass of a render pass
vkCmdEndRenderPassEnd the current render pass
vkCmdEndRenderPass2End the current render pass
VkSubpassEndInfoStructure specifying subpass end information
VkSubpassFragmentDensityMapOffsetEndInfoQCOMStructure specifying fragment density map offset subpass end information

Render Pass Creation Feedback

VkRenderPassCreationControlEXTControl about the creation of render pass or subpass
VkRenderPassCreationFeedbackCreateInfoEXTRequest feedback about the creation of render pass
VkRenderPassCreationFeedbackInfoEXTFeedback about the creation of a render pass
VkRenderPassSubpassFeedbackCreateInfoEXTRequest for feedback about the creation of subpass
VkRenderPassSubpassFeedbackInfoEXTFeedback about the creation of subpass
VkSubpassMergeStatusEXTSpecify a subpass merging status

Common Render Pass Data Races (Informative)

Due to the complexity of how rendering is performed, there are several ways an application can accidentally introduce a data race, usually by doing something that may seem benign but actually cannot be supported. This section indicates a number of the more common cases as guidelines to help avoid them.

Sampling From a Read-only Attachment

Vulkan includes read-only layouts for depth/stencil images, that allow the images to be both read during a render pass for the purposes of depth/stencil tests, and read as a non-attachment.

However, because VK_ATTACHMENT_STORE_OP_STORE and VK_ATTACHMENT_STORE_OP_DONT_CARE may perform write operations, even if no recorded command writes to an attachment, reading from an image while also using it as an attachment with these store operations can result in a data race. If the reads from the non-attachment are performed in a fragment shader where the accessed samples match those covered by the fragment shader, no data race will occur as store operations are guaranteed to operate after fragment shader execution for the set of samples the fragment covers. Notably, input attachments can also be used for this case. Reading other samples or in any other shader stage can result in unexpected behavior due to the potential for a data race, and validation errors should be generated for doing so. In practice, many applications have shipped reading samples outside of the covered fragment without any observable issue, but there is no guarantee that this will always work, and it is not advisable to rely on this in new or re-worked code bases. As VK_ATTACHMENT_STORE_OP_NONE is guaranteed to perform no writes, applications wishing to read an image as both an attachment and a non-attachment should make use of this store operation, coupled with a load operation that also performs no writes.

Non-overlapping Access Between Resources

When relying on non-overlapping accesses between attachments and other resources, it is important to note that load and store operations have fairly wide alignment requirements - potentially affecting entire subresources and adjacent depth/stencil aspects. This makes it invalid to access a non-attachment subresource that is simultaneously being used as an attachment where either access performs a write operation.

The only exception to this is if a subresource is in the VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT image layout, in which case the overlap is defined to occur at a per-pixel granularity, and applications can read data from pixels outside the render area without introducing a data race.

Depth/Stencil and Input Attachments

When rendering to only the depth OR stencil aspect of an image, an input attachment accessing the other aspect will not cause a data race only under very specific conditions. To avoid a data race, the aspect not being written must be in a read-only layout, and writes to it must be disabled in the draw state. For example, to read from stencil while writing depth, the attachment must be in VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL (or equivalent), and the stencil write mask must be set to 0. Similarly to read from depth while writing stencil, the attachment must be in VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL (or equivalent), and depth write enable must be set to VK_FALSE.

Synchronization Options

There are several synchronization options available to synchronize between accesses to resources within a render pass. Some of the options are outlined below:

  • A VkSubpassDependency in a render pass object can synchronize attachment writes and multisample resolve operations from a prior subpass for subsequent input attachment reads.
  • A vkCmdPipelineBarrier inside a subpass can synchronize prior attachment writes in the subpass with subsequent input attachment reads.
  • A vkCmdPipelineBarrier inside a subpass can synchronize prior attachment writes in the subpass with subsequent non-attachment reads if the attachment is in the VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT image layout.
  • If a subresource is used as a color and input attachment, and the pipeline performing the read was created with VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT
  • If a subresource is used as a depth and input attachment, and the pipeline performing the read was created with VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
  • If a subresource is used as a stencil and input attachment, and the pipeline performing the read was created with VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
  • If a subresource is used as two separate non-attachment resources, writes to a pixel or individual sample in a fragment shader can be synchronized with access to the same pixel or sample in another fragment shader by using one of the fragment interlock execution modes.