Resource Descriptors

A descriptor is an opaque data structure representing a shader resource such as a buffer, buffer view, image view, sampler, or combined image sampler. Descriptors are organized into descriptor sets, which are bound during command recording for use in subsequent drawing commands. The arrangement of content in each descriptor set is determined by a descriptor set layout, which determines what descriptors can be stored within it. The sequence of descriptor set layouts that can be used by a pipeline is specified in a pipeline layout. Each pipeline object can use up to maxBoundDescriptorSets (see Limits) descriptor sets.

If the descriptorBuffer feature is enabled, the implementation supports placing descriptors into descriptor buffers which are bound during command recording in a similar way to descriptor sets.

Shaders access resources via variables decorated with a descriptor set and binding number that link them to a descriptor in a descriptor set. The shader interface mapping to bound descriptor sets is 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.

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_GENERAL layout in order to access its data in a shader.

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 operationscan 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:

  • VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_GENERAL
  • VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR
  • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
  • VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR
  • VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT

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:

  • VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_GENERAL
  • VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR
  • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
  • VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR
  • VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT

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. The base offset calculated by the VkDescriptorBufferInfo when initially updating the descriptor set is added to a dynamic offset when binding the 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. The base offset calculated by the VkDescriptorBufferInfo when initially updating the descriptor set is added to a dynamic offset when binding the descriptor set.

Inline Uniform Block

An inline uniform block (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) is almost identical to a uniform buffer, and differs only in taking its storage directly from the encompassing descriptor set instead of being backed by buffer memory. It is 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:

  • VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_GENERAL
  • VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR
  • VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
  • VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
  • VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR
  • VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT
  • VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR

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 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 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::pDescriptorTypes array for that binding.

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.

Descriptor Sets

Descriptors are grouped together into descriptor set objects. A descriptor set object is an opaque object containing 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 implementation 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.

Descriptor Set Layout

VkDescriptorSetLayoutOpaque handle to a descriptor set layout object
vkCreateDescriptorSetLayoutCreate a new descriptor set layout
VkDescriptorSetLayoutCreateInfoStructure specifying parameters of a newly created descriptor set layout
VkMutableDescriptorTypeCreateInfoEXTStructure describing the list of possible active descriptor types for mutable type descriptors
VkMutableDescriptorTypeListEXTStructure describing descriptor types that a given descriptor may mutate to
VkDescriptorSetLayoutCreateFlagBitsBitmask specifying descriptor set layout properties
VkDescriptorSetLayoutCreateFlagsBitmask of VkDescriptorSetLayoutCreateFlagBits
VkDescriptorSetLayoutBindingStructure specifying a descriptor set layout binding
VkDescriptorSetLayoutBindingFlagsCreateInfoStructure specifying creation flags for descriptor set layout bindings
VkDescriptorBindingFlagBitsBitmask specifying descriptor set layout binding properties
VkDescriptorBindingFlagsBitmask of VkDescriptorBindingFlagBits
vkGetDescriptorSetLayoutSupportQuery whether a descriptor set layout can be created
VkDescriptorSetLayoutSupportStructure returning information about whether a descriptor set layout can be supported
VkDescriptorSetVariableDescriptorCountLayoutSupportStructure returning information about whether a descriptor set layout can be supported

The following examples show a shader snippet using two descriptor sets, and application code that creates corresponding descriptor set layouts.

GLSL Example

//
// 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

VkResult myResult;

const VkDescriptorSetLayoutBinding myDescriptorSetLayoutBinding[] =
{
    // binding to a single image descriptor
    {
        .binding = 0,
        .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
        .descriptorCount = 1,
        .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
        .pImmutableSamplers = NULL
    },

    // binding to an array of image descriptors
    {
        .binding = 1,
        .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
        .descriptorCount = 12,
        .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
        .pImmutableSamplers = NULL
    },

    // binding to a single uniform buffer descriptor
    {
        .binding = 0,
        .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
        .descriptorCount = 1,
        .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
        .pImmutableSamplers = NULL
    }
};

const VkDescriptorSetLayoutCreateInfo myDescriptorSetLayoutCreateInfo[] =
{
    // Information for first descriptor set with two descriptor bindings
    {
        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
        .pNext = NULL,
        .flags = 0,
        .bindingCount = 2,
        .pBindings = &myDescriptorSetLayoutBinding[0]
    },

    // Information for second descriptor set with one descriptor binding
    {
        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
        .pNext = NULL,
        .flags = 0,
        .bindingCount = 1,
        .pBindings = &myDescriptorSetLayoutBinding[2]
    }
};

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]);
vkDestroyDescriptorSetLayoutDestroy a descriptor set layout object

Pipeline Layouts

