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.