10. Pipelines
The following figure shows a block diagram of the Vulkan pipelines. Some Vulkan commands specify geometric objects to be drawn or computational work to be performed, while others specify state controlling how objects are handled by the various pipeline stages, or control data transfer between memory organized as images and buffers. Commands are effectively sent through a processing pipeline, either a graphics pipeline, or a compute pipeline.
The first stage of the graphics pipeline (Input Assembler) assembles vertices to form geometric primitives such as points, lines, and triangles, based on a requested primitive topology. In the next stage (Vertex Shader) vertices can be transformed, computing positions and attributes for each vertex. If tessellation and/or geometry shaders are supported, they can then generate multiple primitives from a single input primitive, possibly changing the primitive topology or generating additional attribute data in the process.
The final resulting primitives are clipped to a clip volume in preparation for the next stage, Rasterization. The rasterizer produces a series of fragments associated with a region of the framebuffer, from a two-dimensional description of a point, line segment, or triangle. These fragments are processed by fragment operations to determine whether generated values will be written to the framebuffer. Fragment shading determines the values to be written to the framebuffer attachments. Framebuffer operations then read and write the color and depth/stencil attachments of the framebuffer for a given subpass of a render pass instance. The attachments can be used as input attachments in the fragment shader in a later subpass of the same render pass.
The compute pipeline is a separate pipeline from the graphics pipeline, which operates on one-, two-, or three-dimensional workgroups which can read from and write to buffer and image memory.
This ordering is meant only as a tool for describing Vulkan, not as a strict rule of how Vulkan is implemented, and we present it only as a means to organize the various operations of the pipelines. Actual ordering guarantees between pipeline stages are explained in detail in the synchronization chapter.
Each pipeline is controlled by a monolithic object created from a description of all of the shader stages and any relevant fixed-function stages. Linking the whole pipeline together allows the optimization of shaders based on their input/outputs and eliminates expensive draw time state validation.
A pipeline object is bound to the current state using vkCmdBindPipeline. Any pipeline object state that is specified as dynamic is not applied to the current state when the pipeline object is bound, but is instead set by dynamic state setting commands.
No state, including dynamic state, is inherited from one command buffer to another.
Compute,
and graphics pipelines are each represented by VkPipeline
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline)
10.1. Compute Pipelines
Compute pipelines consist of a single static compute shader stage and the pipeline layout.
The compute pipeline represents a compute shader and is created by calling
vkCreateComputePipelines
with module
and pName
selecting
an entry point from a shader module, where that entry point defines a valid
compute shader, in the VkPipelineShaderStageCreateInfo structure
contained within the VkComputePipelineCreateInfo structure.
To create compute pipelines, call:
// Provided by VK_VERSION_1_0
VkResult vkCreateComputePipelines(
VkDevice device,
VkPipelineCache pipelineCache,
uint32_t createInfoCount,
const VkComputePipelineCreateInfo* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkPipeline* pPipelines);
-
device
is the logical device that creates the compute pipelines. -
pipelineCache
is either VK_NULL_HANDLE, indicating that pipeline caching is disabled; or the handle of a valid pipeline cache object, in which case use of that cache is enabled for the duration of the command. -
createInfoCount
is the length of thepCreateInfos
andpPipelines
arrays. -
pCreateInfos
is a pointer to an array of VkComputePipelineCreateInfo structures. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pPipelines
is a pointer to an array of VkPipeline handles in which the resulting compute pipeline objects are returned.
The VkComputePipelineCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkComputePipelineCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineCreateFlags flags;
VkPipelineShaderStageCreateInfo stage;
VkPipelineLayout layout;
VkPipeline basePipelineHandle;
int32_t basePipelineIndex;
} VkComputePipelineCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkPipelineCreateFlagBits specifying how the pipeline will be generated. -
stage
is a VkPipelineShaderStageCreateInfo structure describing the compute shader. -
layout
is the description of binding locations used by both the pipeline and descriptor sets used with the pipeline. -
basePipelineHandle
is a pipeline to derive from -
basePipelineIndex
is an index into thepCreateInfos
parameter to use as a pipeline to derive from
The parameters basePipelineHandle
and basePipelineIndex
are
described in more detail in Pipeline
Derivatives.
The VkPipelineShaderStageCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkPipelineShaderStageCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineShaderStageCreateFlags flags;
VkShaderStageFlagBits stage;
VkShaderModule module;
const char* pName;
const VkSpecializationInfo* pSpecializationInfo;
} VkPipelineShaderStageCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkPipelineShaderStageCreateFlagBits specifying how the pipeline shader stage will be generated. -
stage
is a VkShaderStageFlagBits value specifying a single pipeline stage. -
module
is a VkShaderModule object containing the shader code for this stage. -
pName
is a pointer to a null-terminated UTF-8 string specifying the entry point name of the shader for this stage. -
pSpecializationInfo
is a pointer to a VkSpecializationInfo structure, as described in Specialization Constants, orNULL
.
The shader code used by the pipeline is defined by module
.
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineShaderStageCreateFlags;
VkPipelineShaderStageCreateFlags
is a bitmask type for setting a mask
of zero or more VkPipelineShaderStageCreateFlagBits.
Possible values of the flags
member of
VkPipelineShaderStageCreateInfo specifying how a pipeline shader stage
is created, are:
// Provided by VK_VERSION_1_0
typedef enum VkPipelineShaderStageCreateFlagBits {
// Provided by VK_VERSION_1_3
VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001,
// Provided by VK_VERSION_1_3
VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002,
} VkPipelineShaderStageCreateFlagBits;
-
VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT
specifies that theSubgroupSize
may vary in the shader stage. -
VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT
specifies that the subgroup sizes must be launched with all invocations active in the compute stage.
Note
If |
Bits which can be set by commands and structures, specifying one or more shader stages, are:
// Provided by VK_VERSION_1_0
typedef enum VkShaderStageFlagBits {
VK_SHADER_STAGE_VERTEX_BIT = 0x00000001,
VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002,
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004,
VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008,
VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010,
VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
} VkShaderStageFlagBits;
-
VK_SHADER_STAGE_VERTEX_BIT
specifies the vertex stage. -
VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
specifies the tessellation control stage. -
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
specifies the tessellation evaluation stage. -
VK_SHADER_STAGE_GEOMETRY_BIT
specifies the geometry stage. -
VK_SHADER_STAGE_FRAGMENT_BIT
specifies the fragment stage. -
VK_SHADER_STAGE_COMPUTE_BIT
specifies the compute stage. -
VK_SHADER_STAGE_ALL_GRAPHICS
is a combination of bits used as shorthand to specify all graphics stages defined above (excluding the compute stage). -
VK_SHADER_STAGE_ALL
is a combination of bits used as shorthand to specify all shader stages supported by the device, including all additional stages which are introduced by extensions.
Note
|
// Provided by VK_VERSION_1_0
typedef VkFlags VkShaderStageFlags;
VkShaderStageFlags
is a bitmask type for setting a mask of zero or
more VkShaderStageFlagBits.
The VkPipelineShaderStageRequiredSubgroupSizeCreateInfo
structure is
defined as:
// Provided by VK_VERSION_1_3
typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo {
VkStructureType sType;
void* pNext;
uint32_t requiredSubgroupSize;
} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo;
If a VkPipelineShaderStageRequiredSubgroupSizeCreateInfo
structure is
included in the pNext
chain of VkPipelineShaderStageCreateInfo,
it specifies that the pipeline shader stage being compiled has a required
subgroup size.
10.2. Graphics Pipelines
Graphics pipelines consist of multiple shader stages, multiple fixed-function pipeline stages, and a pipeline layout.
To create graphics pipelines, call:
// Provided by VK_VERSION_1_0
VkResult vkCreateGraphicsPipelines(
VkDevice device,
VkPipelineCache pipelineCache,
uint32_t createInfoCount,
const VkGraphicsPipelineCreateInfo* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkPipeline* pPipelines);
-
device
is the logical device that creates the graphics pipelines. -
pipelineCache
is either VK_NULL_HANDLE, indicating that pipeline caching is disabled; or the handle of a valid pipeline cache object, in which case use of that cache is enabled for the duration of the command. -
createInfoCount
is the length of thepCreateInfos
andpPipelines
arrays. -
pCreateInfos
is a pointer to an array of VkGraphicsPipelineCreateInfo structures. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pPipelines
is a pointer to an array of VkPipeline handles in which the resulting graphics pipeline objects are returned.
The VkGraphicsPipelineCreateInfo structure includes an array of VkPipelineShaderStageCreateInfo structures for each of the desired active shader stages, as well as creation information for all relevant fixed-function stages, and a pipeline layout.
Note
An implicit cache may be provided by the implementation or a layer.
For this reason, it is still valid to set
|
The VkGraphicsPipelineCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkGraphicsPipelineCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineCreateFlags flags;
uint32_t stageCount;
const VkPipelineShaderStageCreateInfo* pStages;
const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
const VkPipelineTessellationStateCreateInfo* pTessellationState;
const VkPipelineViewportStateCreateInfo* pViewportState;
const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
const VkPipelineDynamicStateCreateInfo* pDynamicState;
VkPipelineLayout layout;
VkRenderPass renderPass;
uint32_t subpass;
VkPipeline basePipelineHandle;
int32_t basePipelineIndex;
} VkGraphicsPipelineCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkPipelineCreateFlagBits specifying how the pipeline will be generated. -
stageCount
is the number of entries in thepStages
array. -
pStages
is a pointer to an array ofstageCount
VkPipelineShaderStageCreateInfo structures describing the set of the shader stages to be included in the graphics pipeline. -
pVertexInputState
is a pointer to a VkPipelineVertexInputStateCreateInfo structure. -
pInputAssemblyState
is a pointer to a VkPipelineInputAssemblyStateCreateInfo structure which determines input assembly behavior for vertex shading, as described in Drawing Commands. -
pTessellationState
is a pointer to a VkPipelineTessellationStateCreateInfo structure defining tessellation state used by tessellation shaders. -
pViewportState
is a pointer to a VkPipelineViewportStateCreateInfo structure defining viewport state used when rasterization is enabled. -
pRasterizationState
is a pointer to a VkPipelineRasterizationStateCreateInfo structure defining rasterization state. -
pMultisampleState
is a pointer to a VkPipelineMultisampleStateCreateInfo structure defining multisample state used when rasterization is enabled. -
pDepthStencilState
is a pointer to a VkPipelineDepthStencilStateCreateInfo structure defining depth/stencil state used when rasterization is enabled for depth or stencil attachments accessed during rendering. -
pColorBlendState
is a pointer to a VkPipelineColorBlendStateCreateInfo structure defining color blend state used when rasterization is enabled for any color attachments accessed during rendering. -
pDynamicState
is a pointer to a VkPipelineDynamicStateCreateInfo structure defining which properties of the pipeline state object are dynamic and can be changed independently of the pipeline state. This can beNULL
, which means no state in the pipeline is considered dynamic. -
layout
is the description of binding locations used by both the pipeline and descriptor sets used with the pipeline. -
renderPass
is a handle to a render pass object describing the environment in which the pipeline will be used. The pipeline must only be used with a render pass instance compatible with the one provided. See Render Pass Compatibility for more information. -
subpass
is the index of the subpass in the render pass where this pipeline will be used. -
basePipelineHandle
is a pipeline to derive from. -
basePipelineIndex
is an index into thepCreateInfos
parameter to use as a pipeline to derive from.
The parameters basePipelineHandle
and basePipelineIndex
are
described in more detail in Pipeline
Derivatives.
The state required for a graphics pipeline is divided into vertex input state, pre-rasterization shader state, fragment shader state, and fragment output state.
Vertex input state is defined by:
This state must be specified to create a complete graphics pipeline.
Pre-rasterization shader state is defined by:
-
VkPipelineShaderStageCreateInfo entries for:
-
Vertex shaders
-
Tessellation control shaders
-
Tessellation evaluation shaders
-
Geometry shaders
-
-
Within the VkPipelineLayout, the full pipeline layout must be specified.
-
VkRenderPass and
subpass
parameter -
The
viewMask
parameter of VkPipelineRenderingCreateInfo (formats are ignored)
This state must be specified to create a complete graphics pipeline.
Fragment shader state is defined by:
-
A VkPipelineShaderStageCreateInfo entry for the fragment shader
-
Within the VkPipelineLayout, the full pipeline layout must be specified.
-
VkPipelineMultisampleStateCreateInfo if sample shading is enabled or
renderpass
is not VK_NULL_HANDLE -
VkRenderPass and
subpass
parameter -
The
viewMask
parameter of VkPipelineRenderingCreateInfo (formats are ignored)
If
rasterizerDiscardEnable
is set to VK_FALSE
or VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE
is used,
this state must be specified to create a
complete graphics pipeline.
Fragment output state is defined by:
If
rasterizerDiscardEnable
is set to VK_FALSE
or VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE
is used,
this state must be specified to create a
complete graphics pipeline.
Dynamic state values set via pDynamicState
must be ignored if the
state they correspond to is not otherwise statically set by one of the state
subsets used to create the pipeline.
For example, if a pipeline only included
pre-rasterization shader
state, then any dynamic state value corresponding to depth or stencil
testing has no effect.
A complete graphics pipeline always includes pre-rasterization shader state, with other subsets included depending on that state as specified in the above sections.
The VkPipelineRenderingCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_3
typedef struct VkPipelineRenderingCreateInfo {
VkStructureType sType;
const void* pNext;
uint32_t viewMask;
uint32_t colorAttachmentCount;
const VkFormat* pColorAttachmentFormats;
VkFormat depthAttachmentFormat;
VkFormat stencilAttachmentFormat;
} VkPipelineRenderingCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
viewMask
is the viewMask used for rendering. -
colorAttachmentCount
is the number of entries inpColorAttachmentFormats
-
pColorAttachmentFormats
is a pointer to an array of VkFormat values defining the format of color attachments used in this pipeline. -
depthAttachmentFormat
is a VkFormat value defining the format of the depth attachment used in this pipeline. -
stencilAttachmentFormat
is a VkFormat value defining the format of the stencil attachment used in this pipeline.
When a pipeline is created without a VkRenderPass, if this structure
is present in the pNext
chain of VkGraphicsPipelineCreateInfo,
it specifies the view mask and format of attachments used for rendering.
If this structure is not specified, and the pipeline does not include a
VkRenderPass, viewMask
and colorAttachmentCount
are 0
,
and depthAttachmentFormat
and stencilAttachmentFormat
are
VK_FORMAT_UNDEFINED
.
If a graphics pipeline is created with a valid VkRenderPass,
parameters of this structure are ignored.
If depthAttachmentFormat
, stencilAttachmentFormat
, or any
element of pColorAttachmentFormats
is VK_FORMAT_UNDEFINED
, it
indicates that the corresponding attachment is unused within the render
pass.
Valid formats indicate that an attachment can be used - but it is still
valid to set the attachment to NULL
when beginning rendering.
Bits which can be set in
-
VkGraphicsPipelineCreateInfo::
flags
-
VkComputePipelineCreateInfo::
flags
specify how a pipeline is created, and are:
// Provided by VK_VERSION_1_0
typedef enum VkPipelineCreateFlagBits {
VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001,
VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002,
VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004,
// Provided by VK_VERSION_1_1
VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008,
// Provided by VK_VERSION_1_1
VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010,
// Provided by VK_VERSION_1_3
VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100,
// Provided by VK_VERSION_1_3
VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200,
// Provided by VK_VERSION_1_1
VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT,
} VkPipelineCreateFlagBits;
-
VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT
specifies that the created pipeline will not be optimized. Using this flag may reduce the time taken to create the pipeline. -
VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT
specifies that the pipeline to be created is allowed to be the parent of a pipeline that will be created in a subsequent pipeline creation call. -
VK_PIPELINE_CREATE_DERIVATIVE_BIT
specifies that the pipeline to be created will be a child of a previously created parent pipeline. -
VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT
specifies that any shader input variables decorated asViewIndex
will be assigned values as if they were decorated asDeviceIndex
. -
VK_PIPELINE_CREATE_DISPATCH_BASE
specifies that a compute pipeline can be used with vkCmdDispatchBase with a non-zero base workgroup. -
VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT
specifies that pipeline creation will fail if a compile is required for creation of a valid VkPipeline object;VK_PIPELINE_COMPILE_REQUIRED
will be returned by pipeline creation, and the VkPipeline will be set to VK_NULL_HANDLE. -
When creating multiple pipelines,
VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT
specifies that control will be returned to the application if any individual pipeline returns a result which is notVK_SUCCESS
rather than continuing to create additional pipelines.
It is valid to set both VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT
and
VK_PIPELINE_CREATE_DERIVATIVE_BIT
.
This allows a pipeline to be both a parent and possibly a child in a
pipeline hierarchy.
See Pipeline Derivatives for more
information.
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineCreateFlags;
VkPipelineCreateFlags
is a bitmask type for setting a mask of zero or
more VkPipelineCreateFlagBits.
The VkPipelineDynamicStateCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkPipelineDynamicStateCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineDynamicStateCreateFlags flags;
uint32_t dynamicStateCount;
const VkDynamicState* pDynamicStates;
} VkPipelineDynamicStateCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
dynamicStateCount
is the number of elements in thepDynamicStates
array. -
pDynamicStates
is a pointer to an array of VkDynamicState values specifying which pieces of pipeline state will use the values from dynamic state commands rather than from pipeline state creation information.
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineDynamicStateCreateFlags;
VkPipelineDynamicStateCreateFlags
is a bitmask type for setting a
mask, but is currently reserved for future use.
The source of different pieces of dynamic state is specified by the
VkPipelineDynamicStateCreateInfo::pDynamicStates
property of the
currently active pipeline, each of whose elements must be one of the
values:
// Provided by VK_VERSION_1_0
typedef enum VkDynamicState {
VK_DYNAMIC_STATE_VIEWPORT = 0,
VK_DYNAMIC_STATE_SCISSOR = 1,
VK_DYNAMIC_STATE_LINE_WIDTH = 2,
VK_DYNAMIC_STATE_DEPTH_BIAS = 3,
VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4,
VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5,
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6,
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7,
VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_CULL_MODE = 1000267000,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_FRONT_FACE = 1000267001,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_STENCIL_OP = 1000267011,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004,
} VkDynamicState;
-
VK_DYNAMIC_STATE_VIEWPORT
specifies that thepViewports
state in VkPipelineViewportStateCreateInfo will be ignored and must be set dynamically with vkCmdSetViewport before any drawing commands. The number of viewports used by a pipeline is still specified by theviewportCount
member of VkPipelineViewportStateCreateInfo. -
VK_DYNAMIC_STATE_SCISSOR
specifies that thepScissors
state in VkPipelineViewportStateCreateInfo will be ignored and must be set dynamically with vkCmdSetScissor before any drawing commands. The number of scissor rectangles used by a pipeline is still specified by thescissorCount
member of VkPipelineViewportStateCreateInfo. -
VK_DYNAMIC_STATE_LINE_WIDTH
specifies that thelineWidth
state in VkPipelineRasterizationStateCreateInfo will be ignored and must be set dynamically with vkCmdSetLineWidth before any drawing commands that generate line primitives for the rasterizer. -
VK_DYNAMIC_STATE_DEPTH_BIAS
specifies that thedepthBiasConstantFactor
,depthBiasClamp
anddepthBiasSlopeFactor
states in VkPipelineRasterizationStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthBias before any draws are performed withdepthBiasEnable
in VkPipelineRasterizationStateCreateInfo set toVK_TRUE
. -
VK_DYNAMIC_STATE_BLEND_CONSTANTS
specifies that theblendConstants
state in VkPipelineColorBlendStateCreateInfo will be ignored and must be set dynamically with vkCmdSetBlendConstants before any draws are performed with a pipeline state withVkPipelineColorBlendAttachmentState
memberblendEnable
set toVK_TRUE
and any of the blend functions using a constant blend color. -
VK_DYNAMIC_STATE_DEPTH_BOUNDS
specifies that theminDepthBounds
andmaxDepthBounds
states of VkPipelineDepthStencilStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthBounds before any draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo memberdepthBoundsTestEnable
set toVK_TRUE
. -
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
specifies that thecompareMask
state in VkPipelineDepthStencilStateCreateInfo for bothfront
andback
will be ignored and must be set dynamically with vkCmdSetStencilCompareMask before any draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo memberstencilTestEnable
set toVK_TRUE
-
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
specifies that thewriteMask
state in VkPipelineDepthStencilStateCreateInfo for bothfront
andback
will be ignored and must be set dynamically with vkCmdSetStencilWriteMask before any draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo memberstencilTestEnable
set toVK_TRUE
-
VK_DYNAMIC_STATE_STENCIL_REFERENCE
specifies that thereference
state in VkPipelineDepthStencilStateCreateInfo for bothfront
andback
will be ignored and must be set dynamically with vkCmdSetStencilReference before any draws are performed with a pipeline state with VkPipelineDepthStencilStateCreateInfo memberstencilTestEnable
set toVK_TRUE
-
VK_DYNAMIC_STATE_CULL_MODE
specifies that thecullMode
state in VkPipelineRasterizationStateCreateInfo will be ignored and must be set dynamically with vkCmdSetCullMode before any drawing commands. -
VK_DYNAMIC_STATE_FRONT_FACE
specifies that thefrontFace
state in VkPipelineRasterizationStateCreateInfo will be ignored and must be set dynamically with vkCmdSetFrontFace before any drawing commands. -
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY
specifies that thetopology
state in VkPipelineInputAssemblyStateCreateInfo only specifies the topology class, and the specific topology order and adjacency must be set dynamically with vkCmdSetPrimitiveTopology before any drawing commands. -
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT
specifies that theviewportCount
andpViewports
state in VkPipelineViewportStateCreateInfo will be ignored and must be set dynamically with vkCmdSetViewportWithCount before any draw call. -
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT
specifies that thescissorCount
andpScissors
state in VkPipelineViewportStateCreateInfo will be ignored and must be set dynamically with vkCmdSetScissorWithCount before any draw call. -
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE
specifies that thestride
state in VkVertexInputBindingDescription will be ignored and must be set dynamically with vkCmdBindVertexBuffers2 before any draw call. -
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE
specifies that thedepthTestEnable
state in VkPipelineDepthStencilStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthTestEnable before any draw call. -
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE
specifies that thedepthWriteEnable
state in VkPipelineDepthStencilStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthWriteEnable before any draw call. -
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP
specifies that thedepthCompareOp
state in VkPipelineDepthStencilStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthCompareOp before any draw call. -
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE
specifies that thedepthBoundsTestEnable
state in VkPipelineDepthStencilStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthBoundsTestEnable before any draw call. -
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE
specifies that thestencilTestEnable
state in VkPipelineDepthStencilStateCreateInfo will be ignored and must be set dynamically with vkCmdSetStencilTestEnable before any draw call. -
VK_DYNAMIC_STATE_STENCIL_OP
specifies that thefailOp
,passOp
,depthFailOp
, andcompareOp
states inVkPipelineDepthStencilStateCreateInfo
for bothfront
andback
will be ignored and must be set dynamically with vkCmdSetStencilOp before any draws are performed with a pipeline state withVkPipelineDepthStencilStateCreateInfo
memberstencilTestEnable
set toVK_TRUE
-
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE
specifies that therasterizerDiscardEnable
state in VkPipelineRasterizationStateCreateInfo will be ignored and must be set dynamically with vkCmdSetRasterizerDiscardEnable before any drawing commands. -
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE
specifies that thedepthBiasEnable
state in VkPipelineRasterizationStateCreateInfo will be ignored and must be set dynamically with vkCmdSetDepthBiasEnable before any drawing commands. -
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE
specifies that theprimitiveRestartEnable
state in VkPipelineInputAssemblyStateCreateInfo will be ignored and must be set dynamically with vkCmdSetPrimitiveRestartEnable before any drawing commands.
10.2.1. Valid Combinations of Stages for Graphics Pipelines
If tessellation shader stages are omitted, the tessellation shading and fixed-function stages of the pipeline are skipped.
If a geometry shader is omitted, the geometry shading stage is skipped.
If a fragment shader is omitted, fragment color outputs have undefined values, and the fragment depth value is determined by Fragment Operations state. This can be useful for depth-only rendering.
Presence of a shader stage in a pipeline is indicated by including a valid
VkPipelineShaderStageCreateInfo with module
and pName
selecting an entry point from a shader module, where that entry point is
valid for the stage specified by stage
.
Presence of some of the fixed-function stages in the pipeline is implicitly derived from enabled shaders and provided state. For example, the fixed-function tessellator is always present when the pipeline has valid Tessellation Control and Tessellation Evaluation shaders.
-
Depth/stencil-only rendering in a subpass with no color attachments
-
Active Pipeline Shader Stages
-
Vertex Shader
-
-
Required: Fixed-Function Pipeline Stages
-
-
Color-only rendering in a subpass with no depth/stencil attachment
-
Active Pipeline Shader Stages
-
Vertex Shader
-
Fragment Shader
-
-
Required: Fixed-Function Pipeline Stages
-
-
Rendering pipeline with tessellation and geometry shaders
-
Active Pipeline Shader Stages
-
Vertex Shader
-
Tessellation Control Shader
-
Tessellation Evaluation Shader
-
Geometry Shader
-
Fragment Shader
-
-
Required: Fixed-Function Pipeline Stages
-
10.3. Pipeline Destruction
To destroy a pipeline, call:
// Provided by VK_VERSION_1_0
void vkDestroyPipeline(
VkDevice device,
VkPipeline pipeline,
const VkAllocationCallbacks* pAllocator);
-
device
is the logical device that destroys the pipeline. -
pipeline
is the handle of the pipeline to destroy. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
10.4. Multiple Pipeline Creation
Multiple pipelines can be created simultaneously by passing an array of VkGraphicsPipelineCreateInfo, or VkComputePipelineCreateInfo structures into the vkCreateGraphicsPipelines, and vkCreateComputePipelines commands, respectively. Applications can group together similar pipelines to be created in a single call, and implementations are encouraged to look for reuse opportunities within a group-create.
When an application attempts to create many pipelines in a single command,
it is possible that some subset may fail creation.
In that case, the corresponding entries in the pPipelines
output array
will be filled with VK_NULL_HANDLE values.
If any pipeline fails creation despite valid arguments (for example, due to
out of memory errors), the VkResult code returned by
vkCreate*Pipelines
will indicate why.
The implementation will attempt to create all pipelines, and only return
VK_NULL_HANDLE values for those that actually failed.
If creation fails for a pipeline that had
VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT
set, pipelines at an
index in the pPipelines
array greater than or equal to that of the
failing pipeline must be set to VK_NULL_HANDLE.
If multiple pipelines fail to be created, the VkResult must be the
return value of any of the pipelines which did not return VK_SUCCESS
.
10.5. Pipeline Derivatives
A pipeline derivative is a child pipeline created from a parent pipeline, where the child and parent are expected to have much commonality. The goal of derivative pipelines is that they be cheaper to create using the parent as a starting point, and that it be more efficient (on either host or device) to switch/bind between children of the same parent.
A derivative pipeline is created by setting the
VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag in the
Vk*PipelineCreateInfo
structure.
If this is set, then exactly one of basePipelineHandle
or
basePipelineIndex
members of the structure must have a valid
handle/index, and specifies the parent pipeline.
If basePipelineHandle
is used, the parent pipeline must have already
been created.
If basePipelineIndex
is used, then the parent is being created in the
same command.
VK_NULL_HANDLE acts as the invalid handle for
basePipelineHandle
, and -1 is the invalid index for
basePipelineIndex
.
If basePipelineIndex
is used, the base pipeline must appear earlier
in the array.
The base pipeline must have been created with the
VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT
flag set.
10.6. Pipeline Cache
Pipeline cache objects allow the result of pipeline construction to be reused between pipelines and between runs of an application. Reuse between pipelines is achieved by passing the same pipeline cache object when creating multiple related pipelines. Reuse across runs of an application is achieved by retrieving pipeline cache contents in one run of an application, saving the contents, and using them to preinitialize a pipeline cache on a subsequent run. The contents of the pipeline cache objects are managed by the implementation. Applications can manage the host memory consumed by a pipeline cache object and control the amount of data retrieved from a pipeline cache object.
Pipeline cache objects are represented by VkPipelineCache
handles:
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)
10.6.1. Creating a Pipeline Cache
To create pipeline cache objects, call:
// Provided by VK_VERSION_1_0
VkResult vkCreatePipelineCache(
VkDevice device,
const VkPipelineCacheCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkPipelineCache* pPipelineCache);
-
device
is the logical device that creates the pipeline cache object. -
pCreateInfo
is a pointer to a VkPipelineCacheCreateInfo structure containing initial parameters for the pipeline cache object. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pPipelineCache
is a pointer to a VkPipelineCache handle in which the resulting pipeline cache object is returned.
Note
Applications can track and manage the total host memory size of a pipeline
cache object using the |
Once created, a pipeline cache can be passed to the vkCreateGraphicsPipelines and vkCreateComputePipelines commands. If the pipeline cache passed into these commands is not VK_NULL_HANDLE, the implementation will query it for possible reuse opportunities and update it with new content. The use of the pipeline cache object in these commands is internally synchronized, and the same pipeline cache object can be used in multiple threads simultaneously.
If flags
of pCreateInfo
includes
VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT
, all commands
that modify the returned pipeline cache object must be
externally synchronized.
Note
Implementations should make every effort to limit any critical sections to
the actual accesses to the cache, which is expected to be significantly
shorter than the duration of the |
The VkPipelineCacheCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkPipelineCacheCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineCacheCreateFlags flags;
size_t initialDataSize;
const void* pInitialData;
} VkPipelineCacheCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkPipelineCacheCreateFlagBits specifying the behavior of the pipeline cache. -
initialDataSize
is the number of bytes inpInitialData
. IfinitialDataSize
is zero, the pipeline cache will initially be empty. -
pInitialData
is a pointer to previously retrieved pipeline cache data. If the pipeline cache data is incompatible (as defined below) with the device, the pipeline cache will be initially empty. IfinitialDataSize
is zero,pInitialData
is ignored.
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineCacheCreateFlags;
VkPipelineCacheCreateFlags
is a bitmask type for setting a mask of
zero or more VkPipelineCacheCreateFlagBits.
Bits which can be set in VkPipelineCacheCreateInfo::flags
,
specifying behavior of the pipeline cache, are:
typedef enum VkPipelineCacheCreateFlagBits {
// Provided by VK_VERSION_1_3
VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001,
} VkPipelineCacheCreateFlagBits;
-
VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT
specifies that all commands that modify the created VkPipelineCache will be externally synchronized. When set, the implementation may skip any unnecessary processing needed to support simultaneous modification from multiple threads where allowed.
10.6.2. Merging Pipeline Caches
Pipeline cache objects can be merged using the command:
// Provided by VK_VERSION_1_0
VkResult vkMergePipelineCaches(
VkDevice device,
VkPipelineCache dstCache,
uint32_t srcCacheCount,
const VkPipelineCache* pSrcCaches);
-
device
is the logical device that owns the pipeline cache objects. -
dstCache
is the handle of the pipeline cache to merge results into. -
srcCacheCount
is the length of thepSrcCaches
array. -
pSrcCaches
is a pointer to an array of pipeline cache handles, which will be merged intodstCache
. The previous contents ofdstCache
are included after the merge.
Note
The details of the merge operation are implementation-dependent, but implementations should merge the contents of the specified pipelines and prune duplicate entries. |
10.6.3. Retrieving Pipeline Cache Data
Data can be retrieved from a pipeline cache object using the command:
// Provided by VK_VERSION_1_0
VkResult vkGetPipelineCacheData(
VkDevice device,
VkPipelineCache pipelineCache,
size_t* pDataSize,
void* pData);
-
device
is the logical device that owns the pipeline cache. -
pipelineCache
is the pipeline cache to retrieve data from. -
pDataSize
is a pointer to asize_t
value related to the amount of data in the pipeline cache, as described below. -
pData
is eitherNULL
or a pointer to a buffer.
If pData
is NULL
, then the maximum size of the data that can be
retrieved from the pipeline cache, in bytes, is returned in pDataSize
.
Otherwise, pDataSize
must point to a variable set by the user to the
size of the buffer, in bytes, pointed to by pData
, and on return the
variable is overwritten with the amount of data actually written to
pData
.
If pDataSize
is less than the maximum size that can be retrieved by
the pipeline cache, at most pDataSize
bytes will be written to
pData
, and VK_INCOMPLETE
will be returned instead of
VK_SUCCESS
, to indicate that not all of the pipeline cache was
returned.
Any data written to pData
is valid and can be provided as the
pInitialData
member of the VkPipelineCacheCreateInfo structure
passed to vkCreatePipelineCache
.
Two calls to vkGetPipelineCacheData
with the same parameters must
retrieve the same data unless a command that modifies the contents of the
cache is called between them.
The initial bytes written to pData
must be a header as described in
the Pipeline Cache Header section.
If pDataSize
is less than what is necessary to store this header,
nothing will be written to pData
and zero will be written to
pDataSize
.
10.6.4. Pipeline Cache Header
Applications can store the data retrieved from the pipeline cache, and use these data, possibly in a future run of the application, to populate new pipeline cache objects. The results of pipeline compiles, however, may depend on the vendor ID, device ID, driver version, and other details of the device. To enable applications to detect when previously retrieved data is incompatible with the device, the pipeline cache data must begin with a valid pipeline cache header.
Version one of the pipeline cache header is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkPipelineCacheHeaderVersionOne {
uint32_t headerSize;
VkPipelineCacheHeaderVersion headerVersion;
uint32_t vendorID;
uint32_t deviceID;
uint8_t pipelineCacheUUID[VK_UUID_SIZE];
} VkPipelineCacheHeaderVersionOne;
-
headerSize
is the length in bytes of the pipeline cache header. -
headerVersion
is a VkPipelineCacheHeaderVersion enum value specifying the version of the header. A consumer of the pipeline cache should use the cache version to interpret the remainder of the cache header. -
vendorID
is theVkPhysicalDeviceProperties
::vendorID
of the implementation. -
deviceID
is theVkPhysicalDeviceProperties
::deviceID
of the implementation. -
pipelineCacheUUID
is theVkPhysicalDeviceProperties
::pipelineCacheUUID
of the implementation.
Unlike most structures declared by the Vulkan API, all fields of this structure are written with the least significant byte first, regardless of host byte-order.
The C language specification does not define the packing of structure members. This layout assumes tight structure member packing, with members laid out in the order listed in the structure, and the intended size of the structure is 32 bytes. If a compiler produces code that diverges from that pattern, applications must employ another method to set values at the correct offsets.
Possible values of the headerVersion
value of the pipeline cache
header are:
// Provided by VK_VERSION_1_0
typedef enum VkPipelineCacheHeaderVersion {
VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
} VkPipelineCacheHeaderVersion;
-
VK_PIPELINE_CACHE_HEADER_VERSION_ONE
specifies version one of the pipeline cache.
10.6.5. Destroying a Pipeline Cache
To destroy a pipeline cache, call:
// Provided by VK_VERSION_1_0
void vkDestroyPipelineCache(
VkDevice device,
VkPipelineCache pipelineCache,
const VkAllocationCallbacks* pAllocator);
-
device
is the logical device that destroys the pipeline cache object. -
pipelineCache
is the handle of the pipeline cache to destroy. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
10.7. Specialization Constants
Specialization constants are a mechanism whereby constants in a SPIR-V
module can have their constant value specified at the time the
VkPipeline
is created.
This allows a SPIR-V module to have constants that can be modified while
executing an application that uses the Vulkan API.
Note
Specialization constants are useful to allow a compute shader to have its local workgroup size changed at runtime by the user, for example. |
Each VkPipelineShaderStageCreateInfo structure contains a
pSpecializationInfo
member, which can be NULL
to indicate no
specialization constants, or point to a VkSpecializationInfo
structure.
The VkSpecializationInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkSpecializationInfo {
uint32_t mapEntryCount;
const VkSpecializationMapEntry* pMapEntries;
size_t dataSize;
const void* pData;
} VkSpecializationInfo;
-
mapEntryCount
is the number of entries in thepMapEntries
array. -
pMapEntries
is a pointer to an array ofVkSpecializationMapEntry
structures, which map constant IDs to offsets inpData
. -
dataSize
is the byte size of thepData
buffer. -
pData
contains the actual constant values to specialize with.
The VkSpecializationMapEntry
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkSpecializationMapEntry {
uint32_t constantID;
uint32_t offset;
size_t size;
} VkSpecializationMapEntry;
-
constantID
is the ID of the specialization constant in SPIR-V. -
offset
is the byte offset of the specialization constant value within the supplied data buffer. -
size
is the byte size of the specialization constant value within the supplied data buffer.
If a constantID
value is not a specialization constant ID used in the
shader, that map entry does not affect the behavior of the pipeline.
In human readable SPIR-V:
OpDecorate %x SpecId 13 ; decorate .x component of WorkgroupSize with ID 13
OpDecorate %y SpecId 42 ; decorate .y component of WorkgroupSize with ID 42
OpDecorate %z SpecId 3 ; decorate .z component of WorkgroupSize with ID 3
OpDecorate %wgsize BuiltIn WorkgroupSize ; decorate WorkgroupSize onto constant
%i32 = OpTypeInt 32 0 ; declare an unsigned 32-bit type
%uvec3 = OpTypeVector %i32 3 ; declare a 3 element vector type of unsigned 32-bit
%x = OpSpecConstant %i32 1 ; declare the .x component of WorkgroupSize
%y = OpSpecConstant %i32 1 ; declare the .y component of WorkgroupSize
%z = OpSpecConstant %i32 1 ; declare the .z component of WorkgroupSize
%wgsize = OpSpecConstantComposite %uvec3 %x %y %z ; declare WorkgroupSize
From the above we have three specialization constants, one for each of the x, y & z elements of the WorkgroupSize vector.
Now to specialize the above via the specialization constants mechanism:
const VkSpecializationMapEntry entries[] =
{
{
13, // constantID
0 * sizeof(uint32_t), // offset
sizeof(uint32_t) // size
},
{
42, // constantID
1 * sizeof(uint32_t), // offset
sizeof(uint32_t) // size
},
{
3, // constantID
2 * sizeof(uint32_t), // offset
sizeof(uint32_t) // size
}
};
const uint32_t data[] = { 16, 8, 4 }; // our workgroup size is 16x8x4
const VkSpecializationInfo info =
{
3, // mapEntryCount
entries, // pMapEntries
3 * sizeof(uint32_t), // dataSize
data, // pData
};
Then when calling vkCreateComputePipelines, and passing the
VkSpecializationInfo
we defined as the pSpecializationInfo
parameter of VkPipelineShaderStageCreateInfo, we will create a compute
pipeline with the runtime specified local workgroup size.
Another example would be that an application has a SPIR-V module that has some platform-dependent constants they wish to use.
In human readable SPIR-V:
OpDecorate %1 SpecId 0 ; decorate our signed 32-bit integer constant
OpDecorate %2 SpecId 12 ; decorate our 32-bit floating-point constant
%i32 = OpTypeInt 32 1 ; declare a signed 32-bit type
%float = OpTypeFloat 32 ; declare a 32-bit floating-point type
%1 = OpSpecConstant %i32 -1 ; some signed 32-bit integer constant
%2 = OpSpecConstant %float 0.5 ; some 32-bit floating-point constant
From the above we have two specialization constants, one is a signed 32-bit integer and the second is a 32-bit floating-point value.
Now to specialize the above via the specialization constants mechanism:
struct SpecializationData {
int32_t data0;
float data1;
};
const VkSpecializationMapEntry entries[] =
{
{
0, // constantID
offsetof(SpecializationData, data0), // offset
sizeof(SpecializationData::data0) // size
},
{
12, // constantID
offsetof(SpecializationData, data1), // offset
sizeof(SpecializationData::data1) // size
}
};
SpecializationData data;
data.data0 = -42; // set the data for the 32-bit integer
data.data1 = 42.0f; // set the data for the 32-bit floating-point
const VkSpecializationInfo info =
{
2, // mapEntryCount
entries, // pMapEntries
sizeof(data), // dataSize
&data, // pData
};
It is legal for a SPIR-V module with specializations to be compiled into a pipeline where no specialization information was provided. SPIR-V specialization constants contain default values such that if a specialization is not provided, the default value will be used. In the examples above, it would be valid for an application to only specialize some of the specialization constants within the SPIR-V module, and let the other constants use their default values encoded within the OpSpecConstant declarations.
10.8. Pipeline Binding
Once a pipeline has been created, it can be bound to the command buffer using the command:
// Provided by VK_VERSION_1_0
void vkCmdBindPipeline(
VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipeline pipeline);
-
commandBuffer
is the command buffer that the pipeline will be bound to. -
pipelineBindPoint
is a VkPipelineBindPoint value specifying to which bind point the pipeline is bound. Binding one does not disturb the others. -
pipeline
is the pipeline to be bound.
Once bound, a pipeline binding affects subsequent commands that interact with the given pipeline type in the command buffer until a different pipeline of the same type is bound to the bind point. Commands that do not interact with the given pipeline type must not be affected by the pipeline state.
Possible values of vkCmdBindPipeline::pipelineBindPoint
,
specifying the bind point of a pipeline object, are:
// Provided by VK_VERSION_1_0
typedef enum VkPipelineBindPoint {
VK_PIPELINE_BIND_POINT_GRAPHICS = 0,
VK_PIPELINE_BIND_POINT_COMPUTE = 1,
} VkPipelineBindPoint;
-
VK_PIPELINE_BIND_POINT_COMPUTE
specifies binding as a compute pipeline. -
VK_PIPELINE_BIND_POINT_GRAPHICS
specifies binding as a graphics pipeline.
10.9. Dynamic State
When a pipeline object is bound, any pipeline object state that is not specified as dynamic is applied to the command buffer state. Pipeline object state that is specified as dynamic is not applied to the command buffer state at this time. Instead, dynamic state can be modified at any time and persists for the lifetime of the command buffer, or until modified by another dynamic state setting command, or made invalid by another pipeline bind with that state specified as static.
When a pipeline object is bound, the following applies to each state parameter:
-
If the state is not specified as dynamic in the new pipeline object, then that command buffer state is overwritten by the state in the new pipeline object. Before any draw or dispatch call with this pipeline there must not have been any calls to any of the corresponding dynamic state setting commands after this pipeline was bound.
-
If the state is specified as dynamic in the new pipeline object, then that command buffer state is not disturbed. Before any draw or dispatch call with this pipeline there must have been at least one call to each of the corresponding dynamic state setting commands. The state-setting commands must be recorded after command buffer recording was begun, or after the last command binding a pipeline object with that state specified as static, whichever was the latter.
-
If the state is not included (corresponding pointer in VkGraphicsPipelineCreateInfo was
NULL
or was ignored) in the new pipeline object, then that command buffer state is not disturbed.
Dynamic state that does not affect the result of operations can be left undefined.
Note
For example, if blending is disabled by the pipeline object state then the dynamic color blend constants do not need to be specified in the command buffer, even if this state is specified as dynamic in the pipeline object. |
10.10. Pipeline Creation Feedback
Feedback about the creation of a particular pipeline object can be obtained
by adding a VkPipelineCreationFeedbackCreateInfo
structure to the
pNext
chain of VkGraphicsPipelineCreateInfo,
or VkComputePipelineCreateInfo.
The VkPipelineCreationFeedbackCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_3
typedef struct VkPipelineCreationFeedbackCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineCreationFeedback* pPipelineCreationFeedback;
uint32_t pipelineStageCreationFeedbackCount;
VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks;
} VkPipelineCreationFeedbackCreateInfo;
-
sType
is the type of this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
pPipelineCreationFeedback
is a pointer to a VkPipelineCreationFeedback structure. -
pipelineStageCreationFeedbackCount
is the number of elements inpPipelineStageCreationFeedbacks
. -
pPipelineStageCreationFeedbacks
is a pointer to an array ofpipelineStageCreationFeedbackCount
VkPipelineCreationFeedback structures.
An implementation should write pipeline creation feedback to
pPipelineCreationFeedback
and may write pipeline stage creation
feedback to pPipelineStageCreationFeedbacks
.
An implementation must set or clear the
VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT
in
VkPipelineCreationFeedback::flags
for
pPipelineCreationFeedback
and every element of
pPipelineStageCreationFeedbacks
.
Note
One common scenario for an implementation to skip per-stage feedback is when
|
When chained to
VkGraphicsPipelineCreateInfo, the i
element of
pPipelineStageCreationFeedbacks
corresponds to the i
element of
VkGraphicsPipelineCreateInfo::pStages
.
When chained to VkComputePipelineCreateInfo, the first element of
pPipelineStageCreationFeedbacks
corresponds to
VkComputePipelineCreateInfo::stage
.
The VkPipelineCreationFeedback
structure is defined as:
// Provided by VK_VERSION_1_3
typedef struct VkPipelineCreationFeedback {
VkPipelineCreationFeedbackFlags flags;
uint64_t duration;
} VkPipelineCreationFeedback;
-
flags
is a bitmask of VkPipelineCreationFeedbackFlagBits providing feedback about the creation of a pipeline or of a pipeline stage. -
duration
is the duration spent creating a pipeline or pipeline stage in nanoseconds.
If the VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT
is not set in
flags
, an implementation must not set any other bits in flags
,
and the values of all other VkPipelineCreationFeedback
data members
are undefined.
Possible values of the flags
member of
VkPipelineCreationFeedback are:
// Provided by VK_VERSION_1_3
typedef enum VkPipelineCreationFeedbackFlagBits {
VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001,
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002,
VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004,
VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT,
VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT,
} VkPipelineCreationFeedbackFlagBits;
-
VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT
indicates that the feedback information is valid. -
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT
indicates that a readily usable pipeline or pipeline stage was found in thepipelineCache
specified by the application in the pipeline creation command.An implementation should set the
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT
bit if it was able to avoid the large majority of pipeline or pipeline stage creation work by using thepipelineCache
parameter of vkCreateGraphicsPipelines, or vkCreateComputePipelines. When an implementation sets this bit for the entire pipeline, it may leave it unset for any stage.NoteImplementations are encouraged to provide a meaningful signal to applications using this bit. The intention is to communicate to the application that the pipeline or pipeline stage was created “as fast as it gets” using the pipeline cache provided by the application. If an implementation uses an internal cache, it is discouraged from setting this bit as the feedback would be unactionable.
-
VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT
indicates that the base pipeline specified by thebasePipelineHandle
orbasePipelineIndex
member of theVk*PipelineCreateInfo
structure was used to accelerate the creation of the pipeline.An implementation should set the
VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT
bit if it was able to avoid a significant amount of work by using the base pipeline.NoteWhile “significant amount of work” is subjective, implementations are encouraged to provide a meaningful signal to applications using this bit. For example, a 1% reduction in duration may not warrant setting this bit, while a 50% reduction would.
// Provided by VK_VERSION_1_3
typedef VkFlags VkPipelineCreationFeedbackFlags;
VkPipelineCreationFeedbackFlags
is a bitmask type for providing zero
or more VkPipelineCreationFeedbackFlagBits.