1951 lines
80 KiB
Plaintext
1951 lines
80 KiB
Plaintext
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
|
// Copyright notice at https://www.khronos.org/registry/speccopyright.html
|
|
|
|
[[descriptorsets]]
|
|
= Resource Descriptors
|
|
|
|
Shaders access buffer and image resources by using special shader variables
|
|
which are indirectly bound to buffer and image views via the API.
|
|
These variables are organized into sets, where each set of bindings is
|
|
represented by a _descriptor set_ object in the API and a descriptor set is
|
|
bound all at once.
|
|
A _descriptor_ is an opaque data structure representing a shader resource
|
|
such as a buffer view, image view, sampler, or combined image sampler.
|
|
The content of each set is determined by its _descriptor set layout_ and the
|
|
sequence of set layouts that can: be used by resource variables in shaders
|
|
within a pipeline is specified in a _pipeline layout_.
|
|
|
|
Each shader can: use up to pname:maxBoundDescriptorSets (see
|
|
<<features-limits, Limits>>) descriptor sets, and each descriptor set can:
|
|
include bindings for descriptors of all descriptor types.
|
|
Each shader resource variable is assigned a tuple of (set number, binding
|
|
number, array element) that defines its location within a descriptor set
|
|
layout.
|
|
In GLSL, the set number and binding number are assigned via layout
|
|
qualifiers, and the array element is implicitly assigned consecutively
|
|
starting with index equal to zero for the first element of an array (and
|
|
array element is zero for non-array variables):
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
// Assign set number = M, binding number = N, array element = 0
|
|
layout (set=M, binding=N) uniform sampler2D variableName;
|
|
|
|
// Assign set number = M, binding number = N for all array elements, and
|
|
// array element = I for the I'th member of the array.
|
|
layout (set=M, binding=N) uniform sampler2D variableNameArray[I];
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
// Assign set number = M, binding number = N, array element = 0
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %10 "variableName"
|
|
OpDecorate %10 DescriptorSet M
|
|
OpDecorate %10 Binding N
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 2D 0 0 0 1 Unknown
|
|
%8 = OpTypeSampledImage %7
|
|
%9 = OpTypePointer UniformConstant %8
|
|
%10 = OpVariable %9 UniformConstant
|
|
...
|
|
|
|
// Assign set number = M, binding number = N for all array elements, and
|
|
// array element = I for the I'th member of the array.
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %13 "variableNameArray"
|
|
OpDecorate %13 DescriptorSet M
|
|
OpDecorate %13 Binding N
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 2D 0 0 0 1 Unknown
|
|
%8 = OpTypeSampledImage %7
|
|
%9 = OpTypeInt 32 0
|
|
%10 = OpConstant %9 I
|
|
%11 = OpTypeArray %8 %10
|
|
%12 = OpTypePointer UniformConstant %11
|
|
%13 = OpVariable %12 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-types]]
|
|
== Descriptor Types
|
|
|
|
The following sections outline the various descriptor types supported by
|
|
Vulkan.
|
|
Each section defines a descriptor type, and each descriptor type has a
|
|
manifestation in the shading language and SPIR-V as well as in descriptor
|
|
sets.
|
|
There is mostly a one-to-one correspondence between descriptor types and
|
|
classes of opaque types in the shading language, where the opaque types in
|
|
the shading language must: refer to a descriptor in the pipeline layout of
|
|
the corresponding descriptor type.
|
|
But there is an exception to this rule as described in
|
|
<<descriptorsets-combinedimagesampler,Combined Image Sampler>>.
|
|
|
|
|
|
[[descriptorsets-storageimage]]
|
|
=== Storage Image
|
|
|
|
A _storage image_ (ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) is a descriptor
|
|
type that is used for load, store, and atomic operations on image memory
|
|
from within shaders bound to pipelines.
|
|
|
|
Loads from storage images do not use samplers and are unfiltered and do not
|
|
support coordinate wrapping or clamping.
|
|
Loads are supported in all shader stages for image formats which report
|
|
support for the
|
|
<<features-formats-properties,ename:VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT>>
|
|
feature bit via flink:vkGetPhysicalDeviceFormatProperties.
|
|
|
|
Stores to storage images are supported in compute shaders for image formats
|
|
which report support for the ename:VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
|
|
feature.
|
|
|
|
Storage images also support atomic operations in compute shaders for image
|
|
formats which report support for the
|
|
<<features-formats-properties,ename:VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT>>
|
|
feature.
|
|
|
|
Load and store operations on storage images can: only be done on images in
|
|
ename:VK_IMAGE_LAYOUT_GENERAL layout.
|
|
|
|
When the <<features-features-fragmentStoresAndAtomics,
|
|
pname:fragmentStoresAndAtomics>> feature is enabled, stores and atomic
|
|
operations are also supported for storage images in fragment shaders with
|
|
the same set of image formats as supported in compute shaders.
|
|
When the <<features-features-vertexPipelineStoresAndAtomics,
|
|
pname:vertexPipelineStoresAndAtomics>> feature is enabled, stores and atomic
|
|
operations are also supported in vertex, tessellation, and geometry shaders
|
|
with the same set of image formats as supported in compute shaders.
|
|
|
|
Storage image declarations must: specify the image format in the shader if
|
|
the variable is used for atomic operations.
|
|
|
|
If the <<features-features-shaderStorageImageReadWithoutFormat,
|
|
pname:shaderStorageImageReadWithoutFormat>> feature is not enabled, storage
|
|
image declarations must: specify the image format in the shader if the
|
|
variable is used for load operations.
|
|
|
|
If the <<features-features-shaderStorageImageWriteWithoutFormat,
|
|
pname:shaderStorageImageWriteWithoutFormat>> feature is not enabled, storage
|
|
image declarations must: specify the image format in the shader if the
|
|
variable is used for store operations.
|
|
|
|
Storage images are declared in GLSL shader source using uniform code:image
|
|
variables of the appropriate dimensionality as well as a format layout
|
|
qualifier (if necessary):
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n, r32f) uniform image2D myStorageImage;
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %9 "myStorageImage"
|
|
OpDecorate %9 DescriptorSet m
|
|
OpDecorate %9 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 2D 0 0 0 2 R32f
|
|
%8 = OpTypePointer UniformConstant %7
|
|
%9 = OpVariable %8 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-sampler]]
|
|
=== Sampler
|
|
A _sampler_ (ename:VK_DESCRIPTOR_TYPE_SAMPLER) represents a set of
|
|
parameters which control address calculations, filtering behavior, and other
|
|
properties, that can: be used to perform filtered loads from _sampled
|
|
images_ (see <<descriptorsets-sampledimage, Sampled Image>>).
|
|
|
|
Samplers are declared in GLSL shader source using uniform code:sampler
|
|
variables, where the sampler type has no associated texture dimensionality:
|
|
|
|
.GLSL Example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n) uniform sampler mySampler;
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V Example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %8 "mySampler"
|
|
OpDecorate %8 DescriptorSet m
|
|
OpDecorate %8 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeSampler
|
|
%7 = OpTypePointer UniformConstant %6
|
|
%8 = OpVariable %7 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-sampledimage]]
|
|
=== Sampled Image
|
|
|
|
A _sampled image_ (ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) can: be used
|
|
(usually in conjunction with a sampler) to retrieve sampled image data.
|
|
Shaders use a sampled image handle and a sampler handle to sample data,
|
|
where the image handle generally defines the shape and format of the memory
|
|
and the sampler generally defines how coordinate addressing is performed.
|
|
The same sampler can: be used to sample from multiple images, and it is
|
|
possible to sample from the same sampled image with multiple samplers, each
|
|
containing a different set of sampling parameters.
|
|
|
|
Sampled images are declared in GLSL shader source using uniform code:texture
|
|
variables of the appropriate dimensionality:
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n) uniform texture2D mySampledImage;
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %9 "mySampledImage"
|
|
OpDecorate %9 DescriptorSet m
|
|
OpDecorate %9 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 2D 0 0 0 1 Unknown
|
|
%8 = OpTypePointer UniformConstant %7
|
|
%9 = OpVariable %8 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-combinedimagesampler]]
|
|
=== Combined Image Sampler
|
|
|
|
A _combined image sampler_ (ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
|
represents a sampled image along with a set of sampling parameters.
|
|
It is logically considered a sampled image and a sampler bound together.
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
On some implementations, it may: be more efficient to sample from an image
|
|
using a combination of sampler and sampled image that are stored together in
|
|
the descriptor set in a combined descriptor.
|
|
====
|
|
|
|
Combined image samplers are declared in GLSL shader source using uniform
|
|
code:sampler variables of the appropriate dimensionality:
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n) uniform sampler2D myCombinedImageSampler;
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %10 "myCombinedImageSampler"
|
|
OpDecorate %10 DescriptorSet m
|
|
OpDecorate %10 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 2D 0 0 0 1 Unknown
|
|
%8 = OpTypeSampledImage %7
|
|
%9 = OpTypePointer UniformConstant %8
|
|
%10 = OpVariable %9 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor set entries can:
|
|
also be accessed via separate sampler and sampled image shader variables.
|
|
Such variables refer exclusively to the corresponding half of the
|
|
descriptor, and can: be combined in the shader with samplers or sampled
|
|
images that can: come from the same descriptor or from other combined or
|
|
separate descriptor types.
|
|
There are no additional restrictions on how a separate sampler or sampled
|
|
image variable is used due to it originating from a combined descriptor.
|
|
|
|
|
|
[[descriptorsets-uniformtexelbuffer]]
|
|
=== Uniform Texel Buffer
|
|
|
|
A _uniform texel buffer_ (ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
|
|
represents a tightly packed array of homogeneous formatted data that is
|
|
stored in a buffer and is made accessible to shaders.
|
|
Uniform texel buffers are read-only.
|
|
|
|
Uniform texel buffers are declared in GLSL shader source using uniform
|
|
code:samplerBuffer variables:
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n) uniform samplerBuffer myUniformTexelBuffer;
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %10 "myUniformTexelBuffer"
|
|
OpDecorate %10 DescriptorSet m
|
|
OpDecorate %10 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 Buffer 0 0 0 1 Unknown
|
|
%8 = OpTypeSampledImage %7
|
|
%9 = OpTypePointer UniformConstant %8
|
|
%10 = OpVariable %9 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-storagetexelbuffer]]
|
|
=== Storage Texel Buffer
|
|
|
|
A _storage texel buffer_ (ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
|
represents a tightly packed array of homogeneous formatted data that is
|
|
stored in a buffer and is made accessible to shaders.
|
|
Storage texel buffers differ from uniform texel buffers in that they support
|
|
stores and atomic operations in shaders, may: support a different maximum
|
|
length, and may: have different performance characteristics.
|
|
|
|
Storage texel buffers are declared in GLSL shader source using uniform
|
|
code:imageBuffer variables:
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n, r32f) uniform imageBuffer myStorageTexelBuffer;
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %9 "myStorageTexelBuffer"
|
|
OpDecorate %9 DescriptorSet m
|
|
OpDecorate %9 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 Buffer 0 0 0 2 R32f
|
|
%8 = OpTypePointer UniformConstant %7
|
|
%9 = OpVariable %8 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-uniformbuffer]]
|
|
=== Uniform Buffer
|
|
|
|
A _uniform buffer_ (ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) is a region of
|
|
structured storage that is made accessible for read-only access to shaders.
|
|
It is typically used to store medium sized arrays of constants such as
|
|
shader parameters, matrices and other related data.
|
|
|
|
Uniform buffers are declared in GLSL shader source using the uniform storage
|
|
qualifier and block syntax:
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n) uniform myUniformBuffer
|
|
{
|
|
vec4 myElement[32];
|
|
};
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %11 "myUniformBuffer"
|
|
OpMemberName %11 0 "myElement"
|
|
OpName %13 ""
|
|
OpDecorate %10 ArrayStride 16
|
|
OpMemberDecorate %11 0 Offset 0
|
|
OpDecorate %11 Block
|
|
OpDecorate %13 DescriptorSet m
|
|
OpDecorate %13 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeVector %6 4
|
|
%8 = OpTypeInt 32 0
|
|
%9 = OpConstant %8 32
|
|
%10 = OpTypeArray %7 %9
|
|
%11 = OpTypeStruct %10
|
|
%12 = OpTypePointer Uniform %11
|
|
%13 = OpVariable %12 Uniform
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-storagebuffer]]
|
|
=== Storage Buffer
|
|
|
|
A _storage buffer_ (ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) is a region of
|
|
structured storage that supports both read and write access for shaders.
|
|
In addition to general read and write operations, some members of storage
|
|
buffers can: be used as the target of atomic operations.
|
|
In general, atomic operations are only supported on members that have
|
|
unsigned integer formats.
|
|
|
|
Storage buffers are declared in GLSL shader source using buffer storage
|
|
qualifier and block syntax:
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (set=m, binding=n) buffer myStorageBuffer
|
|
{
|
|
vec4 myElement[];
|
|
};
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %9 "myStorageBuffer"
|
|
OpMemberName %9 0 "myElement"
|
|
OpName %11 ""
|
|
OpDecorate %8 ArrayStride 16
|
|
OpMemberDecorate %9 0 Offset 0
|
|
OpDecorate %9 BufferBlock
|
|
OpDecorate %11 DescriptorSet m
|
|
OpDecorate %11 Binding n
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeVector %6 4
|
|
%8 = OpTypeRuntimeArray %7
|
|
%9 = OpTypeStruct %8
|
|
%10 = OpTypePointer Uniform %9
|
|
%11 = OpVariable %10 Uniform
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-uniformbufferdynamic]]
|
|
=== Dynamic Uniform Buffer
|
|
|
|
A _dynamic uniform buffer_ (ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
|
|
differs from a uniform buffer only in how its address and length are
|
|
specified.
|
|
Uniform buffers bind a buffer address and length that is specified in the
|
|
descriptor set update by a buffer handle, offset and range (see
|
|
<<descriptorsets-updates, Descriptor Set Updates>>).
|
|
With dynamic uniform buffers the buffer handle, offset and range specified
|
|
in the descriptor set define the base address and length.
|
|
The dynamic offset which is relative to this base address is taken from the
|
|
pname:pDynamicOffsets parameter to flink:vkCmdBindDescriptorSets (see
|
|
<<descriptorsets-binding, Descriptor Set Binding>>).
|
|
The address used for a dynamic uniform buffer is the sum of the buffer base
|
|
address and the relative offset.
|
|
The length is unmodified and remains the range as specified in the
|
|
descriptor update.
|
|
The shader syntax is identical for uniform buffers and dynamic uniform
|
|
buffers.
|
|
|
|
|
|
[[descriptorsets-storagebufferdynamic]]
|
|
=== Dynamic Storage Buffer
|
|
|
|
A _dynamic storage buffer_ (ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
|
|
differs from a storage buffer only in how its address and length are
|
|
specified.
|
|
The difference is identical to the difference between uniform buffers and
|
|
dynamic uniform buffers (see <<descriptorsets-uniformbufferdynamic, Dynamic
|
|
Uniform Buffer>>).
|
|
The shader syntax is identical for storage buffers and dynamic storage
|
|
buffers.
|
|
|
|
|
|
[[descriptorsets-inputattachment]]
|
|
=== Input Attachment
|
|
|
|
An _input attachment_ (ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) is an
|
|
image view that can: be used for pixel local load operations from within
|
|
fragment shaders bound to pipelines.
|
|
Loads from input attachments are unfiltered.
|
|
All image formats that are supported for color attachments
|
|
(ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) or depth/stencil attachments
|
|
(ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) for a given image
|
|
tiling mode are also supported for input attachments.
|
|
|
|
In the shader, input attachments must: be decorated with their input
|
|
attachment index in addition to descriptor set and binding numbers.
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
layout (input_attachment_index=i, set=m, binding=n) uniform subpassInput myInputAttachment;
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %9 "myInputAttachment"
|
|
OpDecorate %9 DescriptorSet m
|
|
OpDecorate %9 Binding n
|
|
OpDecorate %9 InputAttachmentIndex i
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 SubpassData 0 0 0 2 Unknown
|
|
%8 = OpTypePointer UniformConstant %7
|
|
%9 = OpVariable %8 UniformConstant
|
|
...
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-sets]]
|
|
== Descriptor Sets
|
|
|
|
Descriptors are grouped together into descriptor set objects.
|
|
A descriptor set object is an opaque object that contains storage for a set
|
|
of descriptors, where the types and number of descriptors is defined by a
|
|
descriptor set layout.
|
|
The layout object may: be used to define the association of each descriptor
|
|
binding with memory or other hardware resources.
|
|
The layout is used both for determining the resources that need to be
|
|
associated with the descriptor set, and determining the interface between
|
|
shader stages and shader resources.
|
|
|
|
|
|
[[descriptorsets-setlayout]]
|
|
=== Descriptor Set Layout
|
|
|
|
// refBegin VkDescriptorSetLayout Opaque handle to a descriptor set layout object
|
|
|
|
A descriptor set layout object is defined by an array of zero or more
|
|
descriptor bindings.
|
|
Each individual descriptor binding is specified by a descriptor type, a
|
|
count (array size) of the number of descriptors in the binding, a set of
|
|
shader stages that can: access the binding, and (if using immutable
|
|
samplers) an array of sampler descriptors.
|
|
|
|
Descriptor set layout objects are represented by sname:VkDescriptorSetLayout
|
|
handles:
|
|
|
|
include::../api/handles/VkDescriptorSetLayout.txt[]
|
|
|
|
// refEnd VkDescriptorSetLayout
|
|
|
|
// refBegin vkCreateDescriptorSetLayout Create a new descriptor set layout
|
|
|
|
To create descriptor set layout objects, call:
|
|
|
|
include::../api/protos/vkCreateDescriptorSetLayout.txt[]
|
|
|
|
* pname:device is the logical device that creates the descriptor set
|
|
layout.
|
|
* pname:pCreateInfo is a pointer to an instance of the
|
|
slink:VkDescriptorSetLayoutCreateInfo structure specifying the state of
|
|
the descriptor set layout object.
|
|
* pname:pAllocator controls host memory allocation as described in the
|
|
<<memory-allocation, Memory Allocation>> chapter.
|
|
* pname:pSetLayout points to a sname:VkDescriptorSetLayout handle in which
|
|
the resulting descriptor set layout object is returned.
|
|
|
|
include::../validity/protos/vkCreateDescriptorSetLayout.txt[]
|
|
|
|
// refBegin VkDescriptorSetLayoutCreateInfo Structure specifying parameters of a newly created descriptor set layout
|
|
|
|
Information about the descriptor set layout is passed in an instance of the
|
|
sname:VkDescriptorSetLayoutCreateInfo structure:
|
|
|
|
include::../api/structs/VkDescriptorSetLayoutCreateInfo.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:bindingCount is the number of elements in pname:pBindings.
|
|
* pname:pBindings is a pointer to an array of
|
|
slink:VkDescriptorSetLayoutBinding structures.
|
|
|
|
.Valid Usage
|
|
****
|
|
* The slink:VkDescriptorSetLayoutBinding::pname:binding members of the
|
|
elements of the pname:pBindings array must: each have different values.
|
|
****
|
|
|
|
include::../validity/structs/VkDescriptorSetLayoutCreateInfo.txt[]
|
|
|
|
// refBegin VkDescriptorSetLayoutBinding Structure specifying a descriptor set layout binding
|
|
|
|
The sname:VkDescriptorSetLayoutBinding structure is defined as:
|
|
|
|
include::../api/structs/VkDescriptorSetLayoutBinding.txt[]
|
|
|
|
* pname:binding is the binding number of this entry and corresponds to a
|
|
resource of the same binding number in the shader stages.
|
|
* pname:descriptorType is a elink:VkDescriptorType specifying which type
|
|
of resource descriptors are used for this binding.
|
|
* pname:descriptorCount is the number of descriptors contained in the
|
|
binding, accessed in a shader as an array.
|
|
If pname:descriptorCount is zero this binding entry is reserved and the
|
|
resource must: not be accessed from any stage via this binding within
|
|
any pipeline using the set layout.
|
|
* pname:stageFlags member is a bitmask of elink:VkShaderStageFlagBits
|
|
specifying which pipeline shader stages can: access a resource for this
|
|
binding.
|
|
ename:VK_SHADER_STAGE_ALL is a shorthand specifying that all defined
|
|
shader stages, including any additional stages defined by extensions,
|
|
can: access the resource.
|
|
+
|
|
--
|
|
If a shader stage is not included in pname:stageFlags, then a resource must:
|
|
not be accessed from that stage via this binding within any pipeline using
|
|
the set layout.
|
|
There are no limitations on what combinations of stages can: be used by a
|
|
descriptor binding, and in particular a binding can: be used by both
|
|
graphics stages and the compute stage.
|
|
--
|
|
* pname:pImmutableSamplers affects initialization of samplers.
|
|
If pname:descriptorType specifies a ename:VK_DESCRIPTOR_TYPE_SAMPLER or
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER type descriptor, then
|
|
pname:pImmutableSamplers can: be used to initialize a set of _immutable
|
|
samplers_.
|
|
Immutable samplers are permanently bound into the set layout; later
|
|
binding a sampler into an immutable sampler slot in a descriptor set is
|
|
not allowed.
|
|
If pname:pImmutableSamplers is not `NULL`, then it is considered to be a
|
|
pointer to an array of sampler handles that will be consumed by the set
|
|
layout and used for the corresponding binding.
|
|
If pname:pImmutableSamplers is `NULL`, then the sampler slots are
|
|
dynamic and sampler handles must: be bound into descriptor sets using
|
|
this layout.
|
|
If pname:descriptorType is not one of these descriptor types, then
|
|
pname:pImmutableSamplers is ignored.
|
|
|
|
The above layout definition allows the descriptor bindings to be specified
|
|
sparsely such that not all binding numbers between 0 and the maximum binding
|
|
number need to be specified in the pname:pBindings array.
|
|
Bindings that are not specified have a pname:descriptorCount and
|
|
pname:stageFlags of zero, and the pname:descriptorType is treated as
|
|
undefined.
|
|
However, all binding numbers between 0 and the maximum binding number in the
|
|
slink:VkDescriptorSetLayoutCreateInfo::pname:pBindings array may: consume
|
|
memory in the descriptor set layout even if not all descriptor bindings are
|
|
used, though it should: not consume additional memory from the descriptor
|
|
pool.
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
The maximum binding number specified should: be as compact as possible to
|
|
avoid wasted memory.
|
|
====
|
|
|
|
.Valid Usage
|
|
****
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_SAMPLER or
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and
|
|
pname:descriptorCount is not `0` and pname:pImmutableSamplers is not
|
|
`NULL`, pname:pImmutableSamplers must: be a pointer to an array of
|
|
pname:descriptorCount valid sname:VkSampler handles
|
|
* If pname:descriptorCount is not `0`, pname:stageFlags must: be a valid
|
|
combination of elink:VkShaderStageFlagBits values
|
|
****
|
|
|
|
include::../validity/structs/VkDescriptorSetLayoutBinding.txt[]
|
|
|
|
The following examples show a shader snippet using two descriptor sets, and
|
|
application code that creates corresponding descriptor set layouts.
|
|
|
|
.GLSL example
|
|
[source,{basebackend@docbook:c:glsl}]
|
|
---------------------------------------------------
|
|
//
|
|
// binding to a single sampled image descriptor in set 0
|
|
//
|
|
layout (set=0, binding=0) uniform texture2D mySampledImage;
|
|
|
|
//
|
|
// binding to an array of sampled image descriptors in set 0
|
|
//
|
|
layout (set=0, binding=1) uniform texture2D myArrayOfSampledImages[12];
|
|
|
|
//
|
|
// binding to a single uniform buffer descriptor in set 1
|
|
//
|
|
layout (set=1, binding=0) uniform myUniformBuffer
|
|
{
|
|
vec4 myElement[32];
|
|
};
|
|
---------------------------------------------------
|
|
|
|
.SPIR-V example
|
|
---------------------------------------------------
|
|
...
|
|
%1 = OpExtInstImport "GLSL.std.450"
|
|
...
|
|
OpName %9 "mySampledImage"
|
|
OpName %14 "myArrayOfSampledImages"
|
|
OpName %18 "myUniformBuffer"
|
|
OpMemberName %18 0 "myElement"
|
|
OpName %20 ""
|
|
OpDecorate %9 DescriptorSet 0
|
|
OpDecorate %9 Binding 0
|
|
OpDecorate %14 DescriptorSet 0
|
|
OpDecorate %14 Binding 1
|
|
OpDecorate %17 ArrayStride 16
|
|
OpMemberDecorate %18 0 Offset 0
|
|
OpDecorate %18 Block
|
|
OpDecorate %20 DescriptorSet 1
|
|
OpDecorate %20 Binding 0
|
|
%2 = OpTypeVoid
|
|
%3 = OpTypeFunction %2
|
|
%6 = OpTypeFloat 32
|
|
%7 = OpTypeImage %6 2D 0 0 0 1 Unknown
|
|
%8 = OpTypePointer UniformConstant %7
|
|
%9 = OpVariable %8 UniformConstant
|
|
%10 = OpTypeInt 32 0
|
|
%11 = OpConstant %10 12
|
|
%12 = OpTypeArray %7 %11
|
|
%13 = OpTypePointer UniformConstant %12
|
|
%14 = OpVariable %13 UniformConstant
|
|
%15 = OpTypeVector %6 4
|
|
%16 = OpConstant %10 32
|
|
%17 = OpTypeArray %15 %16
|
|
%18 = OpTypeStruct %17
|
|
%19 = OpTypePointer Uniform %18
|
|
%20 = OpVariable %19 Uniform
|
|
...
|
|
---------------------------------------------------
|
|
|
|
.API example
|
|
[source,{basebackend@docbook:c++:cpp}]
|
|
-------------------------------------------------------------------------------
|
|
VkResult myResult;
|
|
|
|
const VkDescriptorSetLayoutBinding myDescriptorSetLayoutBinding[] =
|
|
{
|
|
// binding to a single image descriptor
|
|
{
|
|
0, // binding
|
|
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
|
|
1, // descriptorCount
|
|
VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags
|
|
NULL // pImmutableSamplers
|
|
},
|
|
|
|
// binding to an array of image descriptors
|
|
{
|
|
1, // binding
|
|
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
|
|
12, // descriptorCount
|
|
VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags
|
|
NULL // pImmutableSamplers
|
|
},
|
|
|
|
// binding to a single uniform buffer descriptor
|
|
{
|
|
0, // binding
|
|
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // descriptorType
|
|
1, // descriptorCount
|
|
VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags
|
|
NULL // pImmutableSamplers
|
|
}
|
|
};
|
|
|
|
const VkDescriptorSetLayoutCreateInfo myDescriptorSetLayoutCreateInfo[] =
|
|
{
|
|
// Create info for first descriptor set with two descriptor bindings
|
|
{
|
|
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
|
|
NULL, // pNext
|
|
0, // flags
|
|
2, // bindingCount
|
|
&myDescriptorSetLayoutBinding[0] // pBindings
|
|
},
|
|
|
|
// Create info for second descriptor set with one descriptor binding
|
|
{
|
|
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
|
|
NULL, // pNext
|
|
0, // flags
|
|
1, // bindingCount
|
|
&myDescriptorSetLayoutBinding[2] // pBindings
|
|
}
|
|
};
|
|
|
|
VkDescriptorSetLayout myDescriptorSetLayout[2];
|
|
|
|
//
|
|
// Create first descriptor set layout
|
|
//
|
|
myResult = vkCreateDescriptorSetLayout(
|
|
myDevice,
|
|
&myDescriptorSetLayoutCreateInfo[0],
|
|
NULL,
|
|
&myDescriptorSetLayout[0]);
|
|
|
|
//
|
|
// Create second descriptor set layout
|
|
//
|
|
myResult = vkCreateDescriptorSetLayout(
|
|
myDevice,
|
|
&myDescriptorSetLayoutCreateInfo[1],
|
|
NULL,
|
|
&myDescriptorSetLayout[1]);
|
|
-------------------------------------------------------------------------------
|
|
|
|
// refBegin vkDestroyDescriptorSetLayout Destroy a descriptor set layout object
|
|
|
|
To destroy a descriptor set layout, call:
|
|
|
|
include::../api/protos/vkDestroyDescriptorSetLayout.txt[]
|
|
|
|
* pname:device is the logical device that destroys the descriptor set
|
|
layout.
|
|
* pname:descriptorSetLayout is the descriptor set layout 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:descriptorSetLayout was created, a compatible set of callbacks
|
|
must: be provided here
|
|
* If no sname:VkAllocationCallbacks were provided when
|
|
pname:descriptorSetLayout was created, pname:pAllocator must: be `NULL`
|
|
****
|
|
|
|
include::../validity/protos/vkDestroyDescriptorSetLayout.txt[]
|
|
|
|
|
|
[[descriptorsets-pipelinelayout]]
|
|
=== Pipeline Layouts
|
|
|
|
// refBegin VkPipelineLayout Opaque handle to a pipeline layout object
|
|
|
|
Access to descriptor sets from a pipeline is accomplished through a
|
|
_pipeline layout_.
|
|
Zero or more descriptor set layouts and zero or more push constant ranges
|
|
are combined to form a pipeline layout object which describes the complete
|
|
set of resources that can: be accessed by a pipeline.
|
|
The pipeline layout represents a sequence of descriptor sets with each
|
|
having a specific layout.
|
|
This sequence of layouts is used to determine the interface between shader
|
|
stages and shader resources.
|
|
Each pipeline is created using a pipeline layout.
|
|
|
|
Pipeline layout objects are represented by sname:VkPipelineLayout handles:
|
|
|
|
include::../api/handles/VkPipelineLayout.txt[]
|
|
|
|
// refEnd VkPipelineLayout
|
|
|
|
// refBegin vkCreatePipelineLayout Creates a new pipeline layout object
|
|
|
|
To create a pipeline layout, call:
|
|
|
|
include::../api/protos/vkCreatePipelineLayout.txt[]
|
|
|
|
* pname:device is the logical device that creates the pipeline layout.
|
|
* pname:pCreateInfo is a pointer to an instance of the
|
|
slink:VkPipelineLayoutCreateInfo structure specifying the state of the
|
|
pipeline layout object.
|
|
* pname:pAllocator controls host memory allocation as described in the
|
|
<<memory-allocation, Memory Allocation>> chapter.
|
|
* pname:pPipelineLayout points to a sname:VkPipelineLayout handle in which
|
|
the resulting pipeline layout object is returned.
|
|
|
|
include::../validity/protos/vkCreatePipelineLayout.txt[]
|
|
|
|
// refBegin VkPipelineLayoutCreateInfo Structure specifying the parameters of a newly created pipeline layout object
|
|
|
|
The slink:VkPipelineLayoutCreateInfo structure is defined as:
|
|
|
|
include::../api/structs/VkPipelineLayoutCreateInfo.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:setLayoutCount is the number of descriptor sets included in the
|
|
pipeline layout.
|
|
* pname:pSetLayouts is a pointer to an array of
|
|
sname:VkDescriptorSetLayout objects.
|
|
* pname:pushConstantRangeCount is the number of push constant ranges
|
|
included in the pipeline layout.
|
|
* pname:pPushConstantRanges is a pointer to an array of
|
|
sname:VkPushConstantRange structures defining a set of push constant
|
|
ranges for use in a single pipeline layout.
|
|
In addition to descriptor set layouts, a pipeline layout also describes
|
|
how many push constants can: be accessed by each stage of the pipeline.
|
|
+
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
Push constants represent a high speed path to modify constant data in
|
|
pipelines that is expected to outperform memory-backed resource updates.
|
|
====
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:setLayoutCount must: be less than or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxBoundDescriptorSets
|
|
* The total number of descriptors of the type
|
|
ename:VK_DESCRIPTOR_TYPE_SAMPLER and
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any given
|
|
shader stage across all elements of pname:pSetLayouts must: be less than
|
|
or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorSamplers
|
|
* The total number of descriptors of the type
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER and
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible to any given
|
|
shader stage across all elements of pname:pSetLayouts must: be less than
|
|
or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorUniformBuffers
|
|
* The total number of descriptors of the type
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER and
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible to any given
|
|
shader stage across all elements of pname:pSetLayouts must: be less than
|
|
or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorStorageBuffers
|
|
* The total number of descriptors of the type
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible to any given
|
|
shader stage across all elements of pname:pSetLayouts must: be less than
|
|
or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorSampledImages
|
|
* The total number of descriptors of the type
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible to any given
|
|
shader stage across all elements of pname:pSetLayouts must: be less than
|
|
or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorStorageImages
|
|
* Any two elements of pname:pPushConstantRanges must: not include the same
|
|
stage in pname:stageFlags
|
|
****
|
|
|
|
include::../validity/structs/VkPipelineLayoutCreateInfo.txt[]
|
|
|
|
// refBegin VkPushConstantRange Structure specifying a push constant range
|
|
|
|
The sname:VkPushConstantRange structure is defined as:
|
|
|
|
include::../api/structs/VkPushConstantRange.txt[]
|
|
|
|
* pname:stageFlags is a set of stage flags describing the shader stages
|
|
that will access a range of push constants.
|
|
If a particular stage is not included in the range, then accessing
|
|
members of that range of push constants from the corresponding shader
|
|
stage will result in undefined data being read.
|
|
* pname:offset and pname:size are the start offset and size, respectively,
|
|
consumed by the range.
|
|
Both pname:offset and pname:size are in units of bytes and must: be a
|
|
multiple of 4.
|
|
The layout of the push constant variables is specified in the shader.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:offset must: be less than
|
|
sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize
|
|
* pname:offset must: be a multiple of `4`
|
|
* pname:size must: be greater than `0`
|
|
* pname:size must: be a multiple of `4`
|
|
* pname:size must: be less than or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize minus
|
|
pname:offset
|
|
****
|
|
|
|
include::../validity/structs/VkPushConstantRange.txt[]
|
|
|
|
Once created, pipeline layouts are used as part of pipeline creation (see
|
|
<<pipelines, Pipelines>>), as part of binding descriptor sets (see
|
|
<<descriptorsets-binding, Descriptor Set Binding>>), and as part of setting
|
|
push constants (see <<descriptorsets-push-constants, Push Constant
|
|
Updates>>).
|
|
Pipeline creation accepts a pipeline layout as input, and the layout may: be
|
|
used to map (set, binding, arrayElement) tuples to hardware resources or
|
|
memory locations within a descriptor set.
|
|
The assignment of hardware resources depends only on the bindings defined in
|
|
the descriptor sets that comprise the pipeline layout, and not on any shader
|
|
source.
|
|
|
|
[[descriptorsets-pipelinelayout-consistency]]
|
|
All resource variables <<shaders-staticuse,statically used>> in all shaders
|
|
in a pipeline must: be declared with a (set,binding,arrayElement) that
|
|
exists in the corresponding descriptor set layout and is of an appropriate
|
|
descriptor type and includes the set of shader stages it is used by in
|
|
pname:stageFlags.
|
|
The pipeline layout can: include entries that are not used by a particular
|
|
pipeline, or that are dead-code eliminated from any of the shaders.
|
|
The pipeline layout allows the application to provide a consistent set of
|
|
bindings across multiple pipeline compiles, which enables those pipelines to
|
|
be compiled in a way that the implementation may: cheaply switch pipelines
|
|
without reprogramming the bindings.
|
|
|
|
Similarly, the push constant block declared in each shader (if present)
|
|
must: only place variables at offsets that are each included in a push
|
|
constant range with pname:stageFlags including the bit corresponding to the
|
|
shader stage that uses it.
|
|
The pipeline layout can: include ranges or portions of ranges that are not
|
|
used by a particular pipeline, or for which the variables have been
|
|
dead-code eliminated from any of the shaders.
|
|
|
|
There is a limit on the total number of resources of each type that can: be
|
|
included in bindings in all descriptor set layouts in a pipeline layout as
|
|
shown in <<descriptorsets-pipelinelayout-limits,Pipeline Layout Resource
|
|
Limits>>.
|
|
The ``Total Resources Available'' column gives the limit on the number of
|
|
each type of resource that can: be included in bindings in all descriptor
|
|
sets in the pipeline layout.
|
|
Some resource types count against multiple limits.
|
|
Additionally, there are limits on the total number of each type of resource
|
|
that can: be used in any pipeline stage as described in
|
|
<<interfaces-resources-limits,Shader Resource Limits>>.
|
|
|
|
[[descriptorsets-pipelinelayout-limits]]
|
|
.Pipeline Layout Resource Limits
|
|
[width="80%",cols="<37,<22",options="header"]
|
|
|====
|
|
| Total Resources Available | Resource Types
|
|
.2+<.^| pname:maxDescriptorSetSamplers
|
|
| sampler | combined image sampler
|
|
.3+<.^| pname:maxDescriptorSetSampledImages
|
|
| sampled image | combined image sampler | uniform texel buffer
|
|
.2+<.^| pname:maxDescriptorSetStorageImages
|
|
| storage image | storage texel buffer
|
|
.2+<.^| pname:maxDescriptorSetUniformBuffers
|
|
| uniform buffer | uniform buffer dynamic
|
|
| pname:maxDescriptorSetUniformBuffersDynamic
|
|
| uniform buffer dynamic
|
|
.2+<.^| pname:maxDescriptorSetStorageBuffers
|
|
| storage buffer | storage buffer dynamic
|
|
| pname:maxDescriptorSetStorageBuffersDynamic
|
|
| storage buffer dynamic
|
|
| pname:maxDescriptorSetInputAttachments
|
|
| input attachment
|
|
|====
|
|
|
|
|
|
// refBegin vkDestroyPipelineLayout Destroy a pipeline layout object
|
|
|
|
To destroy a pipeline layout, call:
|
|
|
|
include::../api/protos/vkDestroyPipelineLayout.txt[]
|
|
|
|
* pname:device is the logical device that destroys the pipeline layout.
|
|
* pname:pipelineLayout is the pipeline layout 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:pipelineLayout
|
|
was created, a compatible set of callbacks must: be provided here
|
|
* If no sname:VkAllocationCallbacks were provided when
|
|
pname:pipelineLayout was created, pname:pAllocator must: be `NULL`
|
|
****
|
|
|
|
include::../validity/protos/vkDestroyPipelineLayout.txt[]
|
|
|
|
|
|
[[descriptorsets-compatibility]]
|
|
==== Pipeline Layout Compatibility
|
|
|
|
Two pipeline layouts are defined to be ``compatible for
|
|
<<descriptorsets-push-constants, push constants>>'' if they were created
|
|
with identical push constant ranges.
|
|
Two pipeline layouts are defined to be ``compatible for set N'' if they were
|
|
created with matching (the same, or identically defined) descriptor set
|
|
layouts for sets zero through N, and if they were created with identical
|
|
push constant ranges.
|
|
|
|
When binding a descriptor set (see <<descriptorsets-binding, Descriptor Set
|
|
Binding>>) to set number N, if the previously bound descriptor sets for sets
|
|
zero through N-1 were all bound using compatible pipeline layouts, then
|
|
performing this binding does not disturb any of the lower numbered sets.
|
|
If, additionally, the previous bound descriptor set for set N was bound
|
|
using a pipeline layout compatible for set N, then the bindings in sets
|
|
numbered greater than N are also not disturbed.
|
|
|
|
Similarly, when binding a pipeline, the pipeline can: correctly access any
|
|
previously bound descriptor sets which were bound with compatible pipeline
|
|
layouts, as long as all lower numbered sets were also bound with compatible
|
|
layouts.
|
|
|
|
Layout compatibility means that descriptor sets can: be bound to a command
|
|
buffer for use by any pipeline created with a compatible pipeline layout,
|
|
and without having bound a particular pipeline first.
|
|
It also means that descriptor sets can: remain valid across a pipeline
|
|
change, and the same resources will be accessible to the newly bound
|
|
pipeline.
|
|
|
|
ifdef::implementation-guide[]
|
|
.Implementor's Note
|
|
****
|
|
A consequence of layout compatibility is that when the implementation
|
|
compiles a pipeline layout and assigns hardware units to resources, the
|
|
mechanism to assign hardware units for set N should: only be a function of
|
|
sets [0..N].
|
|
****
|
|
endif::implementation-guide[]
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
Place the least frequently changing descriptor sets near the start of the
|
|
pipeline layout, and place the descriptor sets representing the most
|
|
frequently changing resources near the end.
|
|
When pipelines are switched, only the descriptor set bindings that have been
|
|
invalidated will need to be updated and the remainder of the descriptor set
|
|
bindings will remain in place.
|
|
====
|
|
|
|
The maximum number of descriptor sets that can: be bound to a pipeline
|
|
layout is queried from physical device properties (see
|
|
pname:maxBoundDescriptorSets in <<features-limits, Limits>>).
|
|
|
|
.API example
|
|
[source,{basebackend@docbook:c++:cpp}]
|
|
---------------------------------------------------
|
|
const VkDescriptorSetLayout layouts[] = { layout1, layout2 };
|
|
|
|
const VkPushConstantRange ranges[] =
|
|
{
|
|
{
|
|
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, // stageFlags
|
|
0, // offset
|
|
4 // size
|
|
},
|
|
|
|
{
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // stageFlags
|
|
4, // offset
|
|
4 // size
|
|
},
|
|
};
|
|
|
|
const VkPipelineLayoutCreateInfo createInfo =
|
|
{
|
|
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
|
|
NULL, // pNext
|
|
0, // flags
|
|
2, // setLayoutCount
|
|
layouts, // pSetLayouts
|
|
2, // pushConstantRangeCount
|
|
ranges // pPushConstantRanges
|
|
};
|
|
|
|
VkPipelineLayout myPipelineLayout;
|
|
myResult = vkCreatePipelineLayout(
|
|
myDevice,
|
|
&createInfo,
|
|
NULL,
|
|
&myPipelineLayout);
|
|
---------------------------------------------------
|
|
|
|
|
|
[[descriptorsets-allocation]]
|
|
=== Allocation of Descriptor Sets
|
|
|
|
// refBegin VkDescriptorPool Opaque handle to a descriptor pool object
|
|
|
|
A _descriptor pool_ maintains a pool of descriptors, from which descriptor
|
|
sets are allocated.
|
|
Descriptor pools are externally synchronized, meaning that the application
|
|
must: not allocate and/or free descriptor sets from the same pool in
|
|
multiple threads simultaneously.
|
|
|
|
Descriptor pools are represented by sname:VkDescriptorPool handles:
|
|
|
|
include::../api/handles/VkDescriptorPool.txt[]
|
|
|
|
// refEnd VkDescriptorPool
|
|
|
|
// refBegin vkCreateDescriptorPool Creates a descriptor pool object
|
|
|
|
To create a descriptor pool object, call:
|
|
|
|
include::../api/protos/vkCreateDescriptorPool.txt[]
|
|
|
|
* pname:device is the logical device that creates the descriptor pool.
|
|
* pname:pCreateInfo is a pointer to an instance of the
|
|
slink:VkDescriptorPoolCreateInfo structure specifying the state of the
|
|
descriptor pool object.
|
|
* pname:pAllocator controls host memory allocation as described in the
|
|
<<memory-allocation, Memory Allocation>> chapter.
|
|
* pname:pDescriptorPool points to a sname:VkDescriptorPool handle in which
|
|
the resulting descriptor pool object is returned.
|
|
|
|
pname:pAllocator controls host memory allocation as described in the
|
|
<<memory-allocation, Memory Allocation>> chapter.
|
|
|
|
The created descriptor pool is returned in pname:pDescriptorPool.
|
|
|
|
include::../validity/protos/vkCreateDescriptorPool.txt[]
|
|
|
|
// refBegin VkDescriptorPoolCreateInfo Structure specifying parameters of a newly created descriptor pool
|
|
|
|
Additional information about the pool is passed in an instance of the
|
|
sname:VkDescriptorPoolCreateInfo structure:
|
|
|
|
include::../api/structs/VkDescriptorPoolCreateInfo.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:flags specifies certain supported operations on the pool.
|
|
Bits which can: be set include:
|
|
+
|
|
--
|
|
// refBegin VkDescriptorPoolCreateFlagBits Bitmask specifying certain supported operations on a descriptor pool
|
|
include::../api/enums/VkDescriptorPoolCreateFlagBits.txt[]
|
|
--
|
|
+
|
|
If pname:flags includes
|
|
ename:VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, then descriptor
|
|
sets can: return their individual allocations to the pool, i.e. all of
|
|
fname:vkAllocateDescriptorSets, fname:vkFreeDescriptorSets, and
|
|
fname:vkResetDescriptorPool are allowed.
|
|
Otherwise, descriptor sets allocated from the pool must: not be individually
|
|
freed back to the pool, i.e. only fname:vkAllocateDescriptorSets and
|
|
fname:vkResetDescriptorPool are allowed.
|
|
+
|
|
* pname:maxSets is the maximum number of descriptor sets that can: be
|
|
allocated from the pool.
|
|
* pname:poolSizeCount is the number of elements in pname:pPoolSizes.
|
|
* pname:pPoolSizes is a pointer to an array of sname:VkDescriptorPoolSize
|
|
structures, each containing a descriptor type and number of descriptors
|
|
of that type to be allocated in the pool.
|
|
|
|
If multiple sname:VkDescriptorPoolSize structures appear in the
|
|
pname:pPoolSizes array then the pool will be created with enough storage for
|
|
the total number of descriptors of each type.
|
|
|
|
Fragmentation of a descriptor pool is possible and may: lead to descriptor
|
|
set allocation failures.
|
|
A failure due to fragmentation is defined as failing a descriptor set
|
|
allocation despite the sum of all outstanding descriptor set allocations
|
|
from the pool plus the requested allocation requiring no more than the total
|
|
number of descriptors requested at pool creation.
|
|
Implementations provide certain guarantees of when fragmentation must: not
|
|
cause allocation failure, as described below.
|
|
|
|
If a descriptor pool has not had any descriptor sets freed since it was
|
|
created or most recently reset then fragmentation must: not cause an
|
|
allocation failure (note that this is always the case for a pool created
|
|
without the ename:VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT bit
|
|
set).
|
|
Additionally, if all sets allocated from the pool since it was created or
|
|
most recently reset use the same number of descriptors (of each type) and
|
|
the requested allocation also uses that same number of descriptors (of each
|
|
type), then fragmentation must: not cause an allocation failure.
|
|
|
|
If an allocation failure occurs due to fragmentation, an application can:
|
|
create an additional descriptor pool to perform further descriptor set
|
|
allocations.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:maxSets must: be greater than `0`
|
|
****
|
|
|
|
include::../validity/structs/VkDescriptorPoolCreateInfo.txt[]
|
|
|
|
// refBegin VkDescriptorPoolSize Structure specifying descriptor pool size
|
|
|
|
The sname:VkDescriptorPoolSize structure is defined as:
|
|
|
|
include::../api/structs/VkDescriptorPoolSize.txt[]
|
|
|
|
* pname:type is the type of descriptor.
|
|
* pname:descriptorCount is the number of descriptors of that type to
|
|
allocate.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:descriptorCount must: be greater than `0`
|
|
****
|
|
|
|
include::../validity/structs/VkDescriptorPoolSize.txt[]
|
|
|
|
// refBegin vkDestroyDescriptorPool Destroy a descriptor pool object
|
|
|
|
To destroy a descriptor pool, call:
|
|
|
|
include::../api/protos/vkDestroyDescriptorPool.txt[]
|
|
|
|
* pname:device is the logical device that destroys the descriptor pool.
|
|
* pname:descriptorPool is the descriptor pool to destroy.
|
|
* pname:pAllocator controls host memory allocation as described in the
|
|
<<memory-allocation, Memory Allocation>> chapter.
|
|
|
|
When a pool is destroyed, all descriptor sets allocated from the pool are
|
|
implicitly freed and become invalid.
|
|
Descriptor sets allocated from a given pool do not need to be freed before
|
|
destroying that descriptor pool.
|
|
|
|
.Valid Usage
|
|
****
|
|
* All submitted commands that refer to pname:descriptorPool (via any
|
|
allocated descriptor sets) must: have completed execution
|
|
* If sname:VkAllocationCallbacks were provided when pname:descriptorPool
|
|
was created, a compatible set of callbacks must: be provided here
|
|
* If no sname:VkAllocationCallbacks were provided when
|
|
pname:descriptorPool was created, pname:pAllocator must: be `NULL`
|
|
****
|
|
|
|
include::../validity/protos/vkDestroyDescriptorPool.txt[]
|
|
|
|
// refBegin VkDescriptorSet Opaque handle to a descriptor set object
|
|
|
|
Descriptor sets are allocated from descriptor pool objects, and are
|
|
represented by sname:VkDescriptorSet handles:
|
|
|
|
include::../api/handles/VkDescriptorSet.txt[]
|
|
|
|
// refEnd VkDescriptorSet
|
|
|
|
// refBegin vkAllocateDescriptorSets Allocate one or more descriptor sets
|
|
|
|
To allocate descriptor sets from a descriptor pool, call:
|
|
|
|
include::../api/protos/vkAllocateDescriptorSets.txt[]
|
|
|
|
* pname:device is the logical device that owns the descriptor pool.
|
|
* pname:pAllocateInfo is a pointer to an instance of the
|
|
slink:VkDescriptorSetAllocateInfo structure describing parameters of the
|
|
allocation.
|
|
* pname:pDescriptorSets is a pointer to an array of sname:VkDescriptorSet
|
|
handles in which the resulting descriptor set objects are returned.
|
|
The array must: be at least the length specified by the
|
|
pname:descriptorSetCount member of pname:pAllocateInfo.
|
|
|
|
The allocated descriptor sets are returned in pname:pDescriptorSets.
|
|
|
|
When a descriptor set is allocated, the initial state is largely
|
|
uninitialized and all descriptors are undefined.
|
|
However, the descriptor set can: be bound in a command buffer without
|
|
causing errors or exceptions.
|
|
All entries that are statically used by a pipeline in a drawing or
|
|
dispatching command must: have been populated before the descriptor set is
|
|
bound for use by that command.
|
|
Entries that are not statically used by a pipeline can: have uninitialized
|
|
descriptors or descriptors of resources that have been destroyed, and
|
|
executing a draw or dispatch with such a descriptor set bound does not cause
|
|
undefined behavior.
|
|
This means applications need not populate unused entries with dummy
|
|
descriptors.
|
|
|
|
If an allocation fails due to fragmentation, an indeterminate error is
|
|
returned with an unspecified error code.
|
|
Any returned error other than ename:VK_ERROR_FRAGMENTED_POOL does not imply
|
|
its usual meaning: applications should: assume that the allocation failed
|
|
due to fragmentation, and create a new descriptor pool.
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
Applications should: check for a negative return value when allocating new
|
|
descriptor sets, assume that any error effectively means
|
|
ename:VK_ERROR_FRAGMENTED_POOL, and try to create a new descriptor pool.
|
|
If ename:VK_ERROR_FRAGMENTED_POOL is the actual return value, it adds
|
|
certainty to that decision.
|
|
|
|
The reason for this is that ename:VK_ERROR_FRAGMENTED_POOL was only added in
|
|
a later revision of the 1.0 specification, and so drivers may: return other
|
|
errors if they were written against earlier revisions.
|
|
To ensure full compatibility with earlier patch revisions, these other
|
|
errors are allowed.
|
|
====
|
|
|
|
include::../validity/protos/vkAllocateDescriptorSets.txt[]
|
|
|
|
// refBegin VkDescriptorSetAllocateInfo Structure specifying the allocation parameters for descriptor sets
|
|
|
|
The sname:VkDescriptorSetAllocateInfo structure is defined as:
|
|
|
|
include::../api/structs/VkDescriptorSetAllocateInfo.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:descriptorPool is the pool which the sets will be allocated from.
|
|
* pname:descriptorSetCount determines the number of descriptor sets to be
|
|
allocated from the pool.
|
|
* pname:pSetLayouts is an array of descriptor set layouts, with each
|
|
member specifying how the corresponding descriptor set is allocated.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:descriptorSetCount must: not be greater than the number of sets
|
|
that are currently available for allocation in pname:descriptorPool
|
|
* pname:descriptorPool must: have enough free descriptor capacity
|
|
remaining to allocate the descriptor sets of the specified layouts
|
|
****
|
|
|
|
include::../validity/structs/VkDescriptorSetAllocateInfo.txt[]
|
|
|
|
// refBegin vkFreeDescriptorSets Free one or more descriptor sets
|
|
|
|
To free allocated descriptor sets, call:
|
|
|
|
include::../api/protos/vkFreeDescriptorSets.txt[]
|
|
|
|
* pname:device is the logical device that owns the descriptor pool.
|
|
* pname:descriptorPool is the descriptor pool from which the descriptor
|
|
sets were allocated.
|
|
* pname:descriptorSetCount is the number of elements in the
|
|
pname:pDescriptorSets array.
|
|
* pname:pDescriptorSets is an array of handles to sname:VkDescriptorSet
|
|
objects.
|
|
|
|
After a successful call to fname:vkFreeDescriptorSets, all descriptor sets
|
|
in pname:pDescriptorSets are invalid.
|
|
|
|
.Valid Usage
|
|
****
|
|
* All submitted commands that refer to any element of
|
|
pname:pDescriptorSets must: have completed execution
|
|
* pname:pDescriptorSets must: be a pointer to an array of
|
|
pname:descriptorSetCount sname:VkDescriptorSet handles, each element of
|
|
which must: either be a valid handle or dlink:VK_NULL_HANDLE
|
|
* Each valid handle in pname:pDescriptorSets must: have been allocated
|
|
from pname:descriptorPool
|
|
* pname:descriptorPool must: have been created with the
|
|
ename:VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT flag
|
|
****
|
|
|
|
include::../validity/protos/vkFreeDescriptorSets.txt[]
|
|
|
|
// refBegin vkResetDescriptorPool Resets a descriptor pool object
|
|
|
|
To return all descriptor sets allocated from a given pool to the pool,
|
|
rather than freeing individual descriptor sets, call:
|
|
|
|
include::../api/protos/vkResetDescriptorPool.txt[]
|
|
|
|
* pname:device is the logical device that owns the descriptor pool.
|
|
* pname:descriptorPool is the descriptor pool to be reset.
|
|
* pname:flags is reserved for future use.
|
|
|
|
Resetting a descriptor pool recycles all of the resources from all of the
|
|
descriptor sets allocated from the descriptor pool back to the descriptor
|
|
pool, and the descriptor sets are implicitly freed.
|
|
|
|
.Valid Usage
|
|
****
|
|
* All uses of pname:descriptorPool (via any allocated descriptor sets)
|
|
must: have completed execution
|
|
****
|
|
|
|
include::../validity/protos/vkResetDescriptorPool.txt[]
|
|
|
|
|
|
[[descriptorsets-updates]]
|
|
=== Descriptor Set Updates
|
|
|
|
// refBegin vkUpdateDescriptorSets Update the contents of a descriptor set object
|
|
|
|
Once allocated, descriptor sets can: be updated with a combination of write
|
|
and copy operations.
|
|
To update descriptor sets, call:
|
|
|
|
include::../api/protos/vkUpdateDescriptorSets.txt[]
|
|
|
|
* pname:device is the logical device that updates the descriptor sets.
|
|
* pname:descriptorWriteCount is the number of elements in the
|
|
pname:pDescriptorWrites array.
|
|
* pname:pDescriptorWrites is a pointer to an array of
|
|
slink:VkWriteDescriptorSet structures describing the descriptor sets to
|
|
write to.
|
|
* pname:descriptorCopyCount is the number of elements in the
|
|
pname:pDescriptorCopies array.
|
|
* pname:pDescriptorCopies is a pointer to an array of
|
|
slink:VkCopyDescriptorSet structures describing the descriptor sets to
|
|
copy between.
|
|
|
|
The operations described by pname:pDescriptorWrites are performed first,
|
|
followed by the operations described by pname:pDescriptorCopies.
|
|
Within each array, the operations are performed in the order they appear in
|
|
the array.
|
|
|
|
Each element in the pname:pDescriptorWrites array describes an operation
|
|
updating the descriptor set using descriptors for resources specified in the
|
|
structure.
|
|
|
|
Each element in the pname:pDescriptorCopies array is a
|
|
slink:VkCopyDescriptorSet structure describing an operation copying
|
|
descriptors between sets.
|
|
|
|
include::../validity/protos/vkUpdateDescriptorSets.txt[]
|
|
|
|
// refBegin VkWriteDescriptorSet Structure specifying the parameters of a descriptor set write operation
|
|
|
|
The sname:VkWriteDescriptorSet structure is defined as:
|
|
|
|
include::../api/structs/VkWriteDescriptorSet.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:dstSet is the destination descriptor set to update.
|
|
* pname:dstBinding is the descriptor binding within that set.
|
|
* pname:dstArrayElement is the starting element in that array.
|
|
* pname:descriptorCount is the number of descriptors to update (the number
|
|
of elements in pname:pImageInfo, pname:pBufferInfo, or
|
|
pname:pTexelBufferView).
|
|
* pname:descriptorType is a elink:VkDescriptorType specifying the type of
|
|
each descriptor in pname:pImageInfo, pname:pBufferInfo, or
|
|
pname:pTexelBufferView, as described below.
|
|
It must: be the same type as that specified in
|
|
sname:VkDescriptorSetLayoutBinding for pname:dstSet at pname:dstBinding.
|
|
The type of the descriptor also controls which array the descriptors are
|
|
taken from.
|
|
* pname:pImageInfo points to an array of slink:VkDescriptorImageInfo
|
|
structures or is ignored, as described below.
|
|
* pname:pBufferInfo points to an array of slink:VkDescriptorBufferInfo
|
|
structures or is ignored, as described below.
|
|
* pname:pTexelBufferView points to an array of slink:VkBufferView handles
|
|
as described in the <<resources-buffer-views,Buffer Views>> section or
|
|
is ignored, as described below.
|
|
|
|
Only one of pname:pImageInfo, pname:pBufferInfo, or pname:pTexelBufferView
|
|
members is used according to the descriptor type specified in the
|
|
pname:descriptorType member of the containing sname:VkWriteDescriptorSet
|
|
structure, as specified below.
|
|
|
|
[[descriptorsets-updates-consecutive, consecutive binding updates]]
|
|
If the pname:dstBinding has fewer than pname:descriptorCount array elements
|
|
remaining starting from pname:dstArrayElement, then the remainder will be
|
|
used to update the subsequent binding - pname:dstBinding+1 starting at array
|
|
element zero.
|
|
If a binding has a pname:descriptorCount of zero, it is skipped.
|
|
This behavior applies recursively, with the update affecting consecutive
|
|
bindings as needed to update all pname:descriptorCount descriptors.
|
|
All consecutive bindings updated via a single sname:VkWriteDescriptorSet
|
|
structure, except those with a pname:descriptorCount of zero, must: have
|
|
identical pname:descriptorType and pname:stageFlags, and must: all either
|
|
use immutable samplers or must: all not use immutable samplers.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:dstBinding must: be less than or equal to the maximum value of
|
|
pname:binding of all slink:VkDescriptorSetLayoutBinding structures
|
|
specified when pname:dstSet's descriptor set layout was created
|
|
* pname:dstBinding must: be a binding with a non-zero
|
|
pname:descriptorCount
|
|
* pname:descriptorType must: match the type of pname:dstBinding within
|
|
pname:dstSet
|
|
* The sum of pname:dstArrayElement and pname:descriptorCount must: be less
|
|
than or equal to the number of array elements in the descriptor set
|
|
binding specified by pname:dstBinding, and all applicable consecutive
|
|
bindings, as described by <<descriptorsets-updates-consecutive>>
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or
|
|
ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pname:pImageInfo must: be a
|
|
pointer to an array of pname:descriptorCount valid
|
|
sname:VkDescriptorImageInfo structures
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|
|
or ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pname:pTexelBufferView
|
|
must: be a pointer to an array of pname:descriptorCount valid
|
|
sname:VkBufferView handles
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pname:pBufferInfo must:
|
|
be a pointer to an array of pname:descriptorCount valid
|
|
sname:VkDescriptorBufferInfo structures
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_SAMPLER or
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and pname:dstSet was
|
|
not allocated with a layout that included immutable samplers for
|
|
pname:dstBinding with pname:descriptorType, the pname:sampler member of
|
|
any given element of pname:pImageInfo must: be a valid sname:VkSampler
|
|
object
|
|
* If pname:descriptorType is
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or
|
|
ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the pname:imageView and
|
|
pname:imageLayout members of any given element of pname:pImageInfo must:
|
|
be a valid sname:VkImageView and elink:VkImageLayout, respectively
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the pname:offset member
|
|
of any given element of pname:pBufferInfo must: be a multiple of
|
|
sname:VkPhysicalDeviceLimits::pname:minUniformBufferOffsetAlignment
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the pname:offset member
|
|
of any given element of pname:pBufferInfo must: be a multiple of
|
|
sname:VkPhysicalDeviceLimits::pname:minStorageBufferOffsetAlignment
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, or
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the pname:buffer member
|
|
of any given element of pname:pBufferInfo that is non-sparse must: be
|
|
bound completely and contiguously to a single sname:VkDeviceMemory
|
|
object
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the pname:buffer member
|
|
of any given element of pname:pBufferInfo must: have been created with
|
|
ename:VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the pname:buffer member
|
|
of any given element of pname:pBufferInfo must: have been created with
|
|
ename:VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the pname:range member
|
|
of any given element of pname:pBufferInfo, or the effective range if
|
|
pname:range is ename:VK_WHOLE_SIZE, must: be less than or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxUniformBufferRange
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the pname:range member
|
|
of any given element of pname:pBufferInfo, or the effective range if
|
|
pname:range is ename:VK_WHOLE_SIZE, must: be less than or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxStorageBufferRange
|
|
* If pname:descriptorType is
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, the sname:VkBuffer that
|
|
any given element of pname:pTexelBufferView was created from must: have
|
|
been created with ename:VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set
|
|
* If pname:descriptorType is
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, the sname:VkBuffer that
|
|
any given element of pname:pTexelBufferView was created from must: have
|
|
been created with ename:VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set
|
|
* If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or
|
|
ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the pname:imageView member of
|
|
any given element of pname:pImageInfo must: have been created with the
|
|
identity swizzle
|
|
****
|
|
|
|
include::../validity/structs/VkWriteDescriptorSet.txt[]
|
|
|
|
// refBegin VkDescriptorType Specifies the type of a descriptor in a descriptor set
|
|
|
|
The type of descriptors in a descriptor set is specified by
|
|
slink:VkWriteDescriptorSet::pname:descriptorType, which must: be one of the
|
|
values:
|
|
|
|
include::../api/enums/VkDescriptorType.txt[]
|
|
|
|
If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the elements of the
|
|
slink:VkWriteDescriptorSet::pname:pBufferInfo array of
|
|
slink:VkDescriptorBufferInfo structures will be used to update the
|
|
descriptors, and other arrays will be ignored.
|
|
|
|
If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, the
|
|
slink:VkWriteDescriptorSet::pname:pTexelBufferView array will be used to
|
|
update the descriptors, and other arrays will be ignored.
|
|
|
|
If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or
|
|
ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the elements of the
|
|
slink:VkWriteDescriptorSet::pname:pImageInfo array of
|
|
slink:VkDescriptorImageInfo structures will be used to update the
|
|
descriptors, and other arrays will be ignored.
|
|
|
|
// refEnd VkDescriptorType
|
|
|
|
// refBegin VkDescriptorBufferInfo Structure specifying descriptor buffer info
|
|
|
|
The sname:VkDescriptorBufferInfo structure is defined as:
|
|
|
|
include::../api/structs/VkDescriptorBufferInfo.txt[]
|
|
|
|
* pname:buffer is the buffer resource.
|
|
* pname:offset is the offset in bytes from the start of pname:buffer.
|
|
Access to buffer memory via this descriptor uses addressing that is
|
|
relative to this starting offset.
|
|
* pname:range is the size in bytes that is used for this descriptor
|
|
update, or ename:VK_WHOLE_SIZE to use the range from pname:offset to the
|
|
end of the buffer.
|
|
+
|
|
--
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
When using ename:VK_WHOLE_SIZE, the effective range must: not be larger than
|
|
the maximum range for the descriptor type
|
|
(<<features-limits-maxUniformBufferRange, maxUniformBufferRange>> or
|
|
<<features-limits-maxStorageBufferRange, maxStorageBufferRange>>).
|
|
This means that ename:VK_WHOLE_SIZE is not typically useful in the common
|
|
case where uniform buffer descriptors are suballocated from a buffer that is
|
|
much larger than pname:maxUniformBufferRange.
|
|
====
|
|
--
|
|
+
|
|
For ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC and
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC descriptor types,
|
|
pname:offset is the base offset from which the dynamic offset is applied and
|
|
pname:range is the static size used for all dynamic offsets.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:offset must: be less than the size of pname:buffer
|
|
* If pname:range is not equal to ename:VK_WHOLE_SIZE, pname:range must: be
|
|
greater than `0`
|
|
* If pname:range is not equal to ename:VK_WHOLE_SIZE, pname:range must: be
|
|
less than or equal to the size of pname:buffer minus pname:offset
|
|
****
|
|
|
|
include::../validity/structs/VkDescriptorBufferInfo.txt[]
|
|
|
|
// refBegin VkDescriptorImageInfo Structure specifying descriptor image info
|
|
|
|
The sname:VkDescriptorImageInfo structure is defined as:
|
|
|
|
include::../api/structs/VkDescriptorImageInfo.txt[]
|
|
|
|
* pname:sampler is a sampler handle, and is used in descriptor updates for
|
|
types ename:VK_DESCRIPTOR_TYPE_SAMPLER and
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER if the binding being
|
|
updated does not use immutable samplers.
|
|
* pname:imageView is an image view handle, and is used in descriptor
|
|
updates for types ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and
|
|
ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT.
|
|
* pname:imageLayout is the layout that the image will be in at the time
|
|
this descriptor is accessed.
|
|
pname:imageLayout is used in descriptor updates for types
|
|
ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and
|
|
ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT.
|
|
|
|
Members of sname:VkDescriptorImageInfo that are not used in an update (as
|
|
described above) are ignored.
|
|
|
|
include::../validity/structs/VkDescriptorImageInfo.txt[]
|
|
|
|
// refBegin VkCopyDescriptorSet Structure specifying a copy descriptor set operation
|
|
|
|
The sname:VkCopyDescriptorSet structure is defined as:
|
|
|
|
include::../api/structs/VkCopyDescriptorSet.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:srcSet, pname:srcBinding, and pname:srcArrayElement are the source
|
|
set, binding, and array element, respectively.
|
|
* pname:dstSet, pname:dstBinding, and pname:dstArrayElement are the
|
|
destination set, binding, and array element, respectively.
|
|
* pname:descriptorCount is the number of descriptors to copy from the
|
|
source to destination.
|
|
If pname:descriptorCount is greater than the number of remaining array
|
|
elements in the source or destination binding, those affect consecutive
|
|
bindings in a manner similar to slink:VkWriteDescriptorSet above.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:srcBinding must: be a valid binding within pname:srcSet
|
|
* The sum of pname:srcArrayElement and pname:descriptorCount must: be less
|
|
than or equal to the number of array elements in the descriptor set
|
|
binding specified by pname:srcBinding, and all applicable consecutive
|
|
bindings, as described by <<descriptorsets-updates-consecutive>>
|
|
* pname:dstBinding must: be a valid binding within pname:dstSet
|
|
* The sum of pname:dstArrayElement and pname:descriptorCount must: be less
|
|
than or equal to the number of array elements in the descriptor set
|
|
binding specified by pname:dstBinding, and all applicable consecutive
|
|
bindings, as described by <<descriptorsets-updates-consecutive>>
|
|
* If pname:srcSet is equal to pname:dstSet, then the source and
|
|
destination ranges of descriptors must: not overlap, where the ranges
|
|
may: include array elements from consecutive bindings as described by
|
|
<<descriptorsets-updates-consecutive>>
|
|
****
|
|
|
|
include::../validity/structs/VkCopyDescriptorSet.txt[]
|
|
|
|
|
|
[[descriptorsets-binding]]
|
|
=== Descriptor Set Binding
|
|
|
|
// refBegin vkCmdBindDescriptorSets Binds descriptor sets to a command buffer
|
|
|
|
To bind one or more descriptor sets to a command buffer, call:
|
|
|
|
include::../api/protos/vkCmdBindDescriptorSets.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer that the descriptor sets will
|
|
be bound to.
|
|
* pname:pipelineBindPoint is a elink:VkPipelineBindPoint indicating
|
|
whether the descriptors will be used by graphics pipelines or compute
|
|
pipelines.
|
|
There is a separate set of bind points for each of graphics and compute,
|
|
so binding one does not disturb the other.
|
|
* pname:layout is a sname:VkPipelineLayout object used to program the
|
|
bindings.
|
|
* pname:firstSet is the set number of the first descriptor set to be
|
|
bound.
|
|
* pname:descriptorSetCount is the number of elements in the
|
|
pname:pDescriptorSets array.
|
|
* pname:pDescriptorSets is an array of handles to sname:VkDescriptorSet
|
|
objects describing the descriptor sets to write to.
|
|
* pname:dynamicOffsetCount is the number of dynamic offsets in the
|
|
pname:pDynamicOffsets array.
|
|
* pname:pDynamicOffsets is a pointer to an array of code:uint32_t values
|
|
specifying dynamic offsets.
|
|
|
|
fname:vkCmdBindDescriptorSets causes the sets numbered [pname:firstSet..
|
|
pname:firstSet+pname:descriptorSetCount-1] to use the bindings stored in
|
|
pname:pDescriptorSets[0..pname:descriptorSetCount-1] for subsequent
|
|
rendering commands (either compute or graphics, according to the
|
|
pname:pipelineBindPoint).
|
|
Any bindings that were previously applied via these sets are no longer
|
|
valid.
|
|
|
|
Once bound, a descriptor set affects rendering of subsequent graphics or
|
|
compute commands in the command buffer until a different set is bound to the
|
|
same set number, or else until the set is disturbed as described in
|
|
<<descriptorsets-compatibility, Pipeline Layout Compatibility>>.
|
|
|
|
A compatible descriptor set must: be bound for all set numbers that any
|
|
shaders in a pipeline access, at the time that a draw or dispatch command is
|
|
recorded to execute using that pipeline.
|
|
However, if none of the shaders in a pipeline statically use any bindings
|
|
with a particular set number, then no descriptor set need be bound for that
|
|
set number, even if the pipeline layout includes a non-trivial descriptor
|
|
set layout for that set number.
|
|
|
|
If any of the sets being bound include dynamic uniform or storage buffers,
|
|
then pname:pDynamicOffsets includes one element for each array element in
|
|
each dynamic descriptor type binding in each set.
|
|
Values are taken from pname:pDynamicOffsets in an order such that all
|
|
entries for set N come before set N+1; within a set, entries are ordered by
|
|
the binding numbers in the descriptor set layouts; and within a binding
|
|
array, elements are in order.
|
|
pname:dynamicOffsetCount must: equal the total number of dynamic descriptors
|
|
in the sets being bound.
|
|
|
|
The effective offset used for dynamic uniform and storage buffer bindings is
|
|
the sum of the relative offset taken from pname:pDynamicOffsets, and the
|
|
base address of the buffer plus base offset in the descriptor set.
|
|
The length of the dynamic uniform and storage buffer bindings is the buffer
|
|
range as specified in the descriptor set.
|
|
|
|
Each of the pname:pDescriptorSets must: be compatible with the pipeline
|
|
layout specified by pname:layout.
|
|
The layout used to program the bindings must: also be compatible with the
|
|
pipeline used in subsequent graphics or compute commands, as defined in the
|
|
<<descriptorsets-compatibility, Pipeline Layout Compatibility>> section.
|
|
|
|
The descriptor set contents bound by a call to fname:vkCmdBindDescriptorSets
|
|
may: be consumed during host execution of the command, or during shader
|
|
execution of the resulting draws, or any time in between.
|
|
Thus, the contents must: not be altered (overwritten by an update command,
|
|
or freed) between when the command is recorded and when the command
|
|
completes executing on the queue.
|
|
The contents of pname:pDynamicOffsets are consumed immediately during
|
|
execution of fname:vkCmdBindDescriptorSets.
|
|
Once all pending uses have completed, it is legal to update and reuse a
|
|
descriptor set.
|
|
|
|
.Valid Usage
|
|
****
|
|
* Any given element of pname:pDescriptorSets must: have been allocated
|
|
with a sname:VkDescriptorSetLayout that matches (is the same as, or
|
|
defined identically to) the sname:VkDescriptorSetLayout at set _n_ in
|
|
pname:layout, where _n_ is the sum of pname:firstSet and the index into
|
|
pname:pDescriptorSets
|
|
* pname:dynamicOffsetCount must: be equal to the total number of dynamic
|
|
descriptors in pname:pDescriptorSets
|
|
* The sum of pname:firstSet and pname:descriptorSetCount must: be less
|
|
than or equal to sname:VkPipelineLayoutCreateInfo::pname:setLayoutCount
|
|
provided when pname:layout was created
|
|
* pname:pipelineBindPoint must: be supported by the pname:commandBuffer's
|
|
parent sname:VkCommandPool's queue family
|
|
* Any given element of pname:pDynamicOffsets must: satisfy the required
|
|
alignment for the corresponding descriptor binding's descriptor type
|
|
****
|
|
|
|
include::../validity/protos/vkCmdBindDescriptorSets.txt[]
|
|
|
|
|
|
=== Push Constant Updates
|
|
|
|
[[descriptorsets-push-constants]]
|
|
|
|
As described above in section <<descriptorsets-pipelinelayout, Pipeline
|
|
Layouts>>, the pipeline layout defines shader push constants which are
|
|
updated via Vulkan commands rather than via writes to memory or copy
|
|
commands.
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
Push constants represent a high speed path to modify constant data in
|
|
pipelines that is expected to outperform memory-backed resource updates.
|
|
====
|
|
|
|
The values of push constants are undefined at the start of a command buffer.
|
|
|
|
// refBegin vkCmdPushConstants Update the values of push constants
|
|
|
|
To update push constants, call:
|
|
|
|
include::../api/protos/vkCmdPushConstants.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer in which the push constant
|
|
update will be recorded.
|
|
* pname:layout is the pipeline layout used to program the push constant
|
|
updates.
|
|
* pname:stageFlags is a bitmask of elink:VkShaderStageFlagBits specifying
|
|
the shader stages that will use the push constants in the updated range.
|
|
* pname:offset is the start offset of the push constant range to update,
|
|
in units of bytes.
|
|
* pname:size is the size of the push constant range to update, in units of
|
|
bytes.
|
|
* pname:pValues is an array of pname:size bytes containing the new push
|
|
constant values.
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:stageFlags must: match exactly the shader stages used in
|
|
pname:layout for the range specified by pname:offset and pname:size
|
|
* pname:offset must: be a multiple of `4`
|
|
* pname:size must: be a multiple of `4`
|
|
* pname:offset must: be less than
|
|
sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize
|
|
* pname:size must: be less than or equal to
|
|
sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize minus
|
|
pname:offset
|
|
****
|
|
|
|
include::../validity/protos/vkCmdPushConstants.txt[]
|