Resource Descriptors
A descriptor is an opaque data structure used to access shader resources such as buffers, images, or samplers. Rather than existing as distinct objects, descriptors are handled as opaque data, which can be accessed by a shader through descriptor heaps, descriptor buffers, or descriptor sets.
Shaders access descriptors via
the ResourceHeapEXT and SamplerHeapEXT built-ins, or through
variables decorated with DescriptorSet and Binding values linking
them to the API.
Details of the shader interface mapping are described in the
Shader Resource Interface section.
|
Shaders can also access buffers without going through descriptors by using Physical Storage Buffer Access to access them through 64-bit addresses. |
Descriptor Types
There are a number of different types of descriptor supported by Vulkan, corresponding to different resources or usage. The following sections describe the API definitions of each descriptor type. The mapping of each type to SPIR-V is listed in the Shader Resource and Descriptor Type Correspondence and Shader Resource and Storage Class Correspondence tables in the Shader Interfaces chapter.
Possible descriptor types are:
// Provided by VK_VERSION_1_0
typedef enum VkDescriptorType {
VK_DESCRIPTOR_TYPE_SAMPLER = 0,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2,
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3,
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4,
VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9,
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10,
// Provided by VK_VERSION_1_3
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000,
// Provided by VK_KHR_acceleration_structure
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000,
// Provided by VK_NV_ray_tracing
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
// Provided by VK_QCOM_image_processing
VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000,
// Provided by VK_QCOM_image_processing
VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001,
// Provided by VK_ARM_tensors
VK_DESCRIPTOR_TYPE_TENSOR_ARM = 1000460000,
// Provided by VK_EXT_mutable_descriptor_type
VK_DESCRIPTOR_TYPE_MUTABLE_EXT = 1000351000,
// Provided by VK_NV_partitioned_acceleration_structure
VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV = 1000570000,
// Provided by VK_EXT_inline_uniform_block
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK,
// Provided by VK_VALVE_mutable_descriptor_type
VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = VK_DESCRIPTOR_TYPE_MUTABLE_EXT,
} VkDescriptorType;
-
VK_DESCRIPTOR_TYPE_SAMPLER specifies a sampler descriptor.
-
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER specifies a combined image sampler descriptor.
-
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE specifies a sampled image descriptor.
-
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE specifies a storage image descriptor.
-
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER specifies a uniform texel buffer descriptor.
-
VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER specifies a storage texel buffer descriptor.
-
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER specifies a uniform buffer descriptor.
-
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER specifies a storage buffer descriptor.
-
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC specifies a dynamic uniform buffer descriptor.
-
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC specifies a dynamic storage buffer descriptor.
-
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT specifies an input attachment descriptor.
-
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK specifies an inline uniform block.
-
VK_DESCRIPTOR_TYPE_MUTABLE_EXT specifies a descriptor of mutable type.
-
VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM specifies a sampled weight image descriptor.
-
VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM specifies a block matching image descriptor.
-
VK_DESCRIPTOR_TYPE_TENSOR_ARM specifies a storage tensor descriptor.
Storage Image
A storage image (VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) is a descriptor type associated with an image resource via an image view that load, store, and atomic operations can be performed on.
Storage image loads are supported in all shader stages for image views whose format features contain VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT.
Stores to storage images are supported in task, mesh and compute shaders for image views whose format features contain VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT.
Atomic operations on storage images are supported in task, mesh and compute shaders for image views whose format features contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT.
When the 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 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.
The image subresources for a storage image must be in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or VK_IMAGE_LAYOUT_TENSOR_ALIASING_ARM or VK_IMAGE_LAYOUT_GENERAL layout in order to access its data in a shader.
When the tileShadingColorAttachments feature is enabled, loads using
OpImageRead or OpImageSparseRead are supported for color
tile attachments in fragment and compute
shaders for image views whose format features contain VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT.
Additionally, when the tileShadingColorAttachments feature is enabled, stores using
OpImageWrite are supported for color attachments in compute shaders
with the same set of image formats as for loads.
When the tileShadingAtomicOps
feature is enabled, tile atomic operations are supported for color
attachments in compute shaders with the same set of image formats as for
loads.
When the tileShadingInputAttachments feature is enabled, loads using
OpImageRead are supported for input tile attachments in fragment and compute shaders with the same set of image
formats as for color attachments.
Stores to input attachments are not supported.
When the tileShadingDepthAttachments or
tileShadingStencilAttachments feature is enabled, loads using
OpImageRead or OpImageSparseRead are supported for depth or
stencil aspects of a depth/stencil tile attachment in fragment and compute shaders with the same set of image
formats as for color attachments.
Stores to depth/stencil attachments are not supported.
Sampler
A sampler descriptor (VK_DESCRIPTOR_TYPE_SAMPLER) is a descriptor type associated with a sampler object, used to control the behavior of sampling operations performed on a sampled image.
Sampled Image
A sampled image (VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) is a descriptor type associated with an image resource via an image view that sampling operations can be performed on.
Shaders combine a sampled image variable and a sampler variable to perform sampling operations.
Sampled images are supported in all shader stages for image views whose format features contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT.
An image subresources for a sampled image must be in one of the following layouts:
Combined Image Sampler
A combined image sampler (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) is a single descriptor type associated with both a sampler and an image resource, combining both a sampler and sampled image descriptor into a single descriptor.
If the descriptor refers to a sampler that performs Y′CBCR conversion or samples a subsampled image, the sampler must only be used to sample the image in the same descriptor. Otherwise, the sampler and image in this type of descriptor can be used freely with any other samplers and images.
An image subresources for a combined image sampler must be in one of the following layouts:
|
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. |
Uniform Texel Buffer
A uniform texel buffer (VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) is a descriptor type associated with a buffer resource via a buffer view that image sampling operations can be performed on.
Uniform texel buffers define a tightly-packed 1-dimensional linear array of texels, with texels going through format conversion when read in a shader in the same way as they are for an image.
Load operations from uniform texel buffers are supported in all shader stages for buffer view formats which report format features support for VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
Storage Texel Buffer
A storage texel buffer (VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) is a descriptor type associated with a buffer resource via a buffer view that image load, store, and atomic operations can be performed on.
Storage texel buffers define a tightly-packed 1-dimensional linear array of texels, with texels going through format conversion when read in a shader in the same way as they are for an image. Unlike uniform texel buffers, these buffers can also be written to in the same way as for storage images.
Storage texel buffer loads are supported in all shader stages for texel buffer view formats which report format features support for VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
Stores to storage texel buffers are supported in task, mesh and compute shaders for texel buffer formats which report format features support for VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
Atomic operations on storage texel buffers are supported in task, mesh and compute shaders for texel buffer formats which report format features support for VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
When the fragmentStoresAndAtomics feature is enabled, stores and atomic
operations are also supported for storage texel buffers in fragment shaders
with the same set of texel buffer formats as supported in compute shaders.
When the vertexPipelineStoresAndAtomics feature is enabled, stores and atomic
operations are also supported in vertex, tessellation, and geometry shaders
with the same set of texel buffer formats as supported in compute shaders.
Storage Buffer
A storage buffer (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) is a descriptor type associated with a buffer resource directly, described in a shader as a structure with various members that load, store, and atomic operations can be performed on.
|
Atomic operations can only be performed on members of certain types as defined in the SPIR-V environment appendix. |
Uniform Buffer
A uniform buffer (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) is a descriptor type associated with a buffer resource directly, described in a shader as a structure with various members that load operations can be performed on.
Dynamic Uniform Buffer
A dynamic uniform buffer (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) is almost identical to a uniform buffer, and differs only in how the offset into the buffer is specified. This descriptor type is only valid when using descriptor sets. The base offset calculated by VkDescriptorBufferInfo when initially updating a descriptor set is added to a dynamic offset when binding a descriptor set.
Dynamic Storage Buffer
A dynamic storage buffer (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) is almost identical to a storage buffer, and differs only in how the offset into the buffer is specified. This descriptor type is only valid when using descriptor sets. The base offset calculated by VkDescriptorBufferInfo when initially updating a descriptor set is added to a dynamic offset when binding a descriptor set.
Inline Uniform Block
An inline uniform block (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) is almost identical to a uniform buffer in how it is accessed in the shader. Where it differs is that its storage is taken directly from a containing descriptor set or descriptor buffer, instead of being backed by a separate buffer object. This descriptor type is not valid when using descriptor heaps; applications can directly access the heap pointer in a shader or use the VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_DATA_EXT mapping.
Inline uniform blocks are typically used to access a small set of constant data that does not require the additional flexibility provided by the indirection enabled when using a uniform buffer where the descriptor and the referenced buffer memory are decoupled. Compared to push constants, they allow reusing the same set of constant data across multiple disjoint sets of drawing and dispatching commands.
Inline uniform block descriptors cannot be aggregated into arrays. Instead, the array size specified for an inline uniform block descriptor binding specifies the binding’s capacity in bytes.
Sample Weight Image
A sample weight image (VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM) is a descriptor type associated with an image resource via an image view that can be used in weight image sampling. The image view must have been created with VkImageViewSampleWeightCreateInfoQCOM.
Shaders can combine a weight image variable, a sampled image variable, and a sampler variable to perform weight image sampling.
Weight image sampling is supported in all shader stages if the weight image view specifies a format that supports format feature VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM and the sampled image view specifies a format that supports format feature VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM
The image subresources for the weight image must be in the VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, or VK_IMAGE_LAYOUT_GENERAL layout in order to access its data in a shader.
Block Matching Image
A block matching image (VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM) is a descriptor type associated with an image resource via an image view that can be used in block matching.
Shaders can combine a target image variable, a reference image variable, and a sampler variable to perform block matching.
Block matching is supported in all shader stages for if both the target view and reference view specifies a format that supports format feature VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM
The image subresources for block matching must be in the VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, or VK_IMAGE_LAYOUT_GENERAL layout in order to access its data in a shader.
Input Attachment
An input attachment (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) is a descriptor type associated with an image resource via an image view that can be used for framebuffer local load operations in fragment shaders.
All image formats that are supported for color attachments (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT or VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV ) or depth/stencil attachments (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) for a given image tiling mode are also supported for input attachments.
An image view used as an input attachment must be in one of the following layouts:
Acceleration Structure
An acceleration structure ( VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR or VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV ) is a descriptor type that is used to retrieve scene geometry from within shaders that are used for ray traversal. Shaders have read-only access to the memory.
Mutable
A descriptor of mutable (VK_DESCRIPTOR_TYPE_MUTABLE_EXT) type
indicates that this descriptor can mutate to a number of different types.
This descriptor type is not valid when using descriptor heaps, as the
elements of a descriptor heap can be manually adjusted to hold different
descriptor types already.
When specified in a descriptor set layout, any of the descriptor types given
in the VkMutableDescriptorTypeListEXT::pDescriptorTypes list of
descriptor types in the pNext chain of
VkDescriptorSetLayoutCreateInfo for this binding.
At any point, each individual descriptor of mutable type has an active
descriptor type.
The active descriptor type can be any one of the declared types in
pDescriptorTypes.
Additionally, a mutable descriptor’s active descriptor type can be of the
VK_DESCRIPTOR_TYPE_MUTABLE_EXT type, which is the initial active
descriptor type.
The active descriptor type can change when the descriptor is updated.
When a descriptor is consumed by binding a descriptor
buffer or
set, the active descriptor type is considered, not
VK_DESCRIPTOR_TYPE_MUTABLE_EXT.
An active descriptor type of VK_DESCRIPTOR_TYPE_MUTABLE_EXT is considered an undefined descriptor. If a descriptor is consumed where the active descriptor type does not match what the shader expects, the descriptor is considered an undefined descriptor.
|
To find which descriptor types are supported as
VK_DESCRIPTOR_TYPE_MUTABLE_EXT, the application can use
vkGetDescriptorSetLayoutSupport with a
VK_DESCRIPTOR_TYPE_MUTABLE_EXT binding, with the list of descriptor
types to query in the
VkMutableDescriptorTypeCreateInfoEXT:: |
|
The intention of a mutable descriptor type is that implementations allocate N bytes per descriptor, where N is determined by the maximum descriptor size for a given descriptor binding. Implementations are not expected to keep track of the active descriptor type, and it should be considered a C-like union type. A mutable descriptor type is not considered as efficient in terms of runtime performance as using a non-mutable descriptor type, and applications are not encouraged to use them outside API layering efforts. Mutable descriptor types can be more efficient if the alternative is using many different descriptors to emulate mutable descriptor types. |
Storage Tensor
A storage tensor (VK_DESCRIPTOR_TYPE_TENSOR_ARM) is a descriptor type associated with a tensor resource via a tensor view that read and write operations can be performed on.
Storage tensor reads and writes are supported in shaders for tensor views whose format features contain VK_FORMAT_FEATURE_2_TENSOR_SHADER_BIT_ARM.
Storage tensor reads and writes are supported in graph pipelines for tensor views whose format features contain VK_FORMAT_FEATURE_2_TENSOR_DATA_GRAPH_BIT_ARM.
Physical Storage Buffer Access
Buffer device addresses can also be
used to access buffer memory in a shader, using the
SPV_KHR_physical_storage_buffer extension
or the equivalent
SPV_EXT_physical_storage_buffer extension
and the PhysicalStorageBuffer storage class.
For example, this value can be stored in a uniform buffer, and the shader
can read the value from the uniform buffer and use it to do a dependent
read/write to this buffer.
All loads, stores, and atomics in a shader through
PhysicalStorageBuffer pointers must access addresses in the address
range of some buffer.