Vulkan-Docs/doc/specs/vulkan/chapters/pipelines.txt

1311 lines
60 KiB
Plaintext

// Copyright (c) 2015-2017 The Khronos Group Inc.
// Copyright notice at https://www.khronos.org/registry/speccopyright.html
[[pipelines]]
= Pipelines
The following <<pipelines-block-diagram,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 <<pipelines-graphics,graphics pipeline>>
(<<drawing,Input Assembler>>) assembles vertices to form geometric
primitives such as points, lines, and triangles, based on a requested
primitive topology.
In the next stage (<<shaders-vertex,Vertex Shader>>) vertices can: be
transformed, computing positions and attributes for each vertex.
If <<tessellation,tessellation>> and/or <<geometry,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 <<vertexpostproc-clipping,clipped>> to a
clip volume in preparation for the next stage, <<primsrast,Rasterization>>.
The rasterizer produces a series of framebuffer addresses and values using a
two-dimensional description of a point, line segment, or triangle.
Each _fragment_ so produced is fed to the next stage
(<<shaders-fragment,Fragment Shader>>) that performs operations on
individual fragments before they finally alter the framebuffer.
These operations include conditional updates into the framebuffer based on
incoming and previously stored depth values (to effect <<fragops-depth,depth
buffering>>), <<framebuffer-blending,blending>> of incoming fragment colors
with stored colors, as well as <<framebuffer-blendoperations,masking>>,
<<fragops-stencil,stenciling>>, and other <<framebuffer-logicop,logical
operations>> on fragment values.
Framebuffer operations read and write the color and depth/stencil
attachments of the framebuffer for a given subpass of a <<renderpass,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 <<pipelines-compute,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-pipeline-stages-order, synchronization chapter>>.
[[pipelines-block-diagram]]
image::images/pipeline.svg[title="Block diagram of the Vulkan pipeline",{fullimagewidth},align="center"]
Each pipeline is controlled by a monolithic object created from a
description of all of the shader stages and any relevant fixed-function
stages.
<<interfaces,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 device state in command buffers.
Any pipeline object state that is marked as dynamic is not applied to the
device state when the pipeline is bound.
Dynamic state not set by binding the pipeline object can: be modified at any
time and persists for the lifetime of the command buffer, or until modified
by another dynamic state command or another pipeline bind.
No state, including dynamic state, is inherited from one command buffer to
another.
Only dynamic state that is required: for the operations performed in the
command buffer needs to be set.
For example, if blending is disabled by the pipeline state then the dynamic
color blend constants do not need to be specified in the command buffer,
even if this state is marked as dynamic in the pipeline state object.
If a new pipeline object is bound with state not marked as dynamic after a
previous pipeline object with that same state as dynamic, the new pipeline
object state will override the dynamic state.
Modifying dynamic state that is not set as dynamic by the pipeline state
object will lead to undefined results.
// refBegin VkPipeline Opaque handle to a pipeline object
Compute and graphics pipelines are each represented by sname:VkPipeline
handles:
include::../api/handles/VkPipeline.txt[]
// refEnd VkPipeline
[[pipelines-compute]]
== 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
fname:vkCreateComputePipelines with pname:module and pname:pName selecting
an entry point from a shader module, where that entry point defines a valid
compute shader, in the sname:VkPipelineShaderStageCreateInfo structure
contained within the sname:VkComputePipelineCreateInfo structure.
// refBegin vkCreateComputePipelines Creates a new compute pipeline object
To create compute pipelines, call:
include::../api/protos/vkCreateComputePipelines.txt[]
* pname:device is the logical device that creates the compute pipelines.
* pname:pipelineCache is either dlink:VK_NULL_HANDLE, indicating that
pipeline caching is disabled; or the handle of a valid
<<pipelines-cache,pipeline cache>> object, in which case use of that
cache is enabled for the duration of the command.
* pname:createInfoCount is the length of the pname:pCreateInfos and
pname:pPipelines arrays.
* pname:pCreateInfos is an array of sname:VkComputePipelineCreateInfo
structures.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
* pname:pPipelines is a pointer to an array in which the resulting compute
pipeline objects are returned.
+
--
ifdef::editing-notes[]
[NOTE]
.editing-note
====
TODO (Jon) - Should we say something like ``the i'th element of the
pname:pPipelines array is created based on the corresponding element of the
pname:pCreateInfos array''? Also for flink:vkCreateGraphicsPipelines below.
====
endif::editing-notes[]
--
.Valid Usage
****
* If the pname:flags member of any given element of pname:pCreateInfos
contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the
pname:basePipelineIndex member of that same element is not `-1`,
pname:basePipelineIndex must: be less than the index into
pname:pCreateInfos that corresponds to that element
* If the pname:flags member of any given element of pname:pCreateInfos
contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, the base
pipeline must: have been created with the
ename:VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT flag set
****
include::../validity/protos/vkCreateComputePipelines.txt[]
// refBegin VkComputePipelineCreateInfo Structure specifying parameters of a newly created compute pipeline
The sname:VkComputePipelineCreateInfo structure is defined as:
include::../api/structs/VkComputePipelineCreateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:flags provides options for pipeline creation, and is of type
elink:VkPipelineCreateFlagBits.
* pname:stage is a slink:VkPipelineShaderStageCreateInfo describing the
compute shader.
* pname:layout is the description of binding locations used by both the
pipeline and descriptor sets used with the pipeline.
* pname:basePipelineHandle is a pipeline to derive from
* pname:basePipelineIndex is an index into the pname:pCreateInfos
parameter to use as a pipeline to derive from
The parameters pname:basePipelineHandle and pname:basePipelineIndex are
described in more detail in <<pipelines-pipeline-derivatives,Pipeline
Derivatives>>.
pname:stage points to a structure of type
sname:VkPipelineShaderStageCreateInfo.
.Valid Usage
****
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineIndex is -1, pname:basePipelineHandle must:
be a valid handle to a compute sname:VkPipeline
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineHandle is dlink:VK_NULL_HANDLE,
pname:basePipelineIndex must: be a valid index into the calling
command's pname:pCreateInfos parameter
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineIndex is not -1, pname:basePipelineHandle
must: be dlink:VK_NULL_HANDLE
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE,
pname:basePipelineIndex must: be -1
* The pname:stage member of pname:stage must: be
ename:VK_SHADER_STAGE_COMPUTE_BIT
* The shader code for the entry point identified by pname:stage and the
rest of the state identified by this structure must: adhere to the
pipeline linking rules described in the <<interfaces,Shader Interfaces>>
chapter
* pname:layout must: be
<<descriptorsets-pipelinelayout-consistency,consistent>> with the layout
of the compute shader specified in pname:stage
****
include::../validity/structs/VkComputePipelineCreateInfo.txt[]
// refBegin VkPipelineShaderStageCreateInfo Structure specifying parameters of a newly created pipeline shader stage
The sname:VkPipelineShaderStageCreateInfo structure is defined as:
include::../api/structs/VkPipelineShaderStageCreateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:flags is reserved for future use.
* pname:stage names a single pipeline stage.
Bits which can: be set include:
+
--
// refBegin VkShaderStageFlagBits Bitmask specifying a pipeline stage
include::../api/enums/VkShaderStageFlagBits.txt[]
--
* pname:module is a sname:VkShaderModule object that contains the shader
for this stage.
* pname:pName is a pointer to a null-terminated UTF-8 string specifying
the entry point name of the shader for this stage.
* pname:pSpecializationInfo is a pointer to slink:VkSpecializationInfo, as
described in <<pipelines-specialization-constants,Specialization
Constants>>, and can: be `NULL`.
.Valid Usage
****
* If the <<features-features-geometryShader,geometry shaders>> feature is
not enabled, pname:stage must: not be ename:VK_SHADER_STAGE_GEOMETRY_BIT
* If the <<features-features-tessellationShader,tessellation shaders>>
feature is not enabled, pname:stage must: not be
ename:VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or
ename:VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
* pname:stage must: not be ename:VK_SHADER_STAGE_ALL_GRAPHICS, or
ename:VK_SHADER_STAGE_ALL
* pname:pName must: be the name of an code:OpEntryPoint in pname:module
with an execution model that matches pname:stage
* If the identified entry point includes any variable in its interface
that is declared with the code:ClipDistance code:BuiltIn decoration,
that variable must: not have an array size greater than
sname:VkPhysicalDeviceLimits::pname:maxClipDistances
* If the identified entry point includes any variable in its interface
that is declared with the code:CullDistance code:BuiltIn decoration,
that variable must: not have an array size greater than
sname:VkPhysicalDeviceLimits::pname:maxCullDistances
* If the identified entry point includes any variables in its interface
that are declared with the code:ClipDistance or code:CullDistance
code:BuiltIn decoration, those variables must: not have array sizes
which sum to more than
sname:VkPhysicalDeviceLimits::pname:maxCombinedClipAndCullDistances
* If the identified entry point includes any variable in its interface
that is declared with the code:SampleMask code:BuiltIn decoration, that
variable must: not have an array size greater than
sname:VkPhysicalDeviceLimits::pname:maxSampleMaskWords
* If pname:stage is ename:VK_SHADER_STAGE_VERTEX_BIT, the identified entry
point must: not include any input variable in its interface that is
decorated with code:CullDistance
* If pname:stage is ename:VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or
ename:VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, and the identified
entry point has an code:OpExecutionMode instruction that specifies a
patch size with code:OutputVertices, the patch size must: be greater
than `0` and less than or equal to
sname:VkPhysicalDeviceLimits::pname:maxTessellationPatchSize
* If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, the identified
entry point must: have an code:OpExecutionMode instruction that
specifies a maximum output vertex count that is greater than `0` and
less than or equal to
sname:VkPhysicalDeviceLimits::pname:maxGeometryOutputVertices
* If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, the identified
entry point must: have an code:OpExecutionMode instruction that
specifies an invocation count that is greater than `0` and less than or
equal to
sname:VkPhysicalDeviceLimits::pname:maxGeometryShaderInvocations
* If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, and the identified
entry point writes to code:Layer for any primitive, it must: write the
same value to code:Layer for all vertices of a given primitive
* If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, and the identified
entry point writes to code:ViewportIndex for any primitive, it must:
write the same value to code:ViewportIndex for all vertices of a given
primitive
* If pname:stage is ename:VK_SHADER_STAGE_FRAGMENT_BIT, the identified
entry point must: not include any output variables in its interface
decorated with code:CullDistance
* If pname:stage is ename:VK_SHADER_STAGE_FRAGMENT_BIT, and the identified
entry point writes to code:FragDepth in any execution path, it must:
write to code:FragDepth in all execution paths
****
include::../validity/structs/VkPipelineShaderStageCreateInfo.txt[]
[[pipelines-graphics]]
== Graphics Pipelines
Graphics pipelines consist of multiple shader stages, multiple
fixed-function pipeline stages, and a pipeline layout.
// refBegin vkCreateGraphicsPipelines Create graphics pipelines
To create graphics pipelines, call:
include::../api/protos/vkCreateGraphicsPipelines.txt[]
* pname:device is the logical device that creates the graphics pipelines.
* pname:pipelineCache is either dlink:VK_NULL_HANDLE, indicating that
pipeline caching is disabled; or the handle of a valid
<<pipelines-cache,pipeline cache>> object, in which case use of that
cache is enabled for the duration of the command.
* pname:createInfoCount is the length of the pname:pCreateInfos and
pname:pPipelines arrays.
* pname:pCreateInfos is an array of sname:VkGraphicsPipelineCreateInfo
structures.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
* pname:pPipelines is a pointer to an array in which the resulting
graphics pipeline objects are returned.
The slink:VkGraphicsPipelineCreateInfo structure includes an array of shader
create info structures containing all the desired active shader stages, as
well as creation info to define all relevant fixed-function stages, and a
pipeline layout.
.Valid Usage
****
* If the pname:flags member of any given element of pname:pCreateInfos
contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the
pname:basePipelineIndex member of that same element is not `-1`,
pname:basePipelineIndex must: be less than the index into
pname:pCreateInfos that corresponds to that element
* If the pname:flags member of any given element of pname:pCreateInfos
contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, the base
pipeline must: have been created with the
ename:VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT flag set
****
include::../validity/protos/vkCreateGraphicsPipelines.txt[]
// refBegin VkGraphicsPipelineCreateInfo Structure specifying parameters of a newly created graphics pipeline
The sname:VkGraphicsPipelineCreateInfo structure is defined as:
include::../api/structs/VkGraphicsPipelineCreateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:flags is a bitmask of elink:VkPipelineCreateFlagBits controlling
how the pipeline will be generated, as described below.
* pname:stageCount is the number of entries in the pname:pStages array.
* pname:pStages is an array of size pname:stageCount structures of type
slink:VkPipelineShaderStageCreateInfo describing the set of the shader
stages to be included in the graphics pipeline.
* pname:pVertexInputState is a pointer to an instance of the
slink:VkPipelineVertexInputStateCreateInfo structure.
* pname:pInputAssemblyState is a pointer to an instance of the
slink:VkPipelineInputAssemblyStateCreateInfo structure which determines
input assembly behavior, as described in <<drawing, Drawing Commands>>.
* pname:pTessellationState is a pointer to an instance of the
slink:VkPipelineTessellationStateCreateInfo structure, or `NULL` if the
pipeline does not include a tessellation control shader stage and
tessellation evaluation shader stage.
* pname:pViewportState is a pointer to an instance of the
slink:VkPipelineViewportStateCreateInfo structure, or `NULL` if the
pipeline has rasterization disabled.
* pname:pRasterizationState is a pointer to an instance of the
slink:VkPipelineRasterizationStateCreateInfo structure.
* pname:pMultisampleState is a pointer to an instance of the
slink:VkPipelineMultisampleStateCreateInfo, or `NULL` if the pipeline
has rasterization disabled.
* pname:pDepthStencilState is a pointer to an instance of the
slink:VkPipelineDepthStencilStateCreateInfo structure, or `NULL` if the
pipeline has rasterization disabled or if the subpass of the render pass
the pipeline is created against does not use a depth/stencil attachment.
* pname:pColorBlendState is a pointer to an instance of the
slink:VkPipelineColorBlendStateCreateInfo structure, or `NULL` if the
pipeline has rasterization disabled or if the subpass of the render pass
the pipeline is created against does not use any color attachments.
* pname:pDynamicState is a pointer to
slink:VkPipelineDynamicStateCreateInfo and is used to indicate which
properties of the pipeline state object are dynamic and can: be changed
independently of the pipeline state.
This can: be `NULL`, which means no state in the pipeline is considered
dynamic.
* pname:layout is the description of binding locations used by both the
pipeline and descriptor sets used with the pipeline.
* pname: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 an instance of any render pass compatible with the one
provided.
See <<renderpass-compatibility,Render Pass Compatibility>> for more
information.
* pname:subpass is the index of the subpass in the render pass where this
pipeline will be used.
* pname:basePipelineHandle is a pipeline to derive from.
* pname:basePipelineIndex is an index into the pname:pCreateInfos
parameter to use as a pipeline to derive from.
The parameters pname:basePipelineHandle and pname:basePipelineIndex are
described in more detail in <<pipelines-pipeline-derivatives,Pipeline
Derivatives>>.
pname:pStages points to an array of slink:VkPipelineShaderStageCreateInfo
structures, which were previously described in <<pipelines-compute,Compute
Pipelines>>.
Bits which can: be set in pname:flags are:
// refBegin VkPipelineCreateFlagBits Bitmask controlling how a pipeline is generated
include::../api/enums/VkPipelineCreateFlagBits.txt[]
* ename: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.
* ename: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 call to flink:vkCreateGraphicsPipelines.
* ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT specifies that the pipeline to
be created will be a child of a previously created parent pipeline.
It is valid to set both ename:VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT and
ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT.
This allows a pipeline to be both a parent and possibly a child in a
pipeline hierarchy.
See <<pipelines-pipeline-derivatives,Pipeline Derivatives>> for more
information.
pname:pDynamicState points to a structure of type
sname:VkPipelineDynamicStateCreateInfo.
ifdef::VK_NV_glsl_shader[]
If any shader stage fails to compile,
ifdef::VK_EXT_debug_report[]
the compile log will be reported back to the application, and
endif::VK_EXT_debug_report[]
ename:VK_ERROR_INVALID_SHADER_NV will be generated.
endif::VK_NV_glsl_shader[]
.Valid Usage
****
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineIndex is -1, pname:basePipelineHandle must:
be a valid handle to a graphics sname:VkPipeline
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineHandle is dlink:VK_NULL_HANDLE,
pname:basePipelineIndex must: be a valid index into the calling
command's pname:pCreateInfos parameter
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineIndex is not -1, pname:basePipelineHandle
must: be dlink:VK_NULL_HANDLE
* If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT
flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE,
pname:basePipelineIndex must: be -1
* The pname:stage member of each element of pname:pStages must: be unique
* The pname:stage member of one element of pname:pStages must: be
ename:VK_SHADER_STAGE_VERTEX_BIT
* The pname:stage member of any given element of pname:pStages must: not
be ename:VK_SHADER_STAGE_COMPUTE_BIT
* If pname:pStages includes a tessellation control shader stage, it must:
include a tessellation evaluation shader stage
* If pname:pStages includes a tessellation evaluation shader stage, it
must: include a tessellation control shader stage
* If pname:pStages includes a tessellation control shader stage and a
tessellation evaluation shader stage, pname:pTessellationState must: not
be `NULL`
* If pname:pStages includes tessellation shader stages, the shader code of
at least one stage must: contain an code:OpExecutionMode instruction
that specifies the type of subdivision in the pipeline
* If pname:pStages includes tessellation shader stages, and the shader
code of both stages contain an code:OpExecutionMode instruction that
specifies the type of subdivision in the pipeline, they must: both
specify the same subdivision mode
* If pname:pStages includes tessellation shader stages, the shader code of
at least one stage must: contain an code:OpExecutionMode instruction
that specifies the output patch size in the pipeline
* If pname:pStages includes tessellation shader stages, and the shader
code of both contain an code:OpExecutionMode instruction that specifies
the out patch size in the pipeline, they must: both specify the same
patch size
* If pname:pStages includes tessellation shader stages, the pname:topology
member of pname:pInputAssembly must: be
ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
* If the pname:topology member of pname:pInputAssembly is
ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pname:pStages must: include
tessellation shader stages
* If pname:pStages includes a geometry shader stage, and does not include
any tessellation shader stages, its shader code must: contain an
code:OpExecutionMode instruction that specifies an input primitive type
that is <<shaders-geometry-execution, compatible>> with the primitive
topology specified in pname:pInputAssembly
* If pname:pStages includes a geometry shader stage, and also includes
tessellation shader stages, its shader code must: contain an
code:OpExecutionMode instruction that specifies an input primitive type
that is <<shaders-geometry-execution, compatible>> with the primitive
topology that is output by the tessellation stages
* If pname:pStages includes a fragment shader stage and a geometry shader
stage, and the fragment shader code reads from an input variable that is
decorated with code:PrimitiveID, then the geometry shader code must:
write to a matching output variable, decorated with code:PrimitiveID, in
all execution paths
* If pname:pStages includes a fragment shader stage, its shader code must:
not read from any input attachment that is defined as
ename:VK_ATTACHMENT_UNUSED in pname:subpass
* The shader code for the entry points identified by pname:pStages, and
the rest of the state identified by this structure must: adhere to the
pipeline linking rules described in the <<interfaces,Shader Interfaces>>
chapter
* If pname:subpass uses a depth/stencil attachment in pname:renderpass
that has a layout of
ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the
sname:VkAttachmentReference defined by pname:subpass, and
pname:pDepthStencilState is not `NULL`, the pname:depthWriteEnable
member of pname:pDepthStencilState must: be ename:VK_FALSE
* If pname:subpass uses a depth/stencil attachment in pname:renderpass
that has a layout of
ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the
sname:VkAttachmentReference defined by pname:subpass, and
pname:pDepthStencilState is not `NULL`, the pname:failOp, pname:passOp
and pname:depthFailOp members of each of the pname:front and pname:back
members of pname:pDepthStencilState must: be ename:VK_STENCIL_OP_KEEP
* If pname:pColorBlendState is not `NULL`, the pname:blendEnable member of
each element of the pname:pAttachment member of pname:pColorBlendState
must: be ename:VK_FALSE if the pname:format of the attachment referred
to in pname:subpass of pname:renderPass does not support color blend
operations, as specified by the
ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT flag in
sname:VkFormatProperties::pname:linearTilingFeatures or
sname:VkFormatProperties::pname:optimalTilingFeatures returned by
fname:vkGetPhysicalDeviceFormatProperties
* If pname:pColorBlendState is not `NULL`, The pname:attachmentCount
member of pname:pColorBlendState must: be equal to the
pname:colorAttachmentCount used to create pname:subpass
* If no element of the pname:pDynamicStates member of pname:pDynamicState
is ename:VK_DYNAMIC_STATE_VIEWPORT, the pname:pViewports member of
pname:pViewportState must: be a pointer to an array of
pname:pViewportState::pname:viewportCount sname:VkViewport structures
* If no element of the pname:pDynamicStates member of pname:pDynamicState
is ename:VK_DYNAMIC_STATE_SCISSOR, the pname:pScissors member of
pname:pViewportState must: be a pointer to an array of
pname:pViewportState::pname:scissorCount sname:VkRect2D structures
* If the wide lines feature is not enabled, and no element of the
pname:pDynamicStates member of pname:pDynamicState is
ename:VK_DYNAMIC_STATE_LINE_WIDTH, the pname:lineWidth member of
pname:pRasterizationState must: be `1.0`
* If the pname:rasterizerDiscardEnable member of pname:pRasterizationState
is ename:VK_FALSE, pname:pViewportState must: be a pointer to a valid
sname:VkPipelineViewportStateCreateInfo structure
* If the pname:rasterizerDiscardEnable member of pname:pRasterizationState
is ename:VK_FALSE, pname:pMultisampleState must: be a pointer to a valid
sname:VkPipelineMultisampleStateCreateInfo structure
* If the pname:rasterizerDiscardEnable member of pname:pRasterizationState
is ename:VK_FALSE, and pname:subpass uses a depth/stencil attachment,
pname:pDepthStencilState must: be a pointer to a valid
sname:VkPipelineDepthStencilStateCreateInfo structure
* If the pname:rasterizerDiscardEnable member of pname:pRasterizationState
is ename:VK_FALSE, and pname:subpass uses color attachments,
pname:pColorBlendState must: be a pointer to a valid
sname:VkPipelineColorBlendStateCreateInfo structure
* If the depth bias clamping feature is not enabled, no element of the
pname:pDynamicStates member of pname:pDynamicState is
ename:VK_DYNAMIC_STATE_DEPTH_BIAS, and the pname:depthBiasEnable member
of pname:pDepthStencil is ename:VK_TRUE, the pname:depthBiasClamp member
of pname:pDepthStencil must: be `0.0`
* If no element of the pname:pDynamicStates member of pname:pDynamicState
is ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS, and the
pname:depthBoundsTestEnable member of pname:pDepthStencil is
ename:VK_TRUE, the pname:minDepthBounds and pname:maxDepthBounds members
of pname:pDepthStencil must: be between `0.0` and `1.0`, inclusive
* pname:layout must: be
<<descriptorsets-pipelinelayout-consistency,consistent>> with all
shaders specified in pname:pStages
* If pname:subpass uses color and/or depth/stencil attachments, then the
pname:rasterizationSamples member of pname:pMultisampleState must: be
the same as the sample count for those subpass attachments
* If pname:subpass does not use any color and/or depth/stencil
attachments, then the pname:rasterizationSamples member of
pname:pMultisampleState must: follow the rules for a
<<renderpass-noattachments, zero-attachment subpass>>
* pname:subpass must: be a valid subpass within pname:renderpass
****
include::../validity/structs/VkGraphicsPipelineCreateInfo.txt[]
// refBegin VkPipelineDynamicStateCreateInfo Structure specifying parameters of a newly created pipeline dynamic state
The sname:VkPipelineDynamicStateCreateInfo structure is defined as:
include::../api/structs/VkPipelineDynamicStateCreateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:flags is reserved for future use.
* pname:dynamicStateCount is the number of elements in the
pname:pDynamicStates array.
* pname:pDynamicStates is an array of elink:VkDynamicState enums which
indicate which pieces of pipeline state will use the values from dynamic
state commands rather than from the pipeline state creation info.
include::../validity/structs/VkPipelineDynamicStateCreateInfo.txt[]
// refBegin VkDynamicState Indicate which dynamic state is taken from dynamic state commands
The source of difference pieces of dynamic state is determined by the
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates property of the
currently active pipeline, which takes the following values:
include::../api/enums/VkDynamicState.txt[]
* ename:VK_DYNAMIC_STATE_VIEWPORT indicates that the pname:pViewports
state in sname:VkPipelineViewportStateCreateInfo will be ignored and
must: be set dynamically with flink:vkCmdSetViewport before any draw
commands.
The number of viewports used by a pipeline is still specified by the
pname:viewportCount member of sname:VkPipelineViewportStateCreateInfo.
* ename:VK_DYNAMIC_STATE_SCISSOR indicates that the pname:pScissors state
in sname:VkPipelineViewportStateCreateInfo will be ignored and must: be
set dynamically with flink:vkCmdSetScissor before any draw commands.
The number of scissor rectangles used by a pipeline is still specified
by the pname:scissorCount member of
sname:VkPipelineViewportStateCreateInfo.
* ename:VK_DYNAMIC_STATE_LINE_WIDTH indicates that the pname:lineWidth
state in sname:VkPipelineRasterizationStateCreateInfo will be ignored
and must: be set dynamically with flink:vkCmdSetLineWidth before any
draw commands that generate line primitives for the rasterizer.
* ename:VK_DYNAMIC_STATE_DEPTH_BIAS indicates that the
pname:depthBiasConstantFactor, pname:depthBiasClamp and
pname:depthBiasSlopeFactor states in
sname:VkPipelineRasterizationStateCreateInfo will be ignored and must:
be set dynamically with flink:vkCmdSetDepthBias before any draws are
performed with pname:depthBiasEnable in
sname:VkPipelineRasterizationStateCreateInfo set to ename:VK_TRUE.
* ename:VK_DYNAMIC_STATE_BLEND_CONSTANTS indicates that the
pname:blendConstants state in sname:VkPipelineColorBlendStateCreateInfo
will be ignored and must: be set dynamically with
flink:vkCmdSetBlendConstants before any draws are performed with a
pipeline state with sname:VkPipelineColorBlendAttachmentState member
pname:blendEnable set to ename:VK_TRUE and any of the blend functions
using a constant blend color.
* ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS indicates that the
pname:minDepthBounds and pname:maxDepthBounds states of
slink:VkPipelineDepthStencilStateCreateInfo will be ignored and must: be
set dynamically with flink:vkCmdSetDepthBounds before any draws are
performed with a pipeline state with
sname:VkPipelineDepthStencilStateCreateInfo member
pname:depthBoundsTestEnable set to ename:VK_TRUE.
* ename:VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK indicates that the
pname:compareMask state in sname:VkPipelineDepthStencilStateCreateInfo
for both pname:front and pname:back will be ignored and must: be set
dynamically with flink:vkCmdSetStencilCompareMask before any draws are
performed with a pipeline state with
sname:VkPipelineDepthStencilStateCreateInfo member
pname:stencilTestEnable set to ename:VK_TRUE
* ename:VK_DYNAMIC_STATE_STENCIL_WRITE_MASK indicates that the
pname:writeMask state in sname:VkPipelineDepthStencilStateCreateInfo for
both pname:front and pname:back will be ignored and must: be set
dynamically with flink:vkCmdSetStencilWriteMask before any draws are
performed with a pipeline state with
sname:VkPipelineDepthStencilStateCreateInfo member
pname:stencilTestEnable set to ename:VK_TRUE
* ename:VK_DYNAMIC_STATE_STENCIL_REFERENCE indicates that the
pname:reference state in sname:VkPipelineDepthStencilStateCreateInfo for
both pname:front and pname:back will be ignored and must: be set
dynamically with flink:vkCmdSetStencilReference before any draws are
performed with a pipeline state with
sname:VkPipelineDepthStencilStateCreateInfo member
pname:stencilTestEnable set to ename:VK_TRUE
// refEnd VkDynamicState
=== 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, the results of fragment processing are
undefined.
Specifically, any fragment color outputs are considered to have undefined
values, and the fragment depth is considered to be unmodified.
This can: be useful for depth-only rendering.
Presence of a shader stage in a pipeline is indicated by including a valid
sname:VkPipelineShaderStageCreateInfo with pname:module and pname:pName
selecting an entry point from a shader module, where that entry point is
valid for the stage specified by pname: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.
.For example:
* Depth/stencil-only rendering in a subpass with no color attachments
** Active Pipeline Shader Stages
*** Vertex Shader
** Required: Fixed-Function Pipeline Stages
*** slink:VkPipelineVertexInputStateCreateInfo
*** slink:VkPipelineInputAssemblyStateCreateInfo
*** slink:VkPipelineViewportStateCreateInfo
*** slink:VkPipelineRasterizationStateCreateInfo
*** slink:VkPipelineMultisampleStateCreateInfo
*** slink:VkPipelineDepthStencilStateCreateInfo
* Color-only rendering in a subpass with no depth/stencil attachment
** Active Pipeline Shader Stages
*** Vertex Shader
*** Fragment Shader
** Required: Fixed-Function Pipeline Stages
*** slink:VkPipelineVertexInputStateCreateInfo
*** slink:VkPipelineInputAssemblyStateCreateInfo
*** slink:VkPipelineViewportStateCreateInfo
*** slink:VkPipelineRasterizationStateCreateInfo
*** slink:VkPipelineMultisampleStateCreateInfo
*** slink:VkPipelineColorBlendStateCreateInfo
* 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
*** slink:VkPipelineVertexInputStateCreateInfo
*** slink:VkPipelineInputAssemblyStateCreateInfo
*** slink:VkPipelineTessellationStateCreateInfo
*** slink:VkPipelineViewportStateCreateInfo
*** slink:VkPipelineRasterizationStateCreateInfo
*** slink:VkPipelineMultisampleStateCreateInfo
*** slink:VkPipelineDepthStencilStateCreateInfo
*** slink:VkPipelineColorBlendStateCreateInfo
[[pipelines-destruction]]
== Pipeline destruction
// refBegin vkDestroyPipeline Destroy a pipeline object
To destroy a graphics or compute pipeline, call:
include::../api/protos/vkDestroyPipeline.txt[]
* pname:device is the logical device that destroys the pipeline.
* pname:pipeline is the handle of the pipeline to destroy.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
.Valid Usage
****
* All submitted commands that refer to pname:pipeline must: have completed
execution
* If sname:VkAllocationCallbacks were provided when pname:pipeline was
created, a compatible set of callbacks must: be provided here
* If no sname:VkAllocationCallbacks were provided when pname:pipeline was
created, pname:pAllocator must: be `NULL`
****
include::../validity/protos/vkDestroyPipeline.txt[]
[[pipelines-multiple]]
== Multiple Pipeline Creation
Multiple pipelines can: be created simultaneously by passing an array of
sname:VkGraphicsPipelineCreateInfo or sname:VkComputePipelineCreateInfo
structures into the flink:vkCreateGraphicsPipelines and
flink: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 pname:pPipelines output array
will be filled with dlink:VK_NULL_HANDLE values.
If any pipeline fails creation (for example, due to out of memory errors),
the ftext:vkCreate*Pipelines commands will return an error code.
The implementation will attempt to create all pipelines, and only return
dlink:VK_NULL_HANDLE values for those that actually failed.
[[pipelines-pipeline-derivatives]]
== 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
ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag in the
stext:Vk*PipelineCreateInfo structure.
If this is set, then exactly one of pname:basePipelineHandle or
pname:basePipelineIndex members of the structure must: have a valid
handle/index, and indicates the parent pipeline.
If pname:basePipelineHandle is used, the parent pipeline must: have already
been created.
If pname:basePipelineIndex is used, then the parent is being created in the
same command.
dlink:VK_NULL_HANDLE acts as the invalid handle for
pname:basePipelineHandle, and -1 is the invalid index for
pname:basePipelineIndex.
If pname:basePipelineIndex is used, the base pipeline must: appear earlier
in the array.
The base pipeline must: have been created with the
ename:VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT flag set.
[[pipelines-cache]]
== Pipeline Cache
// refBegin VkPipelineCache Opaque handle to a pipeline cache object
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 sname:VkPipelineCache handles:
include::../api/handles/VkPipelineCache.txt[]
// refEnd VkPipelineCache
// refBegin vkCreatePipelineCache Creates a new pipeline cache
To create pipeline cache objects, call:
include::../api/protos/vkCreatePipelineCache.txt[]
* pname:device is the logical device that creates the pipeline cache
object.
* pname:pCreateInfo is a pointer to a sname:VkPipelineCacheCreateInfo
structure that contains the initial parameters for the pipeline cache
object.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
* pname:pPipelineCache is a pointer to a sname:VkPipelineCache handle in
which the resulting pipeline cache object is returned.
[NOTE]
.Note
====
Applications can: track and manage the total host memory size of a pipeline
cache object using the pname:pAllocator.
Applications can: limit the amount of data retrieved from a pipeline cache
object in fname:vkGetPipelineCacheData.
Implementations should: not internally limit the total number of entries
added to a pipeline cache object or the total host memory consumed.
====
Once created, a pipeline cache can: be passed to the
fname:vkCreateGraphicsPipelines and fname:vkCreateComputePipelines commands.
If the pipeline cache passed into these commands is not
dlink: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.
[NOTE]
.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 fname:vkCreateGraphicsPipelines and
fname:vkCreateComputePipelines commands.
====
include::../validity/protos/vkCreatePipelineCache.txt[]
// refBegin VkPipelineCacheCreateInfo Structure specifying parameters of a newly created pipeline cache
The sname:VkPipelineCacheCreateInfo structure is defined as:
include::../api/structs/VkPipelineCacheCreateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:flags is reserved for future use.
* pname:initialDataSize is the number of bytes in pname:pInitialData.
If pname:initialDataSize is zero, the pipeline cache will initially be
empty.
* pname: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.
If pname:initialDataSize is zero, pname:pInitialData is ignored.
.Valid Usage
****
* If pname:initialDataSize is not `0`, it must: be equal to the size of
pname:pInitialData, as returned by fname:vkGetPipelineCacheData when
pname:pInitialData was originally retrieved
* If pname:initialDataSize is not `0`, pname:pInitialData must: have been
retrieved from a previous call to fname:vkGetPipelineCacheData
****
include::../validity/structs/VkPipelineCacheCreateInfo.txt[]
// refBegin vkMergePipelineCaches Combine the data stores of pipeline caches
Pipeline cache objects can: be merged using the command:
include::../api/protos/vkMergePipelineCaches.txt[]
* pname:device is the logical device that owns the pipeline cache objects.
* pname:dstCache is the handle of the pipeline cache to merge results
into.
* pname:srcCacheCount is the length of the pname:pSrcCaches array.
* pname:pSrcCaches is an array of pipeline cache handles, which will be
merged into pname:dstCache.
The previous contents of pname:dstCache are included after the merge.
[NOTE]
.Note
====
The details of the merge operation are implementation dependent, but
implementations should: merge the contents of the specified pipelines and
prune duplicate entries.
====
.Valid Usage
****
* pname:dstCache must: not appear in the list of source caches
****
include::../validity/protos/vkMergePipelineCaches.txt[]
// refBegin vkGetPipelineCacheData Get the data store from a pipeline cache
Data can: be retrieved from a pipeline cache object using the command:
include::../api/protos/vkGetPipelineCacheData.txt[]
* pname:device is the logical device that owns the pipeline cache.
* pname:pipelineCache is the pipeline cache to retrieve data from.
* pname:pDataSize is a pointer to a value related to the amount of data in
the pipeline cache, as described below.
* pname:pData is either `NULL` or a pointer to a buffer.
If pname:pData is `NULL`, then the maximum size of the data that can: be
retrieved from the pipeline cache, in bytes, is returned in pname:pDataSize.
Otherwise, pname:pDataSize must: point to a variable set by the user to the
size of the buffer, in bytes, pointed to by pname:pData, and on return the
variable is overwritten with the amount of data actually written to
pname:pData.
If pname:pDataSize is less than the maximum size that can: be retrieved by
the pipeline cache, at most pname:pDataSize bytes will be written to
pname:pData, and fname:vkGetPipelineCacheData will return
ename:VK_INCOMPLETE.
Any data written to pname:pData is valid and can: be provided as the
pname:pInitialData member of the sname:VkPipelineCacheCreateInfo structure
passed to fname:vkCreatePipelineCache.
Two calls to fname:vkGetPipelineCacheData with the same parameters must:
retrieve the same data unless a command that modifies the contents of the
cache is called between them.
[[pipelines-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 initial bytes written to pname:pData must:
be a header consisting of the following members:
.Layout for pipeline cache header version ename:VK_PIPELINE_CACHE_HEADER_VERSION_ONE
[width="85%",cols="8%,21%,71%",options="header"]
|====
| Offset | Size | Meaning
| 0 | 4 | length in bytes of the entire pipeline cache header
written as a stream of bytes, with the least
significant byte first
| 4 | 4 | a elink:VkPipelineCacheHeaderVersion value
written as a stream of bytes, with the least
significant byte first
| 8 | 4 | a vendor ID equal to
sname:VkPhysicalDeviceProperties::pname:vendorID
written as a stream of bytes, with the least
significant byte first
| 12 | 4 | a device ID equal to
sname:VkPhysicalDeviceProperties::pname:deviceID
written as a stream of bytes, with the least
significant byte first
| 16 | ename:VK_UUID_SIZE | a pipeline cache ID equal to
sname:VkPhysicalDeviceProperties::pname:pipelineCacheUUID
|====
The first four bytes encode the length of the entire pipeline header, in
bytes.
This value includes all fields in the header including the pipeline cache
version field and the size of the length field.
// refBegin VkPipelineCacheHeaderVersion Encode pipeline cache version
The next four bytes encode the pipeline cache version.
This field is interpreted as a elink:VkPipelineCacheHeaderVersion value, and
must: have one of the following values:
include::../api/enums/VkPipelineCacheHeaderVersion.txt[]
A consumer of the pipeline cache should: use the cache version to interpret
the remainder of the cache header.
// refEnd VkPipelineCacheHeaderVersion vkCreatePipelineCache vkGetPipelineCacheData
If pname:pDataSize is less than what is necessary to store this header,
nothing will be written to pname:pData and zero will be written to
pname:pDataSize.
include::../validity/protos/vkGetPipelineCacheData.txt[]
// refBegin vkDestroyPipelineCache Destroy a pipeline cache object
To destroy a pipeline cache, call:
include::../api/protos/vkDestroyPipelineCache.txt[]
* pname:device is the logical device that destroys the pipeline cache
object.
* pname:pipelineCache is the handle of the pipeline cache to destroy.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
.Valid Usage
****
* If sname:VkAllocationCallbacks were provided when pname:pipelineCache
was created, a compatible set of callbacks must: be provided here
* If no sname:VkAllocationCallbacks were provided when pname:pipelineCache
was created, pname:pAllocator must: be `NULL`
****
include::../validity/protos/vkDestroyPipelineCache.txt[]
[[pipelines-specialization-constants]]
== Specialization Constants
Specialization constants are a mechanism whereby constants in a SPIR-V
module can: have their constant value specified at the time the
sname: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]
.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 instance of the sname:VkPipelineShaderStageCreateInfo structure
contains a parameter pname:pSpecializationInfo, which can: be `NULL` to
indicate no specialization constants, or point to a
sname:VkSpecializationInfo structure.
// refBegin VkSpecializationInfo Structure specifying specialization info
The sname:VkSpecializationInfo structure is defined as:
include::../api/structs/VkSpecializationInfo.txt[]
* pname:mapEntryCount is the number of entries in the pname:pMapEntries
array.
* pname:pMapEntries is a pointer to an array of
sname:VkSpecializationMapEntry which maps constant IDs to offsets in
pname:pData.
* pname:dataSize is the byte size of the pname:pData buffer.
* pname:pData contains the actual constant values to specialize with.
pname:pMapEntries points to a structure of type
slink:VkSpecializationMapEntry.
.Valid Usage
****
* The pname:offset member of any given element of pname:pMapEntries must:
be less than pname:dataSize
* For any given element of pname:pMapEntries, pname:size must: be less
than or equal to pname:dataSize minus pname:offset
* If pname:mapEntryCount is not `0`, pname:pMapEntries must: be a pointer
to an array of pname:mapEntryCount valid sname:VkSpecializationMapEntry
structures
****
include::../validity/structs/VkSpecializationInfo.txt[]
// refBegin VkSpecializationMapEntry Structure specifying a specialization map entry
The sname:VkSpecializationMapEntry structure is defined as:
include::../api/structs/VkSpecializationMapEntry.txt[]
* pname:constantID is the ID of the specialization constant in SPIR-V.
* pname:offset is the byte offset of the specialization constant value
within the supplied data buffer.
* pname:size is the byte size of the specialization constant value within
the supplied data buffer.
If a pname:constantID value is not a specialization constant ID used in the
shader, that map entry does not affect the behavior of the pipeline.
.Valid Usage
****
* For a pname:constantID specialization constant declared in a shader,
pname:size must: match the byte size of the pname:constantID.
If the specialization constant is of type code:boolean, pname:size must:
be the byte size of basetype:VkBool32
****
include::../validity/structs/VkSpecializationMapEntry.txt[]
In human readable SPIR-V:
[source,glsl]
---------------------------------------------------
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:
[source,c++]
---------------------------------------------------
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 flink:vkCreateComputePipelines, and passing the
sname:VkSpecializationInfo we defined as the pname:pSpecializationInfo
parameter of slink: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:
// [source,glsl]
[source,glsl]
---------------------------------------------------
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.
Now to specialize the above via the specialization constants mechanism:
[source,c++]
---------------------------------------------------
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 info 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.
[[pipelines-binding]]
== Pipeline Binding
// refBegin vkCmdBindPipeline Bind a pipeline object to a command buffer
Once a pipeline has been created, it can: be bound to the command buffer
using the command:
include::../api/protos/vkCmdBindPipeline.txt[]
* pname:commandBuffer is the command buffer that the pipeline will be
bound to.
* pname:pipelineBindPoint specifies the bind point, and must: have one of
the values
+
--
// refBegin VkPipelineBindPoint Specify the bind point of a pipeline object to a command buffer
include::../api/enums/VkPipelineBindPoint.txt[]
--
+
specifying whether pname:pipeline will be bound as a compute
(ename:VK_PIPELINE_BIND_POINT_COMPUTE) or graphics
(ename:VK_PIPELINE_BIND_POINT_GRAPHICS) pipeline.
There are separate bind points for each of graphics and compute, so binding
one does not disturb the other.
+
* pname:pipeline is the pipeline to be bound.
Once bound, a pipeline binding affects subsequent graphics or compute
commands in the command buffer until a different pipeline is bound to the
bind point.
The pipeline bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE controls the
behavior of flink:vkCmdDispatch and flink:vkCmdDispatchIndirect.
The pipeline bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS controls the
behavior of flink:vkCmdDraw, flink:vkCmdDrawIndexed,
flink:vkCmdDrawIndirect, and flink:vkCmdDrawIndexedIndirect.
No other commands are affected by the pipeline state.
.Valid Usage
****
* If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_COMPUTE, the
sname:VkCommandPool that pname:commandBuffer was allocated from must:
support compute operations
* If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_GRAPHICS, the
sname:VkCommandPool that pname:commandBuffer was allocated from must:
support graphics operations
* If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_COMPUTE,
pname:pipeline must: be a compute pipeline
* If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_GRAPHICS,
pname:pipeline must: be a graphics pipeline
* If the <<features-features-variableMultisampleRate,variable multisample
rate>> feature is not supported, pname:pipeline is a graphics pipeline,
the current subpass has no attachments, and this is not the first call
to this function with a graphics pipeline after transitioning to the
current subpass, then the sample count specified by this pipeline must:
match that set in the previous pipeline
****
include::../validity/protos/vkCmdBindPipeline.txt[]