VkPipelineLayoutOpaque handle to a pipeline layout object
vkCreatePipelineLayoutCreates a new pipeline layout object
VkPipelineLayoutCreateInfoStructure specifying the parameters of a newly created pipeline layout object
VkPipelineLayoutCreateFlagBitsPipeline layout creation flag bits
VkPipelineLayoutCreateFlagsBitmask of pipeline layout creation flag bits
VkPushConstantRangeStructure specifying a push constant range

Once created, pipeline layouts are used as part of pipeline creation (see Pipelines), as part of binding descriptor sets (see Descriptor Set Binding), and as part of setting push constants (see Push Constant Updates). Pipeline creation accepts a pipeline layout as input, and the layout may be used to map (set, binding, arrayElement) tuples to implementation resources or memory locations within a descriptor set. The assignment of implementation resources depends only on the bindings defined in the descriptor sets that comprise the pipeline layout, and not on any shader source.

All resource variables 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 stageFlags. The pipeline layout can include entries that are not used by a particular pipeline. 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 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.

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 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 Shader Resource Limits.

Table 18. Pipeline Layout Resource Limits
Total Resources AvailableResource Types

maxDescriptorSetSamplers or maxDescriptorSetUpdateAfterBindSamplers

sampler

combined image sampler

maxDescriptorSetSampledImages or maxDescriptorSetUpdateAfterBindSampledImages

sampled image

combined image sampler

uniform texel buffer

maxDescriptorSetStorageImages or maxDescriptorSetUpdateAfterBindStorageImages

storage image

storage texel buffer

maxDescriptorSetUniformBuffers or maxDescriptorSetUpdateAfterBindUniformBuffers

uniform buffer

uniform buffer dynamic

maxDescriptorSetUniformBuffersDynamic or maxDescriptorSetUpdateAfterBindUniformBuffersDynamic or maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic

uniform buffer dynamic

maxDescriptorSetStorageBuffers or maxDescriptorSetUpdateAfterBindStorageBuffers

storage buffer

storage buffer dynamic

maxDescriptorSetStorageBuffersDynamic or maxDescriptorSetUpdateAfterBindStorageBuffersDynamic or maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic

storage buffer dynamic

maxDescriptorSetInputAttachments or maxDescriptorSetUpdateAfterBindInputAttachments

input attachment

maxDescriptorSetInlineUniformBlocks or maxDescriptorSetUpdateAfterBindInlineUniformBlocks

inline uniform block

maxDescriptorSetAccelerationStructures or maxDescriptorSetUpdateAfterBindAccelerationStructures

acceleration structure

vkDestroyPipelineLayoutDestroy a pipeline layout object

Pipeline Layout Compatibility

Two pipeline layouts are defined to be compatible for 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 identically defined descriptor set layouts for sets zero through N, if both of them either were or were not created with VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, and if they were created with identical push constant ranges.

When binding a descriptor set (see Descriptor Set Binding) to set number N, a previously bound descriptor set bound with lower index M than N is disturbed if the pipeline layouts for set M and N are not compatible for set M. Otherwise, the bound descriptor set in M is not disturbed.

If, additionally, the previously bound descriptor set for set N was bound using a pipeline layout not compatible for set N, then all bindings in sets numbered greater than N are disturbed.

When binding a pipeline, the pipeline can correctly access any previously bound descriptor set N if it was bound with compatible pipeline layout for set N, and it was not disturbed.

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.

When a descriptor set is disturbed by binding descriptor sets, the disturbed set is considered to contain undefined: descriptors bound with the same pipeline layout as the disturbing descriptor set.

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 maxBoundDescriptorSets in Limits).

API Example

const VkDescriptorSetLayout layouts[] = { layout1, layout2 };

const VkPushConstantRange ranges[] =
{
    {
        .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
        .offset = 0,
        .size = 4
    },
    {
        .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
        .offset = 4,
        .size = 4
    },
};

const VkPipelineLayoutCreateInfo createInfo =
{
    .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
    .pNext = NULL,
    .flags = 0,
    .setLayoutCount = 2,
    .pSetLayouts = layouts,
    .pushConstantRangeCount = 2,
    .pPushConstantRanges = ranges
};

VkPipelineLayout myPipelineLayout;
myResult = vkCreatePipelineLayout(
    myDevice,
    &createInfo,
    NULL,
    &myPipelineLayout);

Allocation of Descriptor Sets

