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 previous contents of the
image within the render area will be preserved.
For attachments with a depth/stencil format, this uses the access type
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
.
For attachments with a color format, this uses the access type
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
.
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.
For attachments with a depth/stencil format, this uses the access type
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
.
For attachments with a color format, this uses the access type
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
.
VK_ATTACHMENT_LOAD_OP_DONT_CARE
means the previous contents
within the area need not be preserved; the contents of the attachment
will be undefined inside the render area.
For attachments with a depth/stencil format, this uses the access type
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
.
For attachments with a color format, this uses the access type
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
.
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 generated during
the render pass and within the render area are written to memory.
For attachments with a depth/stencil format, this uses the access type
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
.
For attachments with a color format, this uses the access type
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
.
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.
For attachments with a depth/stencil format, this uses the access type
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
.
For attachments with a color format, this uses the access type
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
.
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.
loadOp
and stencilLoadOp
define the load operations that
execute as part of the first subpass that uses the attachment.
storeOp
and stencilStoreOp
define the store operations that
execute as part of the last subpass that uses the attachment.
The load operation for each value in an attachment used by a subpass
happens-before any command recorded into that subpass reads from that value.
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.
Store operations for each value in an attachment used by a subpass
happen-after any command recorded into that subpass writes to that value.
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.
If an attachment is not used by any subpass, then loadOp
,
storeOp
, stencilStoreOp
, and stencilLoadOp
are ignored,
and the attachment’s memory contents will not be modified by execution of a
render pass instance.
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 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.
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:
![]() | Note |
---|---|
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.
These dependencies must not include the |
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. The precise set of valid scenarios 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.
![]() | Note |
---|---|
Once an attachment needs the |
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
multisample resolve operation.
If pResolveAttachments
is not NULL
, each of its elements
corresponds to a color attachment (the element in
pColorAttachments
at the same index), and a multisample resolve
operation is defined for each attachment.
At the end of each subpass, multisample resolve operations read the
subpass’s color attachments, and resolve the samples for each pixel to
the same pixel location in the corresponding resolve attachments, unless
the resolve attachment index is VK_ATTACHMENT_UNUSED
.
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 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
is the subpass index of the first subpass in the
dependency, or VK_SUBPASS_EXTERNAL
.
dstSubpass
is the subpass index of the second subpass in the
dependency, or VK_SUBPASS_EXTERNAL
.
srcStageMask
defines a source stage mask.
dstStageMask
defines a destination stage mask.
srcAccessMask
defines a source access mask.
dstAccessMask
defines a destination access mask.
dependencyFlags
is a bitmask of VkDependencyFlagBits
.
If srcSubpass
is equal to dstSubpass
then the
VkSubpassDependency
describes a
subpass self-dependency, and only constrains the pipeline barriers allowed within
a subpass instance.
Otherwise, when a render pass instance which includes a subpass dependency
is submitted to a queue, it defines a memory dependency between the
subpasses identified by srcSubpass
and dstSubpass
.
If srcSubpass
is equal to VK_SUBPASS_EXTERNAL
, the first
synchronization scope includes
commands submitted to the queue before the render pass instance began.
Otherwise, the first set of commands includes all commands submitted as part
of the subpass instance identified by srcSubpass
and any load, store
or multisample resolve operations on attachments used in srcSubpass
.
In either case, the first synchronization scope is limited to operations on
the pipeline stages determined by the
source stage mask specified by
srcStageMask
.
If dstSubpass
is equal to VK_SUBPASS_EXTERNAL
, the second
synchronization scope includes
commands submitted after the render pass instance is ended.
Otherwise, the second set of commands includes all commands submitted as
part of the subpass instance identified by dstSubpass
and any load,
store or multisample resolve operations on attachments used in
dstSubpass
.
In either case, the second synchronization scope is limited to operations on
the pipeline stages determined by the
destination stage mask specified
by dstStageMask
.
The first access scope is
limited to access in the pipeline stages determined by the
source stage mask specified by
srcStageMask
.
It is also limited to access types in the source access mask specified by srcAccessMask
.
The second access scope is
limited to access in the pipeline stages determined by the
destination stage mask specified
by dstStageMask
.
It is also limited to access types in the destination access mask specified by dstAccessMask
.
The availability and visibility operations defined by a subpass dependency affect the execution of image layout transitions within the render pass.
![]() | editing-note |
---|---|
The following two alleged implicit dependencies are practically no-ops, as the operations they describe are already guaranteed by semaphores and submission order (so they’re almost entirely no-ops on their own). The only reason they exist is because it simplifies reasoning about where automatic layout transitions happen. Further rewrites of this chapter could potentially remove the need for these. |
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 subpass dependency operates as if defined with the following parameters:
VkSubpassDependency implicitDependency = { .srcSubpass = VK_SUBPASS_EXTERNAL; .dstSubpass = firstSubpass; // First subpass attachment is used in .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; .srcAccessMask = 0; .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; .dependencyFlags = 0; };
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 subpass dependency operates as if defined with the following parameters:
VkSubpassDependency implicitDependency = { .srcSubpass = lastSubpass; // Last subpass attachment is used in .dstSubpass = VK_SUBPASS_EXTERNAL; .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; .dstAccessMask = 0; .dependencyFlags = 0; };
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 renderpass, 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 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
happens-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
happens-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.
If two subpasses use the same attachment in different layouts, and both layouts are read-only, 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:
// Used for input attachments VkPipelineStageFlags inputAttachmentStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; VkAccessFlags inputAttachmentAccess = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; // Used for depth stencil attachments VkPipelineStageFlags depthStencilAttachmentStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; VkAccessFlags depthStencilAttachmentAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; VkSubpassDependency implicitDependency = { .srcSubpass = firstSubpass; .dstSubpass = secondSubpass; .srcStageMask = inputAttachmentStages | depthStencilAttachmentStages; .dstStageMask = inputAttachmentStages | depthStencilAttachmentStages; .srcAccessMask = inputAttachmentAccess | depthStencilAttachmentAccess; .dstAccessMask = inputAttachmentAccess | depthStencilAttachmentAccess; .dependencyFlags = 0; };
If a subpass uses the same attachment as both an input attachment and either a color attachment or a depth/stencil attachment, writes via the color or depth/stencil attachment are not automatically made visible to reads via the input attachment, causing a feedback loop, except in any of the following conditions:
colorWriteMask
, and to disable writes to depth/stencil components
that are read as inputs via depthWriteEnable
or
stencilTestEnable
.
An attachment used as both an input attachment and a color attachment must
be in the VK_IMAGE_LAYOUT_GENERAL
layout.
An attachment used as an input attachment and depth/stencil attachment must
be in either VK_IMAGE_LAYOUT_GENERAL
or
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
.
An attachment must not be used as both a depth/stencil attachment and a
color attachment.
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.