To create a render pass, call:
VkResult vkCreateRenderPass( VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
device
is the logical device that creates the render pass.
pCreateInfo
is a pointer to an instance of the
VkRenderPassCreateInfo
structure that describes the parameters of
the render pass.
pAllocator
controls host memory allocation as described in the
Memory Allocation chapter.
pRenderPass
points to a VkRenderPass
handle in which the
resulting render pass object is returned.
The VkRenderPassCreateInfo
structure is defined as:
typedef struct VkRenderPassCreateInfo { VkStructureType sType; const void* pNext; VkRenderPassCreateFlags flags; uint32_t attachmentCount; const VkAttachmentDescription* pAttachments; uint32_t subpassCount; const VkSubpassDescription* pSubpasses; uint32_t dependencyCount; const VkSubpassDependency* pDependencies; } VkRenderPassCreateInfo;
sType
is the type of this structure.
pNext
is NULL
or a pointer to an extension-specific structure.
flags
is reserved for future use.
attachmentCount
is the number of attachments used by this
render pass, or zero indicating no attachments. Attachments are referred
to by zero-based indices in the range [0,attachmentCount
).
pAttachments
points to an array of attachmentCount
number of
VkAttachmentDescription
structures describing properties of the
attachments, or NULL
if attachmentCount
is zero.
subpassCount
is the number of subpasses to create for this render
pass. Subpasses are referred to by zero-based indices in the range
[0,subpassCount
). A render pass must have at least one subpass.
pSubpasses
points to an array of subpassCount
number of
VkSubpassDescription
structures describing properties of the
subpasses.
dependencyCount
is the number of dependencies between pairs of
subpasses, or zero indicating no dependencies.
pDependencies
points to an array of dependencyCount
number
of VkSubpassDependency
structures describing dependencies
between pairs of subpasses, or NULL
if dependencyCount
is zero.
The VkAttachmentDescription
structure is defined as:
typedef struct VkAttachmentDescription { VkAttachmentDescriptionFlags flags; VkFormat format; VkSampleCountFlagBits samples; VkAttachmentLoadOp loadOp; VkAttachmentStoreOp storeOp; VkAttachmentLoadOp stencilLoadOp; VkAttachmentStoreOp stencilStoreOp; VkImageLayout initialLayout; VkImageLayout finalLayout; } VkAttachmentDescription;
flags
is a bitmask describing additional properties of the
attachment. Bits which can be set include:
typedef enum VkAttachmentDescriptionFlagBits { VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, } VkAttachmentDescriptionFlagBits;
format
is a VkFormat
value specifying the format of the
image that will be used for the attachment.
samples
is the number of samples of the image as defined
in VkSampleCountFlagBits
.
loadOp
specifies how the contents of color and depth components of
the attachment are treated at the beginning of the subpass where it is
first used:
typedef enum VkAttachmentLoadOp { VK_ATTACHMENT_LOAD_OP_LOAD = 0, VK_ATTACHMENT_LOAD_OP_CLEAR = 1, VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, } VkAttachmentLoadOp;
VK_ATTACHMENT_LOAD_OP_LOAD
means the contents within the render
area will be preserved.
VK_ATTACHMENT_LOAD_OP_CLEAR
means the contents within the render
area will be cleared to a uniform value, which is specified when a render
pass instance is begun.
VK_ATTACHMENT_LOAD_OP_DONT_CARE
means the contents within the area
need not be preserved; the contents of the attachment will be undefined
inside the render area.
storeOp
specifies how the contents of color and depth components
of the attachment are treated at the end of the subpass where it is last
used:
typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, } VkAttachmentStoreOp;
VK_ATTACHMENT_STORE_OP_STORE
means the contents within the render
area are written to memory and will be available for reading after the
render pass instance completes once the writes have been synchronized
with VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
(for color attachments)
or VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
(for depth/stencil
attachments).
VK_ATTACHMENT_STORE_OP_DONT_CARE
means the contents within the
render area are not needed after rendering, and may be discarded; the
contents of the attachment will be undefined inside the render area.
stencilLoadOp
specifies how the contents of stencil components of
the attachment are treated at the beginning of the subpass where it
is first used, and must be one of the same values allowed for
loadOp
above.
stencilStoreOp
specifies how the contents of stencil components of
the attachment are treated at the end of the last subpass where it
is used, and must be one of the same values allowed for storeOp
above.
initialLayout
is the layout the attachment image subresource will
be in when a render pass instance begins.
finalLayout
is the layout the attachment image subresource will be
transitioned to when a render pass instance ends. During a render pass
instance, an attachment can use a different layout in each subpass, if
desired.
If the attachment uses a color format, then loadOp
and storeOp
are used, and stencilLoadOp
and stencilStoreOp
are ignored. If
the format has depth and/or stencil components, loadOp
and
storeOp
apply only to the depth data, while stencilLoadOp
and
stencilStoreOp
define how the stencil data is handled.
During a render pass instance, input/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 stored or resolved at the end of a render pass
instance via storeOp
. Conversions occur as described in
Numeric Representation and Computation and
Fixed-Point Data Conversions.
If flags
includes VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
, then
the attachment is treated as if it shares physical memory with another
attachment in the same render pass. This information limits the ability of
the implementation to reorder certain operations (like layout transitions
and the loadOp
) such that it is not improperly reordered against
other uses of the same physical memory via a different attachment. This is
described in more detail below.
![]() | editing-note |
---|---|
TODO (Jon) - the following text may need to be moved back to combine with
|
If a render pass uses multiple attachments that alias the same device
memory, those attachments must each include the
VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
bit in their attachment
description flags. Attachments aliasing the same memory occurs in
multiple ways:
Render passes must include subpass dependencies (either directly or via
a subpass dependency chain) between any two subpasses that operate on the
same attachment or aliasing attachments and those subpass dependencies must
include execution and memory dependencies separating uses of the aliases, if
at least one of those subpasses writes to one of the aliases. Those
dependencies must not include the VK_DEPENDENCY_BY_REGION_BIT
if the
aliases are views of distinct image subresources which overlap in memory.
Multiple attachments that alias the same memory must not be used in a single subpass. A given attachment index must not be used multiple times in a single subpass, with one exception: two subpass attachments can use the same attachment index if at least one use is as an input attachment and neither use is as a resolve or preserve attachment. In other words, the same view can be used simultaneously as an input and color or depth/stencil attachment, but must not be used as multiple color or depth/stencil attachments nor as resolve or preserve attachments. This valid scenario is described in more detail below.
If a set of attachments alias each other, then all except the first to be
used in the render pass must use an initialLayout
of
VK_IMAGE_LAYOUT_UNDEFINED
, since the earlier uses of the other aliases
make their contents undefined. Once an alias has been used and a different
alias has been used after it, the first alias must not be used in any later
subpasses. However, an application can assign the same image view to
multiple aliasing attachment indices, which allows that image view to be
used multiple times even if other aliases are used in between. Once an
attachment needs the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
bit,
there should be no additional cost of introducing additional aliases, and
using these additional aliases may allow more efficient clearing of the
attachments on multiple uses via VK_ATTACHMENT_LOAD_OP_CLEAR
.
![]() | Note |
---|---|
The exact set of attachment indices that alias with each other is not known until a framebuffer is created using the render pass, so the above conditions cannot be validated at render pass creation time. |
The VkSubpassDescription
structure is defined as:
typedef struct VkSubpassDescription { VkSubpassDescriptionFlags flags; VkPipelineBindPoint pipelineBindPoint; uint32_t inputAttachmentCount; const VkAttachmentReference* pInputAttachments; uint32_t colorAttachmentCount; const VkAttachmentReference* pColorAttachments; const VkAttachmentReference* pResolveAttachments; const VkAttachmentReference* pDepthStencilAttachment; uint32_t preserveAttachmentCount; const uint32_t* pPreserveAttachments; } VkSubpassDescription;
flags
is reserved for future use.
pipelineBindPoint
is a VkPipelineBindPoint
value specifying
whether this is a compute or graphics subpass. Currently, only graphics
subpasses are supported.
inputAttachmentCount
is the number of input attachments.
pInputAttachments
is an array of VkAttachmentReference
structures (defined below) that lists which of the render pass’s
attachments can be read in the shader during the subpass, and what
layout each attachment will be in during the subpass. Each element
of the array corresponds to an input attachment unit number in the
shader, i.e. if the shader declares an input variable
layout(input_attachment_index=X, set=Y, binding=Z)
then it uses the
attachment provided in pInputAttachments
[X]. Input attachments
must also be bound to the pipeline with a descriptor set, with the
input attachment descriptor written in the location (set=Y, binding=Z).
colorAttachmentCount
is the number of color attachments.
pColorAttachments
is an array of colorAttachmentCount
VkAttachmentReference
structures that lists which of the render
pass’s attachments will be used as color attachments in the subpass, and
what layout each attachment will be in during the subpass. Each
element of the array corresponds to a fragment shader output location,
i.e. if the shader declared an output variable layout(location=X)
then
it uses the attachment provided in pColorAttachments
[X].
pResolveAttachments
is NULL
or an array of colorAttachmentCount
VkAttachmentReference
structures that lists which of the render pass’s
attachments are resolved to at the end of the subpass, and what layout
each attachment will be in during the resolve. If pResolveAttachments
is
not NULL
, each of its elements corresponds to a color attachment (the
element in pColorAttachments
at the same index). At the end of
each subpass, the subpass’s color attachments are resolved to
corresponding resolve attachments, unless the resolve attachment index
is VK_ATTACHMENT_UNUSED
or pResolveAttachments
is NULL
. If
the first use of an attachment in a render pass is as a resolve
attachment, then the loadOp
is effectively ignored as the resolve
is guaranteed to overwrite all pixels in the render area.
pDepthStencilAttachment
is a pointer to a
VkAttachmentReference
specifying which attachment will be used for
depth/stencil data and the layout it will be in during the subpass.
Setting the attachment index to VK_ATTACHMENT_UNUSED
or leaving
this pointer as NULL
indicates that no depth/stencil attachment will
be used in the subpass.
preserveAttachmentCount
is the number of preserved attachments.
pPreserveAttachments
is an array of preserveAttachmentCount
render pass attachment indices describing the attachments that
are not used by a subpass, but whose contents must be preserved
throughout the subpass.
The contents of an attachment within the render area become undefined at the start of a subpass S if all of the following conditions are true:
Once the contents of an attachment become undefined in subpass S, they remain undefined for subpasses in subpass dependency chains starting with subpass S until they are written again. However, they remain valid for subpasses in other subpass dependency chains starting with subpass S1 if those subpasses use or preserve the attachment.
The VkAttachmentReference
structure is defined as:
typedef struct VkAttachmentReference { uint32_t attachment; VkImageLayout layout; } VkAttachmentReference;
attachment
is the index of the attachment of the render pass, and
corresponds to the index of the corresponding element in the
pAttachments
array of the VkRenderPassCreateInfo
structure.
If any color or depth/stencil attachments are
VK_ATTACHMENT_UNUSED
, then no writes occur for those attachments.
layout
is a VkImageLayout
value specifying the layout the
attachment uses during the subpass. The implementation will
automatically perform layout transitions as needed between subpasses to
make each subpass use the requested layouts.
The VkSubpassDependency
structure is defined as:
typedef struct VkSubpassDependency { uint32_t srcSubpass; uint32_t dstSubpass; VkPipelineStageFlags srcStageMask; VkPipelineStageFlags dstStageMask; VkAccessFlags srcAccessMask; VkAccessFlags dstAccessMask; VkDependencyFlags dependencyFlags; } VkSubpassDependency;
srcSubpass
and dstSubpass
are the subpass indices of the
producer and consumer subpasses, respectively. srcSubpass
and
dstSubpass
can also have the special value
VK_SUBPASS_EXTERNAL
. The source subpass must always be a lower
numbered subpass than the destination subpass (excluding external
subpasses and
self-dependencies), so that the order of subpass descriptions is a
valid execution ordering, avoiding cycles in the dependency graph.
srcStageMask
, dstStageMask
, srcAccessMask
,
dstAccessMask
, and dependencyFlags
describe an
execution and memory dependency between subpasses. The bits that can be included in
dependencyFlags
are:
typedef enum VkDependencyFlagBits { VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, } VkDependencyFlagBits;
dependencyFlags
contains VK_DEPENDENCY_BY_REGION_BIT
,
then the dependency is by-region as defined in
Execution And Memory Dependencies.
Each subpass dependency defines an execution and memory dependency
between two sets of commands, with the second set depending on the first
set. When srcSubpass
does not equal dstSubpass
then the first
set of commands is:
srcSubpass
, if
srcSubpass
is not VK_SUBPASS_EXTERNAL
.
srcSubpass
is
VK_SUBPASS_EXTERNAL
.
While the corresponding second set of commands is:
dstSubpass
, if
dstSubpass
is not VK_SUBPASS_EXTERNAL
.
dstSubpass
is
VK_SUBPASS_EXTERNAL
.
When srcSubpass
equals dstSubpass
then the first set consists of
commands in the subpass before a call to vkCmdPipelineBarrier
and the
second set consists of commands in the subpass following that same call as
described in the
Subpass Self-dependency section.
The srcStageMask
, dstStageMask
, srcAccessMask
,
dstAccessMask
, and dependencyFlags
parameters of the dependency
are interpreted the same way as for other dependencies, as described in
Synchronization and Cache Control.
Automatic image layout transitions between subpasses also interact with the
subpass dependencies. If two subpasses are connected by a dependency and
those two subpasses use the same attachment in a different layout, then the
layout transition will occur after the memory accesses via
srcAccessMask
have completed in all pipeline stages included in
srcStageMask
in the source subpass, and before any memory accesses
via dstAccessMask
occur in any pipeline stages included in
dstStageMask
in the destination subpass.
The automatic image layout transitions from initialLayout
to the first
used layout (if it is different) are performed according to the following
rules:
VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
bit and there is no
subpass dependency from VK_SUBPASS_EXTERNAL
to the first subpass
that uses the attachment, then it is as if there were such a dependency
with srcStageMask
= srcAccessMask
= 0 and dstStageMask
and dstAccessMask
including all relevant bits (all graphics
pipeline stages and all access types that use image resources), with the
transition executing as part of that dependency. In other words, it may
overlap work before the render pass instance and is complete before the
subpass begins.
VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
bit and there is a subpass
dependency from VK_SUBPASS_EXTERNAL
to the first subpass that uses
the attachment, then the transition executes as part of that dependency
and according to its stage and access masks. It must not overlap work
that came before the render pass instance that is included in the source
masks, but it may overlap work in previous subpasses.
VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
bit, then the transition
executes according to all the subpass dependencies with dstSubpass
equal to the first subpass index that the attachment is used in. That
is, it occurs after all memory accesses in the source stages and masks
from all the source subpasses have completed and are available, and
before the union of all the destination stages begin, and the new layout
is visible to the union of all the destination access types. If there
are no incoming subpass dependencies, then this case follows the first
rule.
Similar rules apply for the transition to the finalLayout
, using
dependencies with dstSubpass
equal to VK_SUBPASS_EXTERNAL
If an attachment specifies the VK_ATTACHMENT_LOAD_OP_CLEAR
load
operation, then it will logically be cleared at the start of the first
subpass where it is used.
![]() | Note |
---|---|
Implementations may move clears earlier as long as it does not affect the
operation of a render pass instance. For example, an implementation may
choose to clear all attachments at the start of the render pass instance. If
an attachment has the |
The first use of an attachment must not specify a layout equal to
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
or
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
if the attachment specifies
that the loadOp
is VK_ATTACHMENT_LOAD_OP_CLEAR
. If a subpass
uses the same attachment as both an input attachment and either a color
attachment or a depth/stencil attachment, then both uses must observe the
result of the clear.
Similarly, if an attachment specifies that the storeOp
is
VK_ATTACHMENT_STORE_OP_STORE
, then it will logically be stored at the
end of the last subpass where it is used.
![]() | Note |
---|---|
Implementations may move stores
later as long as it does not affect the operation of a render pass instance.
If an attachment has the |
If an attachment is not used by any subpass, then the loadOp
and the
storeOp
are ignored and the attachment’s memory contents will not be
modified by execution of a render pass instance.
It will be common for a render pass to consist of a simple linear graph of dependencies, where subpass N depends on subpass N-1 for all N, and the operation of the memory barriers and layout transitions is fairly straightforward to reason about for those simple cases. But for more complex graphs, there are some rules that govern when there must be dependencies between subpasses.
As stated earlier, render passes must include subpass dependencies which (either directly or via a subpass dependency chain) separate any two subpasses that operate on the same attachment or aliasing attachments, if at least one of those subpasses writes to the attachment. If an image layout changes between those two subpasses, the implementation uses the stageMasks and accessMasks indicated by the subpass dependency as the masks that control when the layout transition must occur. If there is not a layout change on the attachment, or if an implementation treats the two layouts identically, then it may treat the dependency as a simple execution/memory barrier.
If two subpasses use the same attachment in different layouts but both uses are read-only (i.e. input attachment, or read-only depth/stencil attachment), the application does not need to express a dependency between the two subpasses. Implementations that treat the two layouts differently may deduce and insert a dependency between the subpasses, with the implementation choosing the appropriate stage masks and access masks based on whether the attachment is used as an input or depth/stencil attachment, and may insert the appropriate layout transition along with the execution/memory barrier. Implementations that treat the two layouts identically need not insert a barrier, and the two subpasses may execute simultaneously. The stage masks and access masks are chosen as follows:
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
, access mask =
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
.
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
, access mask =
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
where srcStageMask
and srcAccessMask
are taken based on usage in
the source subpass and dstStageMask
and dstAccessMask
are taken
based on usage in the destination subpass.
If a subpass uses the same attachment as both an input attachment and either
a color attachment or a depth/stencil attachment, reads from the input
attachment are not automatically coherent with writes through the color or
depth/stencil attachment. In order to achieve well-defined results, one of
two criteria must be satisfied. First, if the color components or
depth/stencil components read by the input attachment are mutually exclusive
with the components written by the color or depth/stencil
attachment then there is no feedback loop and the reads and writes both
function normally, with the reads observing values from the previous
subpass(es) or from memory. This option requires the graphics pipelines
used by the subpass to disable writes to color components that are read as
inputs via the colorWriteMask
, and to disable writes to depth/stencil
components that are read as inputs via depthWriteEnable
or
stencilTestEnable
.
Second, if the input attachment reads components that are written by the color or depth/stencil attachment, then there is a feedback loop and a pipeline barrier must be used between when the attachment is written and when it is subsequently read by later fragments. This pipeline barrier must follow the rules of a self-dependency as described in Subpass Self-dependency, where the barrier’s flags include:
dstStageMask
= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
,
dstAccessMask
= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
, and
srcAccessMask
= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
(for
color attachments) or srcAccessMask
=
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
(for depth/stencil
attachments).
srcStageMask
= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
(for color attachments) or srcStageMask
=
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
(for depth/stencil
attachments).
dependencyFlags
= VK_DEPENDENCY_BY_REGION_BIT
.
A pipeline barrier is needed each time a fragment will read a particular (x,y,layer,sample) location if that location has been written since the most recent pipeline barrier, or since the start of the subpass if there have been no pipeline barriers since the start of the subpass.
An attachment used as both an input attachment and color attachment must be
in the VK_IMAGE_LAYOUT_GENERAL
layout. An attachment used as both an
input attachment and depth/stencil attachment must be in either the
VK_IMAGE_LAYOUT_GENERAL
or
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
layout. Since an
attachment in the VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
layout is read-only, this situation is not a feedback loop.
To destroy a render pass, call:
void vkDestroyRenderPass( VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator);
device
is the logical device that destroys the render pass.
renderPass
is the handle of the render pass to destroy.
pAllocator
controls host memory allocation as described in the
Memory Allocation chapter.