VkDescriptorPoolOpaque handle to a descriptor pool object
vkCreateDescriptorPoolCreates a descriptor pool object
VkDescriptorPoolCreateInfoStructure specifying parameters of a newly created descriptor pool
VkDescriptorPoolInlineUniformBlockCreateInfoStructure specifying the maximum number of inline uniform block bindings of a newly created descriptor pool
VkDescriptorPoolCreateFlagBitsBitmask specifying certain supported operations on a descriptor pool
VkDescriptorPoolCreateFlagsBitmask of VkDescriptorPoolCreateFlagBits
VkDescriptorPoolSizeStructure specifying descriptor pool size
vkDestroyDescriptorPoolDestroy a descriptor pool object
VkDescriptorSetOpaque handle to a descriptor set object
vkAllocateDescriptorSetsAllocate one or more descriptor sets
VkDescriptorSetAllocateInfoStructure specifying the allocation parameters for descriptor sets
VkDescriptorSetVariableDescriptorCountAllocateInfoStructure specifying additional allocation parameters for descriptor sets
vkFreeDescriptorSetsFree one or more descriptor sets
vkResetDescriptorPoolResets a descriptor pool object
VkDescriptorPoolResetFlagsReserved for future use

Descriptor Set Updates

vkUpdateDescriptorSetsUpdate the contents of a descriptor set object
VkWriteDescriptorSetStructure specifying the parameters of a descriptor set write operation
VkDescriptorTypeSpecifies the type of a descriptor in a descriptor set
VkDescriptorBufferInfoStructure specifying descriptor buffer information
VkDescriptorImageInfoStructure specifying descriptor image information
VkWriteDescriptorSetInlineUniformBlockStructure specifying inline uniform block data
VkWriteDescriptorSetAccelerationStructureKHRStructure specifying acceleration structure descriptor information
VkWriteDescriptorSetAccelerationStructureNVStructure specifying acceleration structure descriptor information
VkCopyDescriptorSetStructure specifying a copy descriptor set operation

Descriptor Update Templates

VkDescriptorUpdateTemplateOpaque handle to a descriptor update template

Descriptor Set Updates With Templates

vkCreateDescriptorUpdateTemplateCreate a new descriptor update template
VkDescriptorUpdateTemplateCreateInfoStructure specifying parameters of a newly created descriptor update template
VkDescriptorUpdateTemplateCreateFlagsReserved for future use
VkDescriptorUpdateTemplateTypeIndicates the valid usage of the descriptor update template
VkDescriptorUpdateTemplateEntryDescribes a single descriptor update of the descriptor update template
vkDestroyDescriptorUpdateTemplateDestroy a descriptor update template object
vkUpdateDescriptorSetWithTemplateUpdate the contents of a descriptor set object using an update template

Descriptor Set Binding

vkCmdBindDescriptorSetsBinds descriptor sets to a command buffer
vkCmdBindDescriptorSets2KHRBinds descriptor sets to a command buffer
VkBindDescriptorSetsInfoKHRStructure specifying a descriptor set binding operation

Push Descriptor Updates

vkCmdPushDescriptorSetKHRPushes descriptor updates into a command buffer
vkCmdPushDescriptorSet2KHRPushes descriptor updates into a command buffer
VkPushDescriptorSetInfoKHRStructure specifying a descriptor set push operation

Push Descriptor Updates With Descriptor Update Templates

vkCmdPushDescriptorSetWithTemplateKHRPushes descriptor updates into a command buffer using a descriptor update template
vkCmdPushDescriptorSetWithTemplate2KHRPushes descriptor updates into a command buffer using a descriptor update template
VkPushDescriptorSetWithTemplateInfoKHRStructure specifying a descriptor set push operation using a descriptor update template

Push Constant Updates

As described above in section Pipeline Layouts, the pipeline layout defines shader push constants which are updated via Vulkan commands rather than via writes to memory or copy commands.

Push constants represent a high speed path to modify constant data in pipelines that is expected to outperform memory-backed resource updates.

vkCmdPushConstantsUpdate the values of push constants
vkCmdPushConstants2KHRUpdate the values of push constants
VkPushConstantsInfoKHRStructure specifying a push constant update operation

Physical Storage Buffer Access

vkGetBufferDeviceAddressQuery an address of a buffer
VkBufferDeviceAddressInfoStructure specifying the buffer to query an address for
vkGetBufferOpaqueCaptureAddressQuery an opaque capture address of a buffer
VkStridedDeviceAddressRegionKHRStructure specifying a region of device addresses with a stride

Descriptor Buffers

If the descriptorBuffer feature is enabled, an alternative way to specify descriptor sets is via buffers, rather than descriptor set objects.

Putting Descriptors in Memory

Commands are provided to retrieve descriptor data, and also to locate where in memory that data must be written to match the given descriptor set layout.

vkGetDescriptorSetLayoutSizeEXTGet the size of a descriptor set layout in memory
vkGetDescriptorSetLayoutBindingOffsetEXTGet the offset of a binding within a descriptor set layout
vkGetDescriptorEXTTo get a descriptor to place in a buffer
VkDescriptorGetInfoEXTStructure specifying parameters of descriptor to get
VkDescriptorDataEXTStructure specifying descriptor data
VkDescriptorAddressInfoEXTStructure specifying descriptor buffer address info

Immutable samplers specified in a descriptor set layout through pImmutableSamplers must be provided by applications when obtaining descriptor data. Immutable samplers written in a descriptor buffer must have identical parameters to the immutable samplers in the descriptor set layout that consumes the sampler.

If the descriptor set layout was created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT, there is no buffer backing for the immutable sampler, so this requirement does not exist. The implementation handles allocation of these descriptors internally.

As descriptors are now in regular memory, drivers cannot hide copies of immutable samplers that end up in descriptor sets from the application. As such, applications are required to provide these samplers as if they were not provided immutably.

Binding Descriptor Buffers

Descriptor buffers have their own separate binding point on the command buffer, with buffers bound using vkCmdBindDescriptorBuffersEXT. vkCmdSetDescriptorBufferOffsetsEXT assigns pairs of buffer binding indices and buffer offsets to the same binding point on the command buffer as vkCmdBindDescriptorSets, allowing subsequent bound pipeline commands to use the specified descriptor buffers. Bindings applied via vkCmdBindDescriptorSets cannot exist simultaneously with those applied via calls to vkCmdSetDescriptorBufferOffsetsEXT or vkCmdBindDescriptorBufferEmbeddedSamplersEXT, as calls to vkCmdSetDescriptorBufferOffsetsEXT or vkCmdBindDescriptorBufferEmbeddedSamplersEXT invalidate any bindings by previous calls to vkCmdBindDescriptorSets and vice-versa.

vkCmdBindDescriptorBuffersEXTBinding descriptor buffers to a command buffer
VkDescriptorBufferBindingInfoEXTStructure specifying descriptor buffer binding information
VkDescriptorBufferBindingPushDescriptorBufferHandleEXTStructure specifying push descriptor buffer binding information
vkCmdSetDescriptorBufferOffsetsEXTSetting descriptor buffer offsets in a command buffer
vkCmdSetDescriptorBufferOffsets2EXTSetting descriptor buffer offsets in a command buffer
VkSetDescriptorBufferOffsetsInfoEXTStructure specifying descriptor buffer offsets to set in a command buffer
vkCmdBindDescriptorBufferEmbeddedSamplersEXTSetting embedded immutable samplers offsets in a command buffer
vkCmdBindDescriptorBufferEmbeddedSamplers2EXTSetting embedded immutable samplers offsets in a command buffer
VkBindDescriptorBufferEmbeddedSamplersInfoEXTStructure specifying embedded immutable sampler offsets to set in a command buffer

Updating Descriptor Buffers

Updates to descriptor data in buffers can be performed by any operation on either the host or device that can access memory.

Descriptor buffer reads can be synchronized using VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT in the relevant shader stage.

Push Descriptors With Descriptor Buffers

If the descriptorBufferPushDescriptors feature is enabled, push descriptors can be used with descriptor buffers in the same way as with descriptor sets.

The VkPhysicalDeviceDescriptorBufferPropertiesEXT::bufferlessPushDescriptors property indicates whether the implementation requires a buffer to back push descriptors. If the property is VK_FALSE then before recording any push descriptors the application must bind exactly 1 descriptor buffer that was created with the VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT bit set. When this buffer is bound any previously recorded push descriptors that are required for a subsequent command must be recorded again.

Capture and Replay

In a similar way to bufferDeviceAddressCaptureReplay, the descriptorBufferCaptureReplay feature allows the creation of opaque handles for objects at capture time that can be passed into object creation calls in a future replay, causing descriptors to be created with the same data. The opaque memory address for any memory used by these resources must have been captured using vkGetDeviceMemoryOpaqueCaptureAddress and be replayed using VkMemoryOpaqueCaptureAddressAllocateInfo.

vkGetBufferOpaqueCaptureDescriptorDataEXTGet buffer opaque capture descriptor data
VkBufferCaptureDescriptorDataInfoEXTStructure specifying a buffer for descriptor capture
vkGetImageOpaqueCaptureDescriptorDataEXTGet image opaque capture descriptor data
VkImageCaptureDescriptorDataInfoEXTStructure specifying an image for descriptor capture
vkGetImageViewOpaqueCaptureDescriptorDataEXTGet image view opaque capture descriptor data
VkImageViewCaptureDescriptorDataInfoEXTStructure specifying an image view for descriptor capture
vkGetSamplerOpaqueCaptureDescriptorDataEXTGet sampler opaque capture descriptor data
VkSamplerCaptureDescriptorDataInfoEXTStructure specifying a sampler for descriptor capture
vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXTGet acceleration structure opaque capture descriptor data
VkAccelerationStructureCaptureDescriptorDataInfoEXTStructure specifying an acceleration structure for descriptor capture
VkOpaqueCaptureDescriptorDataCreateInfoEXTStructure specifying opaque capture descriptor data