Author: The Khronos® Vulkan Working Group

# Vulkan® 1.3.246 - A Specification (with all registered extensions)

The Khronos® Vulkan Working Group
version 1.3.246, 2023-03-31 13:37:21Z
from git branch: Git branch not available commit: Git commit not available

Loading… please wait.

Search:

## 14. 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.

### 14.1. 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.

#### 14.1.1. 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.

#### 14.1.2. 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.

#### 14.1.3. 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:

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

#### 14.1.4. 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`

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

#### 14.1.5. 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`

#### 14.1.6. 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.

#### 14.1.7. 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.

| Note Atomic operations can only be performed on members of certain types as defined in the SPIR-V environment appendix.

#### 14.1.8. 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.

#### 14.1.9. 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.

#### 14.1.10. 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.

#### 14.1.11. 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.

#### 14.1.12. 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.

#### 14.1.13. 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.

#### 14.1.14. 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`

#### 14.1.15. 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.

#### 14.1.16. 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 VkMutableDescriptorTypeCreateInfoEXT::`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.

| Note To find which descriptor types are supported as `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the application can use vkGetDescriptorSetLayoutSupport with an `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` binding, with the list of descriptor types to query in the VkMutableDescriptorTypeCreateInfoEXT::`pDescriptorTypes` array for that binding.

| Note 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.

### 14.2. 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.

#### 14.2.1. Descriptor Set Layout

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 `VkDescriptorSetLayout` handles:

    // Provided by VK_VERSION_1_0
    VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout)

To create descriptor set layout objects, call:

    // Provided by VK_VERSION_1_0
    VkResult vkCreateDescriptorSetLayout(
        VkDevice                                    device,
        const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkDescriptorSetLayout*                      pSetLayout);

- `device` is the logical device that creates the descriptor set layout.

- `pCreateInfo` is a pointer to a VkDescriptorSetLayoutCreateInfo structure specifying the state of the descriptor set layout object.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

- `pSetLayout` is a pointer to a VkDescriptorSetLayout handle in which the resulting descriptor set layout object is returned.

Valid Usage (Implicit)

- VUID-vkCreateDescriptorSetLayout-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkCreateDescriptorSetLayout-pCreateInfo-parameter
  `pCreateInfo` must be a valid pointer to a valid VkDescriptorSetLayoutCreateInfo structure

- VUID-vkCreateDescriptorSetLayout-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkCreateDescriptorSetLayout-pSetLayout-parameter
  `pSetLayout` must be a valid pointer to a VkDescriptorSetLayout handle

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

Information about the descriptor set layout is passed in a `VkDescriptorSetLayoutCreateInfo` structure:

    // Provided by VK_VERSION_1_0
    typedef struct VkDescriptorSetLayoutCreateInfo {
        VkStructureType                        sType;
        const void*                            pNext;
        VkDescriptorSetLayoutCreateFlags       flags;
        uint32_t                               bindingCount;
        const VkDescriptorSetLayoutBinding*    pBindings;
    } VkDescriptorSetLayoutCreateInfo;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `flags` is a bitmask of VkDescriptorSetLayoutCreateFlagBits specifying options for descriptor set layout creation.

- `bindingCount` is the number of elements in `pBindings`.

- `pBindings` is a pointer to an array of VkDescriptorSetLayoutBinding structures.

Valid Usage

- VUID-VkDescriptorSetLayoutCreateInfo-binding-00279
  The VkDescriptorSetLayoutBinding::`binding` members of the elements of the `pBindings` array must each have different values

- VUID-VkDescriptorSetLayoutCreateInfo-flags-00280
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`, then all elements of `pBindings` must not have a `descriptorType` of `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-02208
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`, then all elements of `pBindings` must not have a `descriptorType` of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-00281
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`, then the total number of elements of all bindings must be less than or equal to VkPhysicalDevicePushDescriptorPropertiesKHR::`maxPushDescriptors`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-04590
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`, `flags` must not contain `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-04591
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`, `pBindings` must not have a `descriptorType` of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-03000
  If any binding has the `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` bit set, `flags` must include `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT`

- VUID-VkDescriptorSetLayoutCreateInfo-descriptorType-03001
  If any binding has the `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` bit set, then all bindings must not have `descriptorType` of `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-04592
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT`, `flags` must not contain `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT`

- VUID-VkDescriptorSetLayoutCreateInfo-pBindings-07303
  If any element `pBindings`[i] has a `descriptorType` of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, then a VkMutableDescriptorTypeCreateInfoEXT must be present in the `pNext` chain, and `mutableDescriptorTypeListCount` must be greater than i

- VUID-VkDescriptorSetLayoutCreateInfo-descriptorType-04594
  If a binding has a `descriptorType` value of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, then `pImmutableSamplers` must be `NULL`

- VUID-VkDescriptorSetLayoutCreateInfo-mutableDescriptorType-04595
  If VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT::`mutableDescriptorType` is not enabled, `pBindings` must not contain a `descriptorType` of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-04596
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT`, VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT::`mutableDescriptorType` must be enabled

- VUID-VkDescriptorSetLayoutCreateInfo-flags-08000
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT`, then all elements of `pBindings` must not have a `descriptorType` of `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-08001
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT`, `flags` must also contain `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-08002
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT`, then `flags` must not contain `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT`

- VUID-VkDescriptorSetLayoutCreateInfo-flags-08003
  If `flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT`, then `flags` must not contain `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE`

Valid Usage (Implicit)

- VUID-VkDescriptorSetLayoutCreateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO`

- VUID-VkDescriptorSetLayoutCreateInfo-pNext-pNext
  Each `pNext` member of any structure (including this one) in the `pNext` chain must be either `NULL` or a pointer to a valid instance of VkDescriptorSetLayoutBindingFlagsCreateInfo or VkMutableDescriptorTypeCreateInfoEXT

- VUID-VkDescriptorSetLayoutCreateInfo-sType-unique
  The `sType` value of each struct in the `pNext` chain must be unique

- VUID-VkDescriptorSetLayoutCreateInfo-flags-parameter
  `flags` must be a valid combination of VkDescriptorSetLayoutCreateFlagBits values

- VUID-VkDescriptorSetLayoutCreateInfo-pBindings-parameter
  If `bindingCount` is not `0`, `pBindings` must be a valid pointer to an array of `bindingCount` valid VkDescriptorSetLayoutBinding structures

If the `pNext` chain of a VkDescriptorSetLayoutCreateInfo or VkDescriptorPoolCreateInfo structure includes a VkMutableDescriptorTypeCreateInfoEXT structure, then that structure specifies Information about the possible descriptor types for mutable descriptor types.

The `VkMutableDescriptorTypeCreateInfoEXT` structure is defined as:

    // Provided by VK_EXT_mutable_descriptor_type
    typedef struct VkMutableDescriptorTypeCreateInfoEXT {
        VkStructureType                          sType;
        const void*                              pNext;
        uint32_t                                 mutableDescriptorTypeListCount;
        const VkMutableDescriptorTypeListEXT*    pMutableDescriptorTypeLists;
    } VkMutableDescriptorTypeCreateInfoEXT;

or the equivalent

    // Provided by VK_VALVE_mutable_descriptor_type
    typedef VkMutableDescriptorTypeCreateInfoEXT VkMutableDescriptorTypeCreateInfoVALVE;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `mutableDescriptorTypeListCount` is the number of elements in `pMutableDescriptorTypeLists`.

- `pMutableDescriptorTypeLists` is a pointer to an array of `VkMutableDescriptorTypeListEXT` structures.

If `mutableDescriptorTypeListCount` is zero or if this structure is not included in the `pNext` chain, the VkMutableDescriptorTypeListEXT for each element is considered to be zero or `NULL` for each member. Otherwise, the descriptor set layout binding at VkDescriptorSetLayoutCreateInfo::`pBindings`[i] uses the descriptor type lists in VkMutableDescriptorTypeCreateInfoEXT::`pMutableDescriptorTypeLists`[i].

Valid Usage (Implicit)

- VUID-VkMutableDescriptorTypeCreateInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT`

- VUID-VkMutableDescriptorTypeCreateInfoEXT-pMutableDescriptorTypeLists-parameter
  If `mutableDescriptorTypeListCount` is not `0`, `pMutableDescriptorTypeLists` must be a valid pointer to an array of `mutableDescriptorTypeListCount` valid VkMutableDescriptorTypeListEXT structures

The list of potential descriptor types a given mutable descriptor can mutate to is passed in a `VkMutableDescriptorTypeListEXT` structure.

The `VkMutableDescriptorTypeListEXT` structure is defined as:

    // Provided by VK_EXT_mutable_descriptor_type
    typedef struct VkMutableDescriptorTypeListEXT {
        uint32_t                   descriptorTypeCount;
        const VkDescriptorType*    pDescriptorTypes;
    } VkMutableDescriptorTypeListEXT;

or the equivalent

    // Provided by VK_VALVE_mutable_descriptor_type
    typedef VkMutableDescriptorTypeListEXT VkMutableDescriptorTypeListVALVE;

- `descriptorTypeCount` is the number of elements in `pDescriptorTypes`.

- `pDescriptorTypes` is `NULL` or a pointer to an array of `descriptorTypeCount` VkDescriptorType values defining which descriptor types a given binding may mutate to.

Valid Usage

- VUID-VkMutableDescriptorTypeListEXT-descriptorTypeCount-04597
  `descriptorTypeCount` must not be `0` if the corresponding binding is of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

- VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04598
  `pDescriptorTypes` must be a valid pointer to an array of `descriptorTypeCount` valid, unique VkDescriptorType values if the given binding is of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` type

- VUID-VkMutableDescriptorTypeListEXT-descriptorTypeCount-04599
  `descriptorTypeCount` must be `0` if the corresponding binding is not of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

- VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04600
  `pDescriptorTypes` must not contain `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

- VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04601
  `pDescriptorTypes` must not contain `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`

- VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04602
  `pDescriptorTypes` must not contain `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`

- VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-04603
  `pDescriptorTypes` must not contain `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`

Valid Usage (Implicit)

- VUID-VkMutableDescriptorTypeListEXT-pDescriptorTypes-parameter
  If `descriptorTypeCount` is not `0`, `pDescriptorTypes` must be a valid pointer to an array of `descriptorTypeCount` valid VkDescriptorType values

Bits which can be set in VkDescriptorSetLayoutCreateInfo::`flags`, specifying options for descriptor set layout, are:

    // Provided by VK_VERSION_1_0
    typedef enum VkDescriptorSetLayoutCreateFlagBits {
      // Provided by VK_VERSION_1_2
        VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002,
      // Provided by VK_KHR_push_descriptor
        VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
      // Provided by VK_EXT_descriptor_buffer
        VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT = 0x00000010,
      // Provided by VK_EXT_descriptor_buffer
        VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT = 0x00000020,
      // Provided by VK_EXT_mutable_descriptor_type
        VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT = 0x00000004,
      // Provided by VK_EXT_descriptor_indexing
        VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
      // Provided by VK_VALVE_mutable_descriptor_type
        VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE = VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT,
    } VkDescriptorSetLayoutCreateFlagBits;

- `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR` specifies that descriptor sets must not be allocated using this layout, and descriptors are instead pushed by vkCmdPushDescriptorSetKHR.

- `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` specifies that descriptor sets using this layout must be allocated from a descriptor pool created with the `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` bit set. Descriptor set layouts created with this bit set have alternate limits for the maximum number of descriptors per-stage and per-pipeline layout. The non-UpdateAfterBind limits only count descriptors in sets created without this flag. The UpdateAfterBind limits count all descriptors, but the limits may be higher than the non-UpdateAfterBind limits.

- `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT` specifies that this layout must only be used with descriptor buffers.

- `VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT` specifies that this is a layout only containing immutable samplers that can be bound by vkCmdBindDescriptorBufferEmbeddedSamplersEXT. Unlike normal immutable samplers, embedded immutable samplers do not require the application to provide them in a descriptor buffer.

- `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT` specifies that descriptor sets using this layout must be allocated from a descriptor pool created with the `VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT` bit set. Descriptor set layouts created with this bit have no expressible limit for maximum number of descriptors per-stage. Host descriptor sets are limited only by available host memory, but may be limited for implementation specific reasons. Implementations may limit the number of supported descriptors to UpdateAfterBind limits or non-UpdateAfterBind limits, whichever is larger.

    // Provided by VK_VERSION_1_0
    typedef VkFlags VkDescriptorSetLayoutCreateFlags;

`VkDescriptorSetLayoutCreateFlags` is a bitmask type for setting a mask of zero or more VkDescriptorSetLayoutCreateFlagBits.

The `VkDescriptorSetLayoutBinding` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkDescriptorSetLayoutBinding {
        uint32_t              binding;
        VkDescriptorType      descriptorType;
        uint32_t              descriptorCount;
        VkShaderStageFlags    stageFlags;
        const VkSampler*      pImmutableSamplers;
    } VkDescriptorSetLayoutBinding;

- `binding` is the binding number of this entry and corresponds to a resource of the same binding number in the shader stages.

- `descriptorType` is a VkDescriptorType specifying which type of resource descriptors are used for this binding.

- `descriptorCount` is the number of descriptors contained in the binding, accessed in a shader as an array, except if `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` in which case `descriptorCount` is the size in bytes of the inline uniform block. If `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.

- `stageFlags` member is a bitmask of VkShaderStageFlagBits specifying which pipeline shader stages can access a resource for this binding. `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 `stageFlags`, then a resource must not be accessed from that stage via this binding within any pipeline using the set layout. Other than input attachments which are limited to the fragment shader, there are no limitations on what combinations of stages can use a descriptor binding, and in particular a binding can be used by both graphics stages and the compute stage.

- `pImmutableSamplers` affects initialization of samplers. If `descriptorType` specifies a `VK_DESCRIPTOR_TYPE_SAMPLER` or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` type descriptor, then `pImmutableSamplers` can be used to initialize a set of immutable samplers. Immutable samplers are permanently bound into the set layout and must not be changed; updating a `VK_DESCRIPTOR_TYPE_SAMPLER` descriptor with immutable samplers is not allowed and updates to a `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` descriptor with immutable samplers does not modify the samplers (the image views are updated, but the sampler updates are ignored). If `pImmutableSamplers` is not `NULL`, then it is a pointer to an array of sampler handles that will be copied into the set layout and used for the corresponding binding. Only the sampler handles are copied; the sampler objects must not be destroyed before the final use of the set layout and any descriptor pools and sets created using it. If `pImmutableSamplers` is `NULL`, then the sampler slots are dynamic and sampler handles must be bound into descriptor sets using this layout. If `descriptorType` is not one of these descriptor types, then `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 `pBindings` array. Bindings that are not specified have a `descriptorCount` and `stageFlags` of zero, and the value of `descriptorType` is undefined. However, all binding numbers between 0 and the maximum binding number in the VkDescriptorSetLayoutCreateInfo::`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 The maximum binding number specified should be as compact as possible to avoid wasted memory.

Valid Usage

- VUID-VkDescriptorSetLayoutBinding-descriptorType-00282
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLER` or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and `descriptorCount` is not `0` and `pImmutableSamplers` is not `NULL`, `pImmutableSamplers` must be a valid pointer to an array of `descriptorCount` valid `VkSampler` handles

- VUID-VkDescriptorSetLayoutBinding-descriptorType-04604
  If the `inlineUniformBlock` feature is not enabled, `descriptorType` must not be `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`

- VUID-VkDescriptorSetLayoutBinding-descriptorType-02209
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `descriptorCount` must be a multiple of `4`

- VUID-VkDescriptorSetLayoutBinding-descriptorType-08004
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` and VkDescriptorSetLayoutCreateInfo::`flags` does not contain `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT` then `descriptorCount` must be less than or equal to `VkPhysicalDeviceInlineUniformBlockPropertiesEXT`::`maxInlineUniformBlockSize`

- VUID-VkDescriptorSetLayoutBinding-flags-08005
  If VkDescriptorSetLayoutCreateInfo::`flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT`, `descriptorType` must be `VK_DESCRIPTOR_TYPE_SAMPLER`

- VUID-VkDescriptorSetLayoutBinding-flags-08006
  If VkDescriptorSetLayoutCreateInfo::`flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT`, `descriptorCount` must less than or equal to `1`

- VUID-VkDescriptorSetLayoutBinding-flags-08007
  If VkDescriptorSetLayoutCreateInfo::`flags` contains `VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT`, and `descriptorCount` is equal to `1`, `pImmutableSamplers` must not be `NULL`

- VUID-VkDescriptorSetLayoutBinding-descriptorCount-00283
  If `descriptorCount` is not `0`, `stageFlags` must be a valid combination of VkShaderStageFlagBits values

- VUID-VkDescriptorSetLayoutBinding-descriptorType-01510
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT` and `descriptorCount` is not `0`, then `stageFlags` must be `0` or `VK_SHADER_STAGE_FRAGMENT_BIT`

- VUID-VkDescriptorSetLayoutBinding-pImmutableSamplers-04009
  The sampler objects indicated by `pImmutableSamplers` must not have a `borderColor` with one of the values `VK_BORDER_COLOR_FLOAT_CUSTOM_EXT` or `VK_BORDER_COLOR_INT_CUSTOM_EXT`

- VUID-VkDescriptorSetLayoutBinding-descriptorType-04605
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, then `pImmutableSamplers` must be `NULL`

Valid Usage (Implicit)

- VUID-VkDescriptorSetLayoutBinding-descriptorType-parameter
  `descriptorType` must be a valid VkDescriptorType value

If the `pNext` chain of a VkDescriptorSetLayoutCreateInfo structure includes a VkDescriptorSetLayoutBindingFlagsCreateInfo structure, then that structure includes an array of flags, one for each descriptor set layout binding.

The VkDescriptorSetLayoutBindingFlagsCreateInfo structure is defined as:

    // Provided by VK_VERSION_1_2
    typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo {
        VkStructureType                    sType;
        const void*                        pNext;
        uint32_t                           bindingCount;
        const VkDescriptorBindingFlags*    pBindingFlags;
    } VkDescriptorSetLayoutBindingFlagsCreateInfo;

or the equivalent

    // Provided by VK_EXT_descriptor_indexing
    typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `bindingCount` is zero or the number of elements in `pBindingFlags`.

- `pBindingFlags` is a pointer to an array of VkDescriptorBindingFlags bitfields, one for each descriptor set layout binding.

If `bindingCount` is zero or if this structure is not included in the `pNext` chain, the VkDescriptorBindingFlags for each descriptor set layout binding is considered to be zero. Otherwise, the descriptor set layout binding at VkDescriptorSetLayoutCreateInfo::`pBindings`[i] uses the flags in `pBindingFlags`[i].

Valid Usage

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-bindingCount-03002
  If `bindingCount` is not zero, `bindingCount` must equal VkDescriptorSetLayoutCreateInfo::`bindingCount`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-flags-03003
  If VkDescriptorSetLayoutCreateInfo::`flags` includes `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`, then all elements of `pBindingFlags` must not include `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`, `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT`, or `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004
  If an element of `pBindingFlags` includes `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`, then all other elements of VkDescriptorSetLayoutCreateInfo::`pBindings` must have a smaller value of `binding`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingUniformBufferUpdateAfterBind-03005
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingUniformBufferUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingSampledImageUpdateAfterBind-03006
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingSampledImageUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_SAMPLER`, `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, or `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageImageUpdateAfterBind-03007
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingStorageImageUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingStorageBufferUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingUniformTexelBufferUpdateAfterBind-03009
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingUniformTexelBufferUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageTexelBufferUpdateAfterBind-03010
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingStorageTexelBufferUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingInlineUniformBlockUpdateAfterBind-02211
  If VkPhysicalDeviceInlineUniformBlockFeatures::`descriptorBindingInlineUniformBlockUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingAccelerationStructureUpdateAfterBind-03570
  If VkPhysicalDeviceAccelerationStructureFeaturesKHR::`descriptorBindingAccelerationStructureUpdateAfterBind` is not enabled, all bindings with descriptor type `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR` or `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-None-03011
  All bindings with descriptor type `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` must not use `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingUpdateUnusedWhilePending-03012
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingUpdateUnusedWhilePending` is not enabled, all elements of `pBindingFlags` must not include `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingPartiallyBound-03013
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingPartiallyBound` is not enabled, all elements of `pBindingFlags` must not include `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingVariableDescriptorCount-03014
  If VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingVariableDescriptorCount` is not enabled, all elements of `pBindingFlags` must not include `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03015
  If an element of `pBindingFlags` includes `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`, that element’s `descriptorType` must not be `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`

Valid Usage (Implicit)

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO`

- VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-parameter
  If `bindingCount` is not `0`, `pBindingFlags` must be a valid pointer to an array of `bindingCount` valid combinations of VkDescriptorBindingFlagBits values

Bits which can be set in each element of VkDescriptorSetLayoutBindingFlagsCreateInfo::`pBindingFlags`, specifying options for the corresponding descriptor set layout binding, are:

    // Provided by VK_VERSION_1_2
    typedef enum VkDescriptorBindingFlagBits {
        VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001,
        VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002,
        VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004,
        VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008,
      // Provided by VK_EXT_descriptor_indexing
        VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
      // Provided by VK_EXT_descriptor_indexing
        VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
      // Provided by VK_EXT_descriptor_indexing
        VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
      // Provided by VK_EXT_descriptor_indexing
        VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
    } VkDescriptorBindingFlagBits;

or the equivalent

    // Provided by VK_EXT_descriptor_indexing
    typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT;

- `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` indicates that if descriptors in this binding are updated between when the descriptor set is bound in a command buffer and when that command buffer is submitted to a queue, then the submission will use the most recently set descriptors for this binding and the updates do not invalidate the command buffer. Descriptor bindings created with this flag are also partially exempt from the external synchronization requirement in vkUpdateDescriptorSetWithTemplateKHR and vkUpdateDescriptorSets. Multiple descriptors with this flag set can be updated concurrently in different threads, though the same descriptor must not be updated concurrently by two threads. Descriptors with this flag set can be updated concurrently with the set being bound to a command buffer in another thread, but not concurrently with the set being reset or freed.

- `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT` indicates that descriptors in this binding that are not dynamically used need not contain valid descriptors at the time the descriptors are consumed. A descriptor is dynamically used if any shader invocation executes an instruction that performs any memory access using the descriptor. If a descriptor is not dynamically used, any resource referenced by the descriptor is not considered to be referenced during command execution.

- `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT` indicates that descriptors in this binding can be updated after a command buffer has bound this descriptor set, or while a command buffer that uses this descriptor set is pending execution, as long as the descriptors that are updated are not used by those command buffers. Descriptor bindings created with this flag are also partially exempt from the external synchronization requirement in vkUpdateDescriptorSetWithTemplateKHR and vkUpdateDescriptorSets in the same way as for `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`. If `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT` is also set, then descriptors can be updated as long as they are not dynamically used by any shader invocations. If `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT` is not set, then descriptors can be updated as long as they are not statically used by any shader invocations.

- `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT` indicates that this is a variable-sized descriptor binding whose size will be specified when a descriptor set is allocated using this layout. The value of `descriptorCount` is treated as an upper bound on the size of the binding. This must only be used for the last binding in the descriptor set layout (i.e. the binding with the largest value of `binding`). For the purposes of counting against limits such as `maxDescriptorSet`* and `maxPerStageDescriptor`*, the full value of `descriptorCount` is counted, except for descriptor bindings with a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, when VkDescriptorSetLayoutCreateInfo::`flags` does not contain `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT`. In this case, `descriptorCount` specifies the upper bound on the byte size of the binding; thus it counts against the `maxInlineUniformBlockSize` and `maxInlineUniformTotalSize` limits instead.

| Note Note that while `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` and `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT` both involve updates to descriptor sets after they are bound, `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT` is a weaker requirement since it is only about descriptors that are not used, whereas `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` requires the implementation to observe updates to descriptors that are used.

    // Provided by VK_VERSION_1_2
    typedef VkFlags VkDescriptorBindingFlags;

or the equivalent

    // Provided by VK_EXT_descriptor_indexing
    typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT;

`VkDescriptorBindingFlags` is a bitmask type for setting a mask of zero or more VkDescriptorBindingFlagBits.

To query information about whether a descriptor set layout can be created, call:

    // Provided by VK_VERSION_1_1
    void vkGetDescriptorSetLayoutSupport(
        VkDevice                                    device,
        const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
        VkDescriptorSetLayoutSupport*               pSupport);

or the equivalent command

    // Provided by VK_KHR_maintenance3
    void vkGetDescriptorSetLayoutSupportKHR(
        VkDevice                                    device,
        const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
        VkDescriptorSetLayoutSupport*               pSupport);

- `device` is the logical device that would create the descriptor set layout.

- `pCreateInfo` is a pointer to a VkDescriptorSetLayoutCreateInfo structure specifying the state of the descriptor set layout object.

- `pSupport` is a pointer to a VkDescriptorSetLayoutSupport structure, in which information about support for the descriptor set layout object is returned.

Some implementations have limitations on what fits in a descriptor set which are not easily expressible in terms of existing limits like `maxDescriptorSet`*, for example if all descriptor types share a limited space in memory but each descriptor is a different size or alignment. This command returns information about whether a descriptor set satisfies this limit. If the descriptor set layout satisfies the VkPhysicalDeviceMaintenance3Properties::`maxPerSetDescriptors` limit, this command is guaranteed to return `VK_TRUE` in VkDescriptorSetLayoutSupport::`supported`. If the descriptor set layout exceeds the VkPhysicalDeviceMaintenance3Properties::`maxPerSetDescriptors` limit, whether the descriptor set layout is supported is implementation-dependent and may depend on whether the descriptor sizes and alignments cause the layout to exceed an internal limit.

This command does not consider other limits such as `maxPerStageDescriptor`*, and so a descriptor set layout that is supported according to this command must still satisfy the pipeline layout limits such as `maxPerStageDescriptor`* in order to be used in a pipeline layout.

| Note This is a `VkDevice` query rather than `VkPhysicalDevice` because the answer may depend on enabled features.

Valid Usage (Implicit)

- VUID-vkGetDescriptorSetLayoutSupport-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetDescriptorSetLayoutSupport-pCreateInfo-parameter
  `pCreateInfo` must be a valid pointer to a valid VkDescriptorSetLayoutCreateInfo structure

- VUID-vkGetDescriptorSetLayoutSupport-pSupport-parameter
  `pSupport` must be a valid pointer to a VkDescriptorSetLayoutSupport structure

Information about support for the descriptor set layout is returned in a `VkDescriptorSetLayoutSupport` structure:

    // Provided by VK_VERSION_1_1
    typedef struct VkDescriptorSetLayoutSupport {
        VkStructureType    sType;
        void*              pNext;
        VkBool32           supported;
    } VkDescriptorSetLayoutSupport;

or the equivalent

    // Provided by VK_KHR_maintenance3
    typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `supported` specifies whether the descriptor set layout can be created.

`supported` is set to `VK_TRUE` if the descriptor set can be created, or else is set to `VK_FALSE`.

Valid Usage (Implicit)

- VUID-VkDescriptorSetLayoutSupport-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT`

- VUID-VkDescriptorSetLayoutSupport-pNext-pNext
  `pNext` must be `NULL` or a pointer to a valid instance of VkDescriptorSetVariableDescriptorCountLayoutSupport

- VUID-VkDescriptorSetLayoutSupport-sType-unique
  The `sType` value of each struct in the `pNext` chain must be unique

If the `pNext` chain of a VkDescriptorSetLayoutSupport structure includes a `VkDescriptorSetVariableDescriptorCountLayoutSupport` structure, then that structure returns additional information about whether the descriptor set layout is supported.

    // Provided by VK_VERSION_1_2
    typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport {
        VkStructureType    sType;
        void*              pNext;
        uint32_t           maxVariableDescriptorCount;
    } VkDescriptorSetVariableDescriptorCountLayoutSupport;

or the equivalent

    // Provided by VK_EXT_descriptor_indexing
    typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `maxVariableDescriptorCount` indicates the maximum number of descriptors supported in the highest numbered binding of the layout, if that binding is variable-sized. If the highest numbered binding of the layout has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `maxVariableDescriptorCount` indicates the maximum byte size supported for the binding, if that binding is variable-sized.

If the VkDescriptorSetLayoutCreateInfo structure specified in vkGetDescriptorSetLayoutSupport::`pCreateInfo` includes a variable-sized descriptor, then `supported` is determined assuming the requested size of the variable-sized descriptor, and `maxVariableDescriptorCount` is set to the maximum size of that descriptor that can be successfully created (which is greater than or equal to the requested size passed in). If the VkDescriptorSetLayoutCreateInfo structure does not include a variable-sized descriptor, or if the VkPhysicalDeviceDescriptorIndexingFeatures::`descriptorBindingVariableDescriptorCount` feature is not enabled, then `maxVariableDescriptorCount` is set to zero. For the purposes of this command, a variable-sized descriptor binding with a `descriptorCount` of zero is treated as if the `descriptorCount` is one, and thus the binding is not ignored and the maximum descriptor count will be returned. If the layout is not supported, then the value written to `maxVariableDescriptorCount` is undefined.

Valid Usage (Implicit)

- VUID-VkDescriptorSetVariableDescriptorCountLayoutSupport-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT`

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
        {
            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[] =
    {
        // Information 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
        },

        // Information 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]);

To destroy a descriptor set layout, call:

    // Provided by VK_VERSION_1_0
    void vkDestroyDescriptorSetLayout(
        VkDevice                                    device,
        VkDescriptorSetLayout                       descriptorSetLayout,
        const VkAllocationCallbacks*                pAllocator);

- `device` is the logical device that destroys the descriptor set layout.

- `descriptorSetLayout` is the descriptor set layout to destroy.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

Valid Usage

- VUID-vkDestroyDescriptorSetLayout-descriptorSetLayout-00284
  If `VkAllocationCallbacks` were provided when `descriptorSetLayout` was created, a compatible set of callbacks must be provided here

- VUID-vkDestroyDescriptorSetLayout-descriptorSetLayout-00285
  If no `VkAllocationCallbacks` were provided when `descriptorSetLayout` was created, `pAllocator` must be `NULL`

Valid Usage (Implicit)

- VUID-vkDestroyDescriptorSetLayout-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkDestroyDescriptorSetLayout-descriptorSetLayout-parameter
  If `descriptorSetLayout` is not VK_NULL_HANDLE, `descriptorSetLayout` must be a valid VkDescriptorSetLayout handle

- VUID-vkDestroyDescriptorSetLayout-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkDestroyDescriptorSetLayout-descriptorSetLayout-parent
  If `descriptorSetLayout` is a valid handle, it must have been created, allocated, or retrieved from `device`

Host Synchronization

- Host access to `descriptorSetLayout` must be externally synchronized

#### 14.2.2. Pipeline Layouts

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 describing 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 `VkPipelineLayout` handles:

    // Provided by VK_VERSION_1_0
    VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout)

To create a pipeline layout, call:

    // Provided by VK_VERSION_1_0
    VkResult vkCreatePipelineLayout(
        VkDevice                                    device,
        const VkPipelineLayoutCreateInfo*           pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkPipelineLayout*                           pPipelineLayout);

- `device` is the logical device that creates the pipeline layout.

- `pCreateInfo` is a pointer to a VkPipelineLayoutCreateInfo structure specifying the state of the pipeline layout object.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

- `pPipelineLayout` is a pointer to a VkPipelineLayout handle in which the resulting pipeline layout object is returned.

Valid Usage (Implicit)

- VUID-vkCreatePipelineLayout-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkCreatePipelineLayout-pCreateInfo-parameter
  `pCreateInfo` must be a valid pointer to a valid VkPipelineLayoutCreateInfo structure

- VUID-vkCreatePipelineLayout-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkCreatePipelineLayout-pPipelineLayout-parameter
  `pPipelineLayout` must be a valid pointer to a VkPipelineLayout handle

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

The VkPipelineLayoutCreateInfo structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkPipelineLayoutCreateInfo {
        VkStructureType                 sType;
        const void*                     pNext;
        VkPipelineLayoutCreateFlags     flags;
        uint32_t                        setLayoutCount;
        const VkDescriptorSetLayout*    pSetLayouts;
        uint32_t                        pushConstantRangeCount;
        const VkPushConstantRange*      pPushConstantRanges;
    } VkPipelineLayoutCreateInfo;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `flags` is a bitmask of VkPipelineLayoutCreateFlagBits specifying options for pipeline layout creation.

- `setLayoutCount` is the number of descriptor sets included in the pipeline layout.

- `pSetLayouts` is a pointer to an array of `VkDescriptorSetLayout` objects.

- `pushConstantRangeCount` is the number of push constant ranges included in the pipeline layout.

- `pPushConstantRanges` is a pointer to an array of `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 Push constants represent a high speed path to modify constant data in pipelines that is expected to outperform memory-backed resource updates.

Valid Usage

- VUID-VkPipelineLayoutCreateInfo-setLayoutCount-00286
  `setLayoutCount` must be less than or equal to `VkPhysicalDeviceLimits`::`maxBoundDescriptorSets`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03016
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_SAMPLER` and `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPerStageDescriptorSamplers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03017
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` and `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPerStageDescriptorUniformBuffers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03018
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` and `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPerStageDescriptorStorageBuffers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-06939
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`, `VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM`, and `VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPerStageDescriptorSampledImages`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03020
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPerStageDescriptorStorageImages`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03021
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPerStageDescriptorInputAttachments`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-02214
  The total number of bindings in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceInlineUniformBlockProperties`::`maxPerStageDescriptorInlineUniformBlocks`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03022
  The total number of descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_SAMPLER` and `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxPerStageDescriptorUpdateAfterBindSamplers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03023
  The total number of descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` and `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxPerStageDescriptorUpdateAfterBindUniformBuffers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03024
  The total number of descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` and `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxPerStageDescriptorUpdateAfterBindStorageBuffers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03025
  The total number of descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, and `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxPerStageDescriptorUpdateAfterBindSampledImages`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03026
  The total number of descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxPerStageDescriptorUpdateAfterBindStorageImages`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03027
  The total number of descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxPerStageDescriptorUpdateAfterBindInputAttachments`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-02215
  The total number of bindings with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceInlineUniformBlockProperties`::`maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03028
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_SAMPLER` and `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetSamplers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03029
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetUniformBuffers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03030
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetUniformBuffersDynamic`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03031
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetStorageBuffers`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03032
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetStorageBuffersDynamic`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03033
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, and `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetSampledImages`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03034
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetStorageImages`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03035
  The total number of descriptors in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDescriptorSetInputAttachments`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-02216
  The total number of bindings in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceInlineUniformBlockProperties`::`maxDescriptorSetInlineUniformBlocks`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03036
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_SAMPLER` and `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindSamplers`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03037
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindUniformBuffers`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03038
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindUniformBuffersDynamic`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03039
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindStorageBuffers`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03040
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindStorageBuffersDynamic`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03041
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, and `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindSampledImages`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03042
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindStorageImages`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03043
  The total number of descriptors of the type `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceDescriptorIndexingProperties`::`maxDescriptorSetUpdateAfterBindInputAttachments`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-02217
  The total number of bindings with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceInlineUniformBlockProperties`::`maxDescriptorSetUpdateAfterBindInlineUniformBlocks`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-06531
  The total number of descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceVulkan13Properties`::`maxInlineUniformTotalSize`

- VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292
  Any two elements of `pPushConstantRanges` must not include the same stage in `stageFlags`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293
  `pSetLayouts` must not contain more than one descriptor set layout that was created with `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR` set

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03571
  The total number of bindings in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to VkPhysicalDeviceAccelerationStructurePropertiesKHR::`maxPerStageDescriptorAccelerationStructures`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03572
  The total number of bindings with a `descriptorType` of `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR` accessible to any given shader stage across all elements of `pSetLayouts` must be less than or equal to VkPhysicalDeviceAccelerationStructurePropertiesKHR::`maxPerStageDescriptorUpdateAfterBindAccelerationStructures`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03573
  The total number of bindings in descriptor set layouts created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set with a `descriptorType` of `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to VkPhysicalDeviceAccelerationStructurePropertiesKHR::`maxDescriptorSetAccelerationStructures`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-03574
  The total number of bindings with a `descriptorType` of `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to VkPhysicalDeviceAccelerationStructurePropertiesKHR::`maxDescriptorSetUpdateAfterBindAccelerationStructures`

- VUID-VkPipelineLayoutCreateInfo-descriptorType-02381
  The total number of bindings with a `descriptorType` of `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV` accessible across all shader stages and across all elements of `pSetLayouts` must be less than or equal to VkPhysicalDeviceRayTracingPropertiesNV::`maxDescriptorSetAccelerationStructures`

- VUID-VkPipelineLayoutCreateInfo-pImmutableSamplers-03566
  The total number of `pImmutableSamplers` created with `flags` containing `VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT` or `VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT` across all shader stages and across all elements of `pSetLayouts` must be less than or equal to `VkPhysicalDeviceFragmentDensityMap2PropertiesEXT`::`maxDescriptorSetSubsampledSamplers`

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-04606
  Any element of `pSetLayouts` must not have been created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT` bit set

- VUID-VkPipelineLayoutCreateInfo-graphicsPipelineLibrary-06753
  If `graphicsPipelineLibrary` is not enabled, elements of `pSetLayouts` must be valid VkDescriptorSetLayout objects

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-08008
  If any element of `pSetLayouts` was created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT` bit set, all elements of `pSetLayouts` must have been created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT` bit set

Valid Usage (Implicit)

- VUID-VkPipelineLayoutCreateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO`

- VUID-VkPipelineLayoutCreateInfo-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkPipelineLayoutCreateInfo-flags-parameter
  `flags` must be a valid combination of VkPipelineLayoutCreateFlagBits values

- VUID-VkPipelineLayoutCreateInfo-pSetLayouts-parameter
  If `setLayoutCount` is not `0`, `pSetLayouts` must be a valid pointer to an array of `setLayoutCount` valid or VK_NULL_HANDLE VkDescriptorSetLayout handles

- VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-parameter
  If `pushConstantRangeCount` is not `0`, `pPushConstantRanges` must be a valid pointer to an array of `pushConstantRangeCount` valid VkPushConstantRange structures

    // Provided by VK_EXT_graphics_pipeline_library
    typedef enum VkPipelineLayoutCreateFlagBits {
      // Provided by VK_EXT_graphics_pipeline_library
        VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002,
    } VkPipelineLayoutCreateFlagBits;

- `VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT` specifies that implementations must ensure that the properties and/or absence of a particular descriptor set do not influence any other properties of the pipeline layout. This allows pipelines libraries linked without `VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT` to be created with a subset of the total descriptor sets.

    // Provided by VK_VERSION_1_0
    typedef VkFlags VkPipelineLayoutCreateFlags;

`VkPipelineLayoutCreateFlags` is a bitmask type for setting a mask of VkPipelineLayoutCreateFlagBits.

The `VkPushConstantRange` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkPushConstantRange {
        VkShaderStageFlags    stageFlags;
        uint32_t              offset;
        uint32_t              size;
    } VkPushConstantRange;

- `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 return undefined values.

- `offset` and `size` are the start offset and size, respectively, consumed by the range. Both `offset` and `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

- VUID-VkPushConstantRange-offset-00294
  `offset` must be less than `VkPhysicalDeviceLimits`::`maxPushConstantsSize`

- VUID-VkPushConstantRange-offset-00295
  `offset` must be a multiple of `4`

- VUID-VkPushConstantRange-size-00296
  `size` must be greater than `0`

- VUID-VkPushConstantRange-size-00297
  `size` must be a multiple of `4`

- VUID-VkPushConstantRange-size-00298
  `size` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPushConstantsSize` minus `offset`

Valid Usage (Implicit)

- VUID-VkPushConstantRange-stageFlags-parameter
  `stageFlags` must be a valid combination of VkShaderStageFlagBits values

- VUID-VkPushConstantRange-stageFlags-requiredbitmask
  `stageFlags` must not be `0`

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 17. Pipeline Layout Resource Limits
Total Resources Available | Resource 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` | uniform buffer dynamic
`maxDescriptorSetStorageBuffers` or `maxDescriptorSetUpdateAfterBindStorageBuffers` | storage buffer
storage buffer dynamic
`maxDescriptorSetStorageBuffersDynamic` or `maxDescriptorSetUpdateAfterBindStorageBuffersDynamic` | storage buffer dynamic
`maxDescriptorSetInputAttachments` or `maxDescriptorSetUpdateAfterBindInputAttachments` | input attachment
`maxDescriptorSetInlineUniformBlocks` or `maxDescriptorSetUpdateAfterBindInlineUniformBlocks` | inline uniform block
`maxDescriptorSetAccelerationStructures` or `maxDescriptorSetUpdateAfterBindAccelerationStructures` | acceleration structure

To destroy a pipeline layout, call:

    // Provided by VK_VERSION_1_0
    void vkDestroyPipelineLayout(
        VkDevice                                    device,
        VkPipelineLayout                            pipelineLayout,
        const VkAllocationCallbacks*                pAllocator);

- `device` is the logical device that destroys the pipeline layout.

- `pipelineLayout` is the pipeline layout to destroy.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

Valid Usage

- VUID-vkDestroyPipelineLayout-pipelineLayout-00299
  If `VkAllocationCallbacks` were provided when `pipelineLayout` was created, a compatible set of callbacks must be provided here

- VUID-vkDestroyPipelineLayout-pipelineLayout-00300
  If no `VkAllocationCallbacks` were provided when `pipelineLayout` was created, `pAllocator` must be `NULL`

- VUID-vkDestroyPipelineLayout-pipelineLayout-02004
  `pipelineLayout` must not have been passed to any `vkCmd*` command for any command buffers that are still in the recording state when `vkDestroyPipelineLayout` is called

Valid Usage (Implicit)

- VUID-vkDestroyPipelineLayout-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkDestroyPipelineLayout-pipelineLayout-parameter
  If `pipelineLayout` is not VK_NULL_HANDLE, `pipelineLayout` must be a valid VkPipelineLayout handle

- VUID-vkDestroyPipelineLayout-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkDestroyPipelineLayout-pipelineLayout-parent
  If `pipelineLayout` is a valid handle, it must have been created, allocated, or retrieved from `device`

Host Synchronization

- Host access to `pipelineLayout` must be externally synchronized

##### 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.

Implementor’s Note

A consequence of layout compatibility is that when the implementation compiles a pipeline layout and maps pipeline resources to implementation resources, the mechanism for set N should only be a function of sets [0..N].

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

API example

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

    const VkPushConstantRange ranges[] =
    {
        {
            VK_SHADER_STAGE_VERTEX_BIT,    // stageFlags
            0,                             // offset
            4                              // size
        },

        {
            VK_SHADER_STAGE_FRAGMENT_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);

#### 14.2.3. Allocation of Descriptor Sets

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 `VkDescriptorPool` handles:

    // Provided by VK_VERSION_1_0
    VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)

To create a descriptor pool object, call:

    // Provided by VK_VERSION_1_0
    VkResult vkCreateDescriptorPool(
        VkDevice                                    device,
        const VkDescriptorPoolCreateInfo*           pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkDescriptorPool*                           pDescriptorPool);

- `device` is the logical device that creates the descriptor pool.

- `pCreateInfo` is a pointer to a VkDescriptorPoolCreateInfo structure specifying the state of the descriptor pool object.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

- `pDescriptorPool` is a pointer to a VkDescriptorPool handle in which the resulting descriptor pool object is returned.

The created descriptor pool is returned in `pDescriptorPool`.

Valid Usage (Implicit)

- VUID-vkCreateDescriptorPool-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkCreateDescriptorPool-pCreateInfo-parameter
  `pCreateInfo` must be a valid pointer to a valid VkDescriptorPoolCreateInfo structure

- VUID-vkCreateDescriptorPool-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkCreateDescriptorPool-pDescriptorPool-parameter
  `pDescriptorPool` must be a valid pointer to a VkDescriptorPool handle

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

  - `VK_ERROR_FRAGMENTATION_EXT`

Additional information about the pool is passed in a `VkDescriptorPoolCreateInfo` structure:

    // Provided by VK_VERSION_1_0
    typedef struct VkDescriptorPoolCreateInfo {
        VkStructureType                sType;
        const void*                    pNext;
        VkDescriptorPoolCreateFlags    flags;
        uint32_t                       maxSets;
        uint32_t                       poolSizeCount;
        const VkDescriptorPoolSize*    pPoolSizes;
    } VkDescriptorPoolCreateInfo;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `flags` is a bitmask of VkDescriptorPoolCreateFlagBits specifying certain supported operations on the pool.

- `maxSets` is the maximum number of descriptor sets that can be allocated from the pool.

- `poolSizeCount` is the number of elements in `pPoolSizes`.

- `pPoolSizes` is a pointer to an array of VkDescriptorPoolSize structures, each containing a descriptor type and number of descriptors of that type to be allocated in the pool.

If multiple `VkDescriptorPoolSize` structures containing the same descriptor type appear in the `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 `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.

If `flags` has the `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` bit set, descriptor pool creation may fail with the error `VK_ERROR_FRAGMENTATION` if the total number of descriptors across all pools (including this one) created with this bit set exceeds `maxUpdateAfterBindDescriptorsInAllPools`, or if fragmentation of the underlying hardware resources occurs.

If a `pPoolSizes`[i]::`type` is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, a VkMutableDescriptorTypeCreateInfoEXT struct in the `pNext` chain can be used to specify which mutable descriptor types can be allocated from the pool. If present in the `pNext` chain, VkMutableDescriptorTypeCreateInfoEXT::`pMutableDescriptorTypeLists`[i] specifies which kind of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` descriptors can be allocated from this pool entry. If VkMutableDescriptorTypeCreateInfoEXT does not exist in the `pNext` chain, or VkMutableDescriptorTypeCreateInfoEXT::`pMutableDescriptorTypeLists`[i] is out of range, the descriptor pool allocates enough memory to be able to allocate a `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` descriptor with any supported VkDescriptorType as a mutable descriptor. A mutable descriptor can be allocated from a pool entry if the type list in VkDescriptorSetLayoutCreateInfo is a subset of the type list declared in the descriptor pool, or if the pool entry is created without a descriptor type list. Multiple `pPoolSizes` entries with `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` can be declared. When multiple such pool entries are present in `pPoolSizes`, they specify sets of supported descriptor types which either fully overlap, partially overlap, or are disjoint. Two sets fully overlap if the sets of supported descriptor types are equal. If the sets are not disjoint they partially overlap. A pool entry without a `VkMutableDescriptorTypeListEXT` assigned to it is considered to partially overlap any other pool entry which has a `VkMutableDescriptorTypeListEXT` assigned to it. The application must ensure that partial overlap does not exist in `pPoolSizes`.

| Note The requirement of no partial overlap is intended to resolve ambiguity for validation as there is no confusion which `pPoolSizes` entries will be allocated from. An implementation is not expected to depend on this requirement.

Valid Usage

- VUID-VkDescriptorPoolCreateInfo-maxSets-00301
  `maxSets` must be greater than `0`

- VUID-VkDescriptorPoolCreateInfo-flags-04607
  If `flags` has the `VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT` bit set, then the `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` bit must not be set

- VUID-VkDescriptorPoolCreateInfo-mutableDescriptorType-04608
  If VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT::`mutableDescriptorType` is not enabled, `pPoolSizes` must not contain a `descriptorType` of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

- VUID-VkDescriptorPoolCreateInfo-flags-04609
  If `flags` has the `VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT` bit set, VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT::`mutableDescriptorType` must be enabled

- VUID-VkDescriptorPoolCreateInfo-pPoolSizes-04787
  If `pPoolSizes` contains a `descriptorType` of `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, any other `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` element in `pPoolSizes` must not have sets of supported descriptor types which partially overlap

Valid Usage (Implicit)

- VUID-VkDescriptorPoolCreateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO`

- VUID-VkDescriptorPoolCreateInfo-pNext-pNext
  Each `pNext` member of any structure (including this one) in the `pNext` chain must be either `NULL` or a pointer to a valid instance of VkDescriptorPoolInlineUniformBlockCreateInfo or VkMutableDescriptorTypeCreateInfoEXT

- VUID-VkDescriptorPoolCreateInfo-sType-unique
  The `sType` value of each struct in the `pNext` chain must be unique

- VUID-VkDescriptorPoolCreateInfo-flags-parameter
  `flags` must be a valid combination of VkDescriptorPoolCreateFlagBits values

- VUID-VkDescriptorPoolCreateInfo-pPoolSizes-parameter
  If `poolSizeCount` is not `0`, `pPoolSizes` must be a valid pointer to an array of `poolSizeCount` valid VkDescriptorPoolSize structures

In order to be able to allocate descriptor sets having inline uniform block bindings the descriptor pool must be created with specifying the inline uniform block binding capacity of the descriptor pool, in addition to the total inline uniform data capacity in bytes which is specified through a VkDescriptorPoolSize structure with a `descriptorType` value of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`. This can be done by adding a `VkDescriptorPoolInlineUniformBlockCreateInfo` structure to the `pNext` chain of VkDescriptorPoolCreateInfo.

The `VkDescriptorPoolInlineUniformBlockCreateInfo` structure is defined as:

    // Provided by VK_VERSION_1_3
    typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo {
        VkStructureType    sType;
        const void*        pNext;
        uint32_t           maxInlineUniformBlockBindings;
    } VkDescriptorPoolInlineUniformBlockCreateInfo;

or the equivalent

    // Provided by VK_EXT_inline_uniform_block
    typedef VkDescriptorPoolInlineUniformBlockCreateInfo VkDescriptorPoolInlineUniformBlockCreateInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `maxInlineUniformBlockBindings` is the number of inline uniform block bindings to allocate.

Valid Usage (Implicit)

- VUID-VkDescriptorPoolInlineUniformBlockCreateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO`

Bits which can be set in VkDescriptorPoolCreateInfo::`flags`, enabling operations on a descriptor pool, are:

    // Provided by VK_VERSION_1_0
    typedef enum VkDescriptorPoolCreateFlagBits {
        VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
      // Provided by VK_VERSION_1_2
        VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002,
      // Provided by VK_EXT_mutable_descriptor_type
        VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT = 0x00000004,
      // Provided by VK_EXT_descriptor_indexing
        VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
      // Provided by VK_VALVE_mutable_descriptor_type
        VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE = VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT,
    } VkDescriptorPoolCreateFlagBits;

- `VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT` specifies that descriptor sets can return their individual allocations to the pool, i.e. all of vkAllocateDescriptorSets, vkFreeDescriptorSets, and vkResetDescriptorPool are allowed. Otherwise, descriptor sets allocated from the pool must not be individually freed back to the pool, i.e. only vkAllocateDescriptorSets and vkResetDescriptorPool are allowed.

- `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` specifies that descriptor sets allocated from this pool can include bindings with the `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` bit set. It is valid to allocate descriptor sets that have bindings that do not set the `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` bit from a pool that has `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` set.

- `VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT` specifies that this descriptor pool and the descriptor sets allocated from it reside entirely in host memory and cannot be bound. Similar to descriptor sets allocated without this flag, applications can copy-from and copy-to descriptors sets allocated from this descriptor pool. Descriptor sets allocated from this pool are partially exempt from the external synchronization requirement in vkUpdateDescriptorSetWithTemplateKHR and vkUpdateDescriptorSets. Descriptor sets and their descriptors can be updated concurrently in different threads, though the same descriptor must not be updated concurrently by two threads.

    // Provided by VK_VERSION_1_0
    typedef VkFlags VkDescriptorPoolCreateFlags;

`VkDescriptorPoolCreateFlags` is a bitmask type for setting a mask of zero or more VkDescriptorPoolCreateFlagBits.

The `VkDescriptorPoolSize` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkDescriptorPoolSize {
        VkDescriptorType    type;
        uint32_t            descriptorCount;
    } VkDescriptorPoolSize;

- `type` is the type of descriptor.

- `descriptorCount` is the number of descriptors of that type to allocate. If `type` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `descriptorCount` is the number of bytes to allocate for descriptors of this type.

| Note When creating a descriptor pool that will contain descriptors for combined image samplers of multi-planar formats, an application needs to account for non-trivial descriptor consumption when choosing the `descriptorCount` value, as indicated by VkSamplerYcbcrConversionImageFormatProperties::`combinedImageSamplerDescriptorCount`.

Valid Usage

- VUID-VkDescriptorPoolSize-descriptorCount-00302
  `descriptorCount` must be greater than `0`

- VUID-VkDescriptorPoolSize-type-02218
  If `type` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `descriptorCount` must be a multiple of `4`

Valid Usage (Implicit)

- VUID-VkDescriptorPoolSize-type-parameter
  `type` must be a valid VkDescriptorType value

To destroy a descriptor pool, call:

    // Provided by VK_VERSION_1_0
    void vkDestroyDescriptorPool(
        VkDevice                                    device,
        VkDescriptorPool                            descriptorPool,
        const VkAllocationCallbacks*                pAllocator);

- `device` is the logical device that destroys the descriptor pool.

- `descriptorPool` is the descriptor pool to destroy.

- `pAllocator` controls host memory allocation as described in the 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

- VUID-vkDestroyDescriptorPool-descriptorPool-00303
  All submitted commands that refer to `descriptorPool` (via any allocated descriptor sets) must have completed execution

- VUID-vkDestroyDescriptorPool-descriptorPool-00304
  If `VkAllocationCallbacks` were provided when `descriptorPool` was created, a compatible set of callbacks must be provided here

- VUID-vkDestroyDescriptorPool-descriptorPool-00305
  If no `VkAllocationCallbacks` were provided when `descriptorPool` was created, `pAllocator` must be `NULL`

Valid Usage (Implicit)

- VUID-vkDestroyDescriptorPool-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkDestroyDescriptorPool-descriptorPool-parameter
  If `descriptorPool` is not VK_NULL_HANDLE, `descriptorPool` must be a valid VkDescriptorPool handle

- VUID-vkDestroyDescriptorPool-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkDestroyDescriptorPool-descriptorPool-parent
  If `descriptorPool` is a valid handle, it must have been created, allocated, or retrieved from `device`

Host Synchronization

- Host access to `descriptorPool` must be externally synchronized

Descriptor sets are allocated from descriptor pool objects, and are represented by `VkDescriptorSet` handles:

    // Provided by VK_VERSION_1_0
    VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)

To allocate descriptor sets from a descriptor pool, call:

    // Provided by VK_VERSION_1_0
    VkResult vkAllocateDescriptorSets(
        VkDevice                                    device,
        const VkDescriptorSetAllocateInfo*          pAllocateInfo,
        VkDescriptorSet*                            pDescriptorSets);

- `device` is the logical device that owns the descriptor pool.

- `pAllocateInfo` is a pointer to a VkDescriptorSetAllocateInfo structure describing parameters of the allocation.

- `pDescriptorSets` is a pointer to an array of VkDescriptorSet handles in which the resulting descriptor set objects are returned.

The allocated descriptor sets are returned in `pDescriptorSets`.

When a descriptor set is allocated, the initial state is largely uninitialized and all descriptors are undefined, with the exception that samplers with a non-null `pImmutableSamplers` are initialized on allocation. Descriptors also become undefined if the underlying resource or view object is destroyed. Descriptor sets containing undefined descriptors can still be bound and used, subject to the following conditions:

- For descriptor set bindings created with the `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT` bit set, all descriptors in that binding that are dynamically used must have been populated before the descriptor set is consumed.

- For descriptor set bindings created without the `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT` bit set, all descriptors in that binding that are statically used must have been populated before the descriptor set is consumed.

- Descriptor bindings with descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` can be undefined when the descriptor set is consumed; though values in that block will be undefined.

- Entries that are not used by a pipeline can have undefined descriptors.

If a call to `vkAllocateDescriptorSets` would cause the total number of descriptor sets allocated from the pool to exceed the value of VkDescriptorPoolCreateInfo::`maxSets` used to create `pAllocateInfo->descriptorPool`, then the allocation may fail due to lack of space in the descriptor pool. Similarly, the allocation may fail due to lack of space if the call to `vkAllocateDescriptorSets` would cause the number of any given descriptor type to exceed the sum of all the `descriptorCount` members of each element of VkDescriptorPoolCreateInfo::`pPoolSizes` with a `type` equal to that type.

Additionally, the allocation may also fail if a call to `vkAllocateDescriptorSets` would cause the total number of inline uniform block bindings allocated from the pool to exceed the value of VkDescriptorPoolInlineUniformBlockCreateInfo::`maxInlineUniformBlockBindings` used to create the descriptor pool.

If the allocation fails due to no more space in the descriptor pool, and not because of system or device memory exhaustion, then `VK_ERROR_OUT_OF_POOL_MEMORY` must be returned.

`vkAllocateDescriptorSets` can be used to create multiple descriptor sets. If the creation of any of those descriptor sets fails, then the implementation must destroy all successfully created descriptor set objects from this command, set all entries of the `pDescriptorSets` array to VK_NULL_HANDLE and return the error.

Valid Usage (Implicit)

- VUID-vkAllocateDescriptorSets-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkAllocateDescriptorSets-pAllocateInfo-parameter
  `pAllocateInfo` must be a valid pointer to a valid VkDescriptorSetAllocateInfo structure

- VUID-vkAllocateDescriptorSets-pDescriptorSets-parameter
  `pDescriptorSets` must be a valid pointer to an array of `pAllocateInfo->descriptorSetCount` VkDescriptorSet handles

- VUID-vkAllocateDescriptorSets-pAllocateInfo::descriptorSetCount-arraylength
  `pAllocateInfo->descriptorSetCount` must be greater than `0`

Host Synchronization

- Host access to `pAllocateInfo->descriptorPool` must be externally synchronized

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

  - `VK_ERROR_FRAGMENTED_POOL`

  - `VK_ERROR_OUT_OF_POOL_MEMORY`

The `VkDescriptorSetAllocateInfo` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkDescriptorSetAllocateInfo {
        VkStructureType                 sType;
        const void*                     pNext;
        VkDescriptorPool                descriptorPool;
        uint32_t                        descriptorSetCount;
        const VkDescriptorSetLayout*    pSetLayouts;
    } VkDescriptorSetAllocateInfo;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `descriptorPool` is the pool which the sets will be allocated from.

- `descriptorSetCount` determines the number of descriptor sets to be allocated from the pool.

- `pSetLayouts` is a pointer to an array of descriptor set layouts, with each member specifying how the corresponding descriptor set is allocated.

Valid Usage

- VUID-VkDescriptorSetAllocateInfo-apiVersion-07895
  If the VK_KHR_maintenance1 extension is not enabled, VkPhysicalDeviceProperties::`apiVersion` is less than Vulkan 1.1, `descriptorSetCount` must not be greater than the number of sets that are currently available for allocation in `descriptorPool`

- VUID-VkDescriptorSetAllocateInfo-apiVersion-07896
  If the VK_KHR_maintenance1 extension is not enabled, VkPhysicalDeviceProperties::`apiVersion` is less than Vulkan 1.1, `descriptorPool` must have enough free descriptor capacity remaining to allocate the descriptor sets of the specified layouts

- VUID-VkDescriptorSetAllocateInfo-pSetLayouts-00308
  Each element of `pSetLayouts` must not have been created with `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR` set

- VUID-VkDescriptorSetAllocateInfo-pSetLayouts-03044
  If any element of `pSetLayouts` was created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` bit set, `descriptorPool` must have been created with the `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` flag set

- VUID-VkDescriptorSetAllocateInfo-pSetLayouts-04610
  If any element of `pSetLayouts` was created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT` bit set, `descriptorPool` must have been created with the `VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT` flag set

- VUID-VkDescriptorSetAllocateInfo-pSetLayouts-08009
  Each element of `pSetLayouts` must not have been created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT` bit set

Valid Usage (Implicit)

- VUID-VkDescriptorSetAllocateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO`

- VUID-VkDescriptorSetAllocateInfo-pNext-pNext
  `pNext` must be `NULL` or a pointer to a valid instance of VkDescriptorSetVariableDescriptorCountAllocateInfo

- VUID-VkDescriptorSetAllocateInfo-sType-unique
  The `sType` value of each struct in the `pNext` chain must be unique

- VUID-VkDescriptorSetAllocateInfo-descriptorPool-parameter
  `descriptorPool` must be a valid VkDescriptorPool handle

- VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter
  `pSetLayouts` must be a valid pointer to an array of `descriptorSetCount` valid VkDescriptorSetLayout handles

- VUID-VkDescriptorSetAllocateInfo-descriptorSetCount-arraylength
  `descriptorSetCount` must be greater than `0`

- VUID-VkDescriptorSetAllocateInfo-commonparent
  Both of `descriptorPool`, and the elements of `pSetLayouts` must have been created, allocated, or retrieved from the same VkDevice

If the `pNext` chain of a VkDescriptorSetAllocateInfo structure includes a `VkDescriptorSetVariableDescriptorCountAllocateInfo` structure, then that structure includes an array of descriptor counts for variable-sized descriptor bindings, one for each descriptor set being allocated.

The `VkDescriptorSetVariableDescriptorCountAllocateInfo` structure is defined as:

    // Provided by VK_VERSION_1_2
    typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo {
        VkStructureType    sType;
        const void*        pNext;
        uint32_t           descriptorSetCount;
        const uint32_t*    pDescriptorCounts;
    } VkDescriptorSetVariableDescriptorCountAllocateInfo;

or the equivalent

    // Provided by VK_EXT_descriptor_indexing
    typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `descriptorSetCount` is zero or the number of elements in `pDescriptorCounts`.

- `pDescriptorCounts` is a pointer to an array of descriptor counts, with each member specifying the number of descriptors in a variable-sized descriptor binding in the corresponding descriptor set being allocated.

If `descriptorSetCount` is zero or this structure is not included in the `pNext` chain, then the variable lengths are considered to be zero. Otherwise, `pDescriptorCounts`[i] is the number of descriptors in the variable-sized descriptor binding in the corresponding descriptor set layout. If the variable-sized descriptor binding in the corresponding descriptor set layout has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `pDescriptorCounts`[i] specifies the binding’s capacity in bytes. If VkDescriptorSetAllocateInfo::`pSetLayouts`[i] does not include a variable-sized descriptor binding, then `pDescriptorCounts`[i] is ignored.

Valid Usage

- VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-descriptorSetCount-03045
  If `descriptorSetCount` is not zero, `descriptorSetCount` must equal VkDescriptorSetAllocateInfo::`descriptorSetCount`

- VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-pSetLayouts-03046
  If VkDescriptorSetAllocateInfo::`pSetLayouts`[i] has a variable-sized descriptor binding, then `pDescriptorCounts`[i] must be less than or equal to the descriptor count specified for that binding when the descriptor set layout was created

Valid Usage (Implicit)

- VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO`

- VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-pDescriptorCounts-parameter
  If `descriptorSetCount` is not `0`, `pDescriptorCounts` must be a valid pointer to an array of `descriptorSetCount` `uint32_t` values

To free allocated descriptor sets, call:

    // Provided by VK_VERSION_1_0
    VkResult vkFreeDescriptorSets(
        VkDevice                                    device,
        VkDescriptorPool                            descriptorPool,
        uint32_t                                    descriptorSetCount,
        const VkDescriptorSet*                      pDescriptorSets);

- `device` is the logical device that owns the descriptor pool.

- `descriptorPool` is the descriptor pool from which the descriptor sets were allocated.

- `descriptorSetCount` is the number of elements in the `pDescriptorSets` array.

- `pDescriptorSets` is a pointer to an array of handles to VkDescriptorSet objects.

After calling `vkFreeDescriptorSets`, all descriptor sets in `pDescriptorSets` are invalid.

Valid Usage

- VUID-vkFreeDescriptorSets-pDescriptorSets-00309
  All submitted commands that refer to any element of `pDescriptorSets` must have completed execution

- VUID-vkFreeDescriptorSets-pDescriptorSets-00310
  `pDescriptorSets` must be a valid pointer to an array of `descriptorSetCount` `VkDescriptorSet` handles, each element of which must either be a valid handle or VK_NULL_HANDLE

- VUID-vkFreeDescriptorSets-descriptorPool-00312
  `descriptorPool` must have been created with the `VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT` flag

Valid Usage (Implicit)

- VUID-vkFreeDescriptorSets-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkFreeDescriptorSets-descriptorPool-parameter
  `descriptorPool` must be a valid VkDescriptorPool handle

- VUID-vkFreeDescriptorSets-descriptorSetCount-arraylength
  `descriptorSetCount` must be greater than `0`

- VUID-vkFreeDescriptorSets-descriptorPool-parent
  `descriptorPool` must have been created, allocated, or retrieved from `device`

- VUID-vkFreeDescriptorSets-pDescriptorSets-parent
  Each element of `pDescriptorSets` that is a valid handle must have been created, allocated, or retrieved from `descriptorPool`

Host Synchronization

- Host access to `descriptorPool` must be externally synchronized

- Host access to each member of `pDescriptorSets` must be externally synchronized

Return Codes

Success

  - `VK_SUCCESS`

To return all descriptor sets allocated from a given pool to the pool, rather than freeing individual descriptor sets, call:

    // Provided by VK_VERSION_1_0
    VkResult vkResetDescriptorPool(
        VkDevice                                    device,
        VkDescriptorPool                            descriptorPool,
        VkDescriptorPoolResetFlags                  flags);

- `device` is the logical device that owns the descriptor pool.

- `descriptorPool` is the descriptor pool to be reset.

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

- VUID-vkResetDescriptorPool-descriptorPool-00313
  All uses of `descriptorPool` (via any allocated descriptor sets) must have completed execution

Valid Usage (Implicit)

- VUID-vkResetDescriptorPool-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkResetDescriptorPool-descriptorPool-parameter
  `descriptorPool` must be a valid VkDescriptorPool handle

- VUID-vkResetDescriptorPool-flags-zerobitmask
  `flags` must be `0`

- VUID-vkResetDescriptorPool-descriptorPool-parent
  `descriptorPool` must have been created, allocated, or retrieved from `device`

Host Synchronization

- Host access to `descriptorPool` must be externally synchronized

- Host access to any `VkDescriptorSet` objects allocated from `descriptorPool` must be externally synchronized

Return Codes

Success

  - `VK_SUCCESS`

    // Provided by VK_VERSION_1_0
    typedef VkFlags VkDescriptorPoolResetFlags;

`VkDescriptorPoolResetFlags` is a bitmask type for setting a mask, but is currently reserved for future use.

#### 14.2.4. Descriptor Set Updates

Once allocated, descriptor sets can be updated with a combination of write and copy operations. To update descriptor sets, call:

    // Provided by VK_VERSION_1_0
    void vkUpdateDescriptorSets(
        VkDevice                                    device,
        uint32_t                                    descriptorWriteCount,
        const VkWriteDescriptorSet*                 pDescriptorWrites,
        uint32_t                                    descriptorCopyCount,
        const VkCopyDescriptorSet*                  pDescriptorCopies);

- `device` is the logical device that updates the descriptor sets.

- `descriptorWriteCount` is the number of elements in the `pDescriptorWrites` array.

- `pDescriptorWrites` is a pointer to an array of VkWriteDescriptorSet structures describing the descriptor sets to write to.

- `descriptorCopyCount` is the number of elements in the `pDescriptorCopies` array.

- `pDescriptorCopies` is a pointer to an array of VkCopyDescriptorSet structures describing the descriptor sets to copy between.

The operations described by `pDescriptorWrites` are performed first, followed by the operations described by `pDescriptorCopies`. Within each array, the operations are performed in the order they appear in the array.

Each element in the `pDescriptorWrites` array describes an operation updating the descriptor set using descriptors for resources specified in the structure.

Each element in the `pDescriptorCopies` array is a VkCopyDescriptorSet structure describing an operation copying descriptors between sets.

If the `dstSet` member of any element of `pDescriptorWrites` or `pDescriptorCopies` is bound, accessed, or modified by any command that was recorded to a command buffer which is currently in the recording or executable state, and any of the descriptor bindings that are updated were not created with the `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` or `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT` bits set, that command buffer becomes invalid.

Valid Usage

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06236
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` or `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, elements of the `pTexelBufferView` member of `pDescriptorWrites`[i] must have been created on `device`

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06237
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`, the `buffer` member of any element of the `pBufferInfo` member of `pDescriptorWrites`[i] must have been created on `device`

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06238
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLER` or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and `dstSet` was not allocated with a layout that included immutable samplers for `dstBinding` with `descriptorType`, the `sampler` member of any element of the `pImageInfo` member of `pDescriptorWrites`[i] must have been created on `device`

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06239
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` the `imageView` member of any element of `pDescriptorWrites`[i] must have been created on `device`

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06240
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR`, elements of the `pAccelerationStructures` member of a VkWriteDescriptorSetAccelerationStructureKHR structure in the `pNext` chain of `pDescriptorWrites`[i] must have been created on `device`

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06241
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV`, elements of the `pAccelerationStructures` member of a VkWriteDescriptorSetAccelerationStructureNV structure in the `pNext` chain of `pDescriptorWrites`[i] must have been created on `device`

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06940
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM` or `VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM`, the `imageView` member of any element of `pDescriptorWrites`[i] must have been created on `device`

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06493
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLER`, `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, or `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, `pDescriptorWrites`[i].`pImageInfo` must be a valid pointer to an array of `pDescriptorWrites`[i].`descriptorCount` valid `VkDescriptorImageInfo` structures

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06941
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM` or `VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM`, `pDescriptorWrites`[i].`pImageInfo` must be a valid pointer to an array of `pDescriptorWrites`[i].`descriptorCount` valid `VkDescriptorImageInfo` structures

- VUID-vkUpdateDescriptorSets-None-03047
  Descriptor bindings updated by this command which were created without the `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` or `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT` bits set must not be used by any command that was recorded to a command buffer which is in the pending state

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-06993
  Host access to `pDescriptorWrites`[i].`dstSet` and `pDescriptorCopies`[i].`dstSet` must be externally synchronized unless explicitly denoted otherwise for specific flags

Valid Usage (Implicit)

- VUID-vkUpdateDescriptorSets-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkUpdateDescriptorSets-pDescriptorWrites-parameter
  If `descriptorWriteCount` is not `0`, `pDescriptorWrites` must be a valid pointer to an array of `descriptorWriteCount` valid VkWriteDescriptorSet structures

- VUID-vkUpdateDescriptorSets-pDescriptorCopies-parameter
  If `descriptorCopyCount` is not `0`, `pDescriptorCopies` must be a valid pointer to an array of `descriptorCopyCount` valid VkCopyDescriptorSet structures

The `VkWriteDescriptorSet` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkWriteDescriptorSet {
        VkStructureType                  sType;
        const void*                      pNext;
        VkDescriptorSet                  dstSet;
        uint32_t                         dstBinding;
        uint32_t                         dstArrayElement;
        uint32_t                         descriptorCount;
        VkDescriptorType                 descriptorType;
        const VkDescriptorImageInfo*     pImageInfo;
        const VkDescriptorBufferInfo*    pBufferInfo;
        const VkBufferView*              pTexelBufferView;
    } VkWriteDescriptorSet;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `dstSet` is the destination descriptor set to update.

- `dstBinding` is the descriptor binding within that set.

- `dstArrayElement` is the starting element in that array. If the descriptor binding identified by `dstSet` and `dstBinding` has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `dstArrayElement` specifies the starting byte offset within the binding.

- `descriptorCount` is the number of descriptors to update. If the descriptor binding identified by `dstSet` and `dstBinding` has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, then `descriptorCount` specifies the number of bytes to update. Otherwise, `descriptorCount` is one of

  - the number of elements in `pImageInfo`

  - the number of elements in `pBufferInfo`

  - the number of elements in `pTexelBufferView`

  - a value matching the `dataSize` member of a VkWriteDescriptorSetInlineUniformBlock structure in the `pNext` chain

  - a value matching the `accelerationStructureCount` of a VkWriteDescriptorSetAccelerationStructureKHR structure in the `pNext` chain

- `descriptorType` is a VkDescriptorType specifying the type of each descriptor in `pImageInfo`, `pBufferInfo`, or `pTexelBufferView`, as described below. If `VkDescriptorSetLayoutBinding` for `dstSet` at `dstBinding` is not equal to `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, `descriptorType` must be the same type as the `descriptorType` specified in `VkDescriptorSetLayoutBinding` for `dstSet` at `dstBinding`. The type of the descriptor also controls which array the descriptors are taken from.

- `pImageInfo` is a pointer to an array of VkDescriptorImageInfo structures or is ignored, as described below.

- `pBufferInfo` is a pointer to an array of VkDescriptorBufferInfo structures or is ignored, as described below.

- `pTexelBufferView` is a pointer to an array of VkBufferView handles as described in the Buffer Views section or is ignored, as described below.

Only one of `pImageInfo`, `pBufferInfo`, or `pTexelBufferView` members is used according to the descriptor type specified in the `descriptorType` member of the containing `VkWriteDescriptorSet` structure, or none of them in case `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, in which case the source data for the descriptor writes is taken from the VkWriteDescriptorSetInlineUniformBlock structure included in the `pNext` chain of `VkWriteDescriptorSet`, or if `descriptorType` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR`, in which case the source data for the descriptor writes is taken from the VkWriteDescriptorSetAccelerationStructureKHR structure in the `pNext` chain of `VkWriteDescriptorSet`, or if `descriptorType` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV`, in which case the source data for the descriptor writes is taken from the VkWriteDescriptorSetAccelerationStructureNV structure in the `pNext` chain of `VkWriteDescriptorSet`, as specified below.

If the `nullDescriptor` feature is enabled, the buffer, acceleration structure, imageView, or bufferView can be VK_NULL_HANDLE. Loads from a null descriptor return zero values and stores and atomics to a null descriptor are discarded. A null acceleration structure descriptor results in the miss shader being invoked.

If the destination descriptor is a mutable descriptor, the active descriptor type for the destination descriptor becomes `descriptorType`.

If the `dstBinding` has fewer than `descriptorCount` array elements remaining starting from `dstArrayElement`, then the remainder will be used to update the subsequent binding - `dstBinding`+1 starting at array element zero. If a binding has a `descriptorCount` of zero, it is skipped. This behavior applies recursively, with the update affecting consecutive bindings as needed to update all `descriptorCount` descriptors. Consecutive bindings must have identical VkDescriptorType, VkShaderStageFlags, VkDescriptorBindingFlagBits, and immutable samplers references. In addition, if the VkDescriptorType is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the supported descriptor types in VkMutableDescriptorTypeCreateInfoEXT must be equally defined.

| Note The same behavior applies to bindings with a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` where `descriptorCount` specifies the number of bytes to update while `dstArrayElement` specifies the starting byte offset, thus in this case if the `dstBinding` has a smaller byte size than the sum of `dstArrayElement` and `descriptorCount`, then the remainder will be used to update the subsequent binding - `dstBinding`+1 starting at offset zero. This falls out as a special case of the above rule.

Valid Usage

- VUID-VkWriteDescriptorSet-dstBinding-00315
  `dstBinding` must be less than or equal to the maximum value of `binding` of all VkDescriptorSetLayoutBinding structures specified when `dstSet`’s descriptor set layout was created

- VUID-VkWriteDescriptorSet-dstBinding-00316
  `dstBinding` must be a binding with a non-zero `descriptorCount`

- VUID-VkWriteDescriptorSet-descriptorCount-00317
  All consecutive bindings updated via a single `VkWriteDescriptorSet` structure, except those with a `descriptorCount` of zero, must have identical `descriptorType` and `stageFlags`

- VUID-VkWriteDescriptorSet-descriptorCount-00318
  All consecutive bindings updated via a single `VkWriteDescriptorSet` structure, except those with a `descriptorCount` of zero, must all either use immutable samplers or must all not use immutable samplers

- VUID-VkWriteDescriptorSet-descriptorType-00319
  `descriptorType` must match the type of `dstBinding` within `dstSet`

- VUID-VkWriteDescriptorSet-dstSet-00320
  `dstSet` must be a valid VkDescriptorSet handle

- VUID-VkWriteDescriptorSet-dstArrayElement-00321
  The sum of `dstArrayElement` and `descriptorCount` must be less than or equal to the number of array elements in the descriptor set binding specified by `dstBinding`, and all applicable consecutive bindings, as described by consecutive binding updates

- VUID-VkWriteDescriptorSet-descriptorType-02219
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, `dstArrayElement` must be an integer multiple of `4`

- VUID-VkWriteDescriptorSet-descriptorType-02220
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, `descriptorCount` must be an integer multiple of `4`

- VUID-VkWriteDescriptorSet-descriptorType-02994
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` or `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, each element of `pTexelBufferView` must be either a valid `VkBufferView` handle or VK_NULL_HANDLE

- VUID-VkWriteDescriptorSet-descriptorType-02995
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` or `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` and the `nullDescriptor` feature is not enabled, each element of `pTexelBufferView` must not be VK_NULL_HANDLE

- VUID-VkWriteDescriptorSet-descriptorType-00324
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`, `pBufferInfo` must be a valid pointer to an array of `descriptorCount` valid `VkDescriptorBufferInfo` structures

- VUID-VkWriteDescriptorSet-descriptorType-00325
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLER` or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and `dstSet` was not allocated with a layout that included immutable samplers for `dstBinding` with `descriptorType`, the `sampler` member of each element of `pImageInfo` must be a valid `VkSampler` object

- VUID-VkWriteDescriptorSet-descriptorType-02996
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, or `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, the `imageView` member of each element of `pImageInfo` must be either a valid `VkImageView` handle or VK_NULL_HANDLE

- VUID-VkWriteDescriptorSet-descriptorType-02997
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, or `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and the `nullDescriptor` feature is not enabled, the `imageView` member of each element of `pImageInfo` must not be VK_NULL_HANDLE

- VUID-VkWriteDescriptorSet-descriptorType-07683
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, the `imageView` member of each element of `pImageInfo` must not be VK_NULL_HANDLE

- VUID-VkWriteDescriptorSet-descriptorType-02221
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, the `pNext` chain must include a VkWriteDescriptorSetInlineUniformBlock structure whose `dataSize` member equals `descriptorCount`

- VUID-VkWriteDescriptorSet-descriptorType-02382
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR`, the `pNext` chain must include a VkWriteDescriptorSetAccelerationStructureKHR structure whose `accelerationStructureCount` member equals `descriptorCount`

- VUID-VkWriteDescriptorSet-descriptorType-03817
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV`, the `pNext` chain must include a VkWriteDescriptorSetAccelerationStructureNV structure whose `accelerationStructureCount` member equals `descriptorCount`

- VUID-VkWriteDescriptorSet-descriptorType-01946
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, then the `imageView` member of each `pImageInfo` element must have been created without a `VkSamplerYcbcrConversionInfo` structure in its `pNext` chain

- VUID-VkWriteDescriptorSet-descriptorType-02738
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and if any element of `pImageInfo` has a `imageView` member that was created with a `VkSamplerYcbcrConversionInfo` structure in its `pNext` chain, then `dstSet` must have been allocated with a layout that included immutable samplers for `dstBinding`, and the corresponding immutable sampler must have been created with an identically defined `VkSamplerYcbcrConversionInfo` object

- VUID-VkWriteDescriptorSet-descriptorType-01948
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and `dstSet` was allocated with a layout that included immutable samplers for `dstBinding`, then the `imageView` member of each element of `pImageInfo` which corresponds to an immutable sampler that enables sampler Y′CBCR conversion must have been created with a `VkSamplerYcbcrConversionInfo` structure in its `pNext` chain with an identically defined `VkSamplerYcbcrConversionInfo` to the corresponding immutable sampler

- VUID-VkWriteDescriptorSet-descriptorType-00327
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` or `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, the `offset` member of each element of `pBufferInfo` must be a multiple of `VkPhysicalDeviceLimits`::`minUniformBufferOffsetAlignment`

- VUID-VkWriteDescriptorSet-descriptorType-00328
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`, the `offset` member of each element of `pBufferInfo` must be a multiple of `VkPhysicalDeviceLimits`::`minStorageBufferOffsetAlignment`

- VUID-VkWriteDescriptorSet-descriptorType-00329
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`, and the `buffer` member of any element of `pBufferInfo` is the handle of a non-sparse buffer, then that buffer must be bound completely and contiguously to a single `VkDeviceMemory` object

- VUID-VkWriteDescriptorSet-descriptorType-00330
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` or `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, the `buffer` member of each element of `pBufferInfo` must have been created with `VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT` set

- VUID-VkWriteDescriptorSet-descriptorType-00331
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`, the `buffer` member of each element of `pBufferInfo` must have been created with `VK_BUFFER_USAGE_STORAGE_BUFFER_BIT` set

- VUID-VkWriteDescriptorSet-descriptorType-00332
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` or `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, the `range` member of each element of `pBufferInfo`, or the effective range if `range` is `VK_WHOLE_SIZE`, must be less than or equal to `VkPhysicalDeviceLimits`::`maxUniformBufferRange`

- VUID-VkWriteDescriptorSet-descriptorType-00333
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`, the `range` member of each element of `pBufferInfo`, or the effective range if `range` is `VK_WHOLE_SIZE`, must be less than or equal to `VkPhysicalDeviceLimits`::`maxStorageBufferRange`

- VUID-VkWriteDescriptorSet-descriptorType-00334
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`, the `VkBuffer` that each element of `pTexelBufferView` was created from must have been created with `VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT` set

- VUID-VkWriteDescriptorSet-descriptorType-00335
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, the `VkBuffer` that each element of `pTexelBufferView` was created from must have been created with `VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT` set

- VUID-VkWriteDescriptorSet-descriptorType-00336
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE` or `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, the `imageView` member of each element of `pImageInfo` must have been created with the identity swizzle

- VUID-VkWriteDescriptorSet-descriptorType-00337
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE` or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, the `imageView` member of each element of `pImageInfo` must have been created with `VK_IMAGE_USAGE_SAMPLED_BIT` set

- VUID-VkWriteDescriptorSet-descriptorType-04149
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE` the `imageLayout` member of each element of `pImageInfo` must be a member of the list given in Sampled Image

- VUID-VkWriteDescriptorSet-descriptorType-04150
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` the `imageLayout` member of each element of `pImageInfo` must be a member of the list given in Combined Image Sampler

- VUID-VkWriteDescriptorSet-descriptorType-04151
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT` the `imageLayout` member of each element of `pImageInfo` must be a member of the list given in Input Attachment

- VUID-VkWriteDescriptorSet-descriptorType-04152
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE` the `imageLayout` member of each element of `pImageInfo` must be a member of the list given in Storage Image

- VUID-VkWriteDescriptorSet-descriptorType-00338
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, the `imageView` member of each element of `pImageInfo` must have been created with `VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT` set

- VUID-VkWriteDescriptorSet-descriptorType-00339
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, the `imageView` member of each element of `pImageInfo` must have been created with `VK_IMAGE_USAGE_STORAGE_BIT` set

- VUID-VkWriteDescriptorSet-descriptorType-02752
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLER`, then `dstSet` must not have been allocated with a layout that included immutable samplers for `dstBinding`

- VUID-VkWriteDescriptorSet-dstSet-04611
  If the `VkDescriptorSetLayoutBinding` for `dstSet` at `dstBinding` is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the new active descriptor type `descriptorType` must exist in the corresponding `pMutableDescriptorTypeLists` list for `dstBinding`

- VUID-VkWriteDescriptorSet-descriptorType-06450
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, the `imageView` member of each element of `pImageInfo` must have either been created without a VkImageViewMinLodCreateInfoEXT present in the `pNext` chain or with a VkImageViewMinLodCreateInfoEXT::`minLod` of `0.0`

- VUID-VkWriteDescriptorSet-descriptorType-06942
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM`, the `imageView` member of each element of `pImageInfo` must have been created with a view created with an `image` created with `VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM`

- VUID-VkWriteDescriptorSet-descriptorType-06943
  If `descriptorType` is `VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM`, the `imageView` member of each element of `pImageInfo` must have been created with a view created with an `image` created with `VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM`

Valid Usage (Implicit)

- VUID-VkWriteDescriptorSet-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET`

- VUID-VkWriteDescriptorSet-pNext-pNext
  Each `pNext` member of any structure (including this one) in the `pNext` chain must be either `NULL` or a pointer to a valid instance of VkWriteDescriptorSetAccelerationStructureKHR, VkWriteDescriptorSetAccelerationStructureNV, or VkWriteDescriptorSetInlineUniformBlock

- VUID-VkWriteDescriptorSet-sType-unique
  The `sType` value of each struct in the `pNext` chain must be unique

- VUID-VkWriteDescriptorSet-descriptorType-parameter
  `descriptorType` must be a valid VkDescriptorType value

- VUID-VkWriteDescriptorSet-descriptorCount-arraylength
  `descriptorCount` must be greater than `0`

- VUID-VkWriteDescriptorSet-commonparent
  Both of `dstSet`, and the elements of `pTexelBufferView` that are valid handles of non-ignored parameters must have been created, allocated, or retrieved from the same VkDevice

The type of descriptors in a descriptor set is specified by VkWriteDescriptorSet::`descriptorType`, which must be one of the values:

    // 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_EXT_mutable_descriptor_type
        VK_DESCRIPTOR_TYPE_MUTABLE_EXT = 1000351000,
      // 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.

When a descriptor set is updated via elements of VkWriteDescriptorSet, members of `pImageInfo`, `pBufferInfo` and `pTexelBufferView` are only accessed by the implementation when they correspond to descriptor type being defined - otherwise they are ignored. The members accessed are as follows for each descriptor type:

- For `VK_DESCRIPTOR_TYPE_SAMPLER`, only the `sampler` member of each element of VkWriteDescriptorSet::`pImageInfo` is accessed.

- For `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, or `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, only the `imageView` and `imageLayout` members of each element of VkWriteDescriptorSet::`pImageInfo` are accessed.

- For `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, all members of each element of VkWriteDescriptorSet::`pImageInfo` are accessed.

- For `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, or `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`, all members of each element of VkWriteDescriptorSet::`pBufferInfo` are accessed.

- For `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` or `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, each element of VkWriteDescriptorSet::`pTexelBufferView` is accessed.

When updating descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, none of the `pImageInfo`, `pBufferInfo`, or `pTexelBufferView` members are accessed, instead the source data of the descriptor update operation is taken from the VkWriteDescriptorSetInlineUniformBlock structure in the `pNext` chain of `VkWriteDescriptorSet`. When updating descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR`, none of the `pImageInfo`, `pBufferInfo`, or `pTexelBufferView` members are accessed, instead the source data of the descriptor update operation is taken from the VkWriteDescriptorSetAccelerationStructureKHR structure in the `pNext` chain of `VkWriteDescriptorSet`. When updating descriptors with a `descriptorType` of `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV`, none of the `pImageInfo`, `pBufferInfo`, or `pTexelBufferView` members are accessed, instead the source data of the descriptor update operation is taken from the VkWriteDescriptorSetAccelerationStructureNV structure in the `pNext` chain of `VkWriteDescriptorSet`.

The `VkDescriptorBufferInfo` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkDescriptorBufferInfo {
        VkBuffer        buffer;
        VkDeviceSize    offset;
        VkDeviceSize    range;
    } VkDescriptorBufferInfo;

- `buffer` is VK_NULL_HANDLE or the buffer resource.

- `offset` is the offset in bytes from the start of `buffer`. Access to buffer memory via this descriptor uses addressing that is relative to this starting offset.

- `range` is the size in bytes that is used for this descriptor update, or `VK_WHOLE_SIZE` to use the range from `offset` to the end of the buffer.

When setting `range` to `VK_WHOLE_SIZE`, the effective range must not be larger than the maximum range for the descriptor type (`maxUniformBufferRange` or `maxStorageBufferRange`). This means that `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 `maxUniformBufferRange`.

For `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` and `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` descriptor types, `offset` is the base offset from which the dynamic offset is applied and `range` is the static size used for all dynamic offsets.

When `range` is `VK_WHOLE_SIZE` the effective range is calculated at vkUpdateDescriptorSets is by taking the size of `buffer` minus the `offset`.

Valid Usage

- VUID-VkDescriptorBufferInfo-offset-00340
  `offset` must be less than the size of `buffer`

- VUID-VkDescriptorBufferInfo-range-00341
  If `range` is not equal to `VK_WHOLE_SIZE`, `range` must be greater than `0`

- VUID-VkDescriptorBufferInfo-range-00342
  If `range` is not equal to `VK_WHOLE_SIZE`, `range` must be less than or equal to the size of `buffer` minus `offset`

- VUID-VkDescriptorBufferInfo-buffer-02998
  If the `nullDescriptor` feature is not enabled, `buffer` must not be VK_NULL_HANDLE

- VUID-VkDescriptorBufferInfo-buffer-02999
  If `buffer` is VK_NULL_HANDLE, `offset` must be zero and `range` must be `VK_WHOLE_SIZE`

Valid Usage (Implicit)

- VUID-VkDescriptorBufferInfo-buffer-parameter
  If `buffer` is not VK_NULL_HANDLE, `buffer` must be a valid VkBuffer handle

The `VkDescriptorImageInfo` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkDescriptorImageInfo {
        VkSampler        sampler;
        VkImageView      imageView;
        VkImageLayout    imageLayout;
    } VkDescriptorImageInfo;

- `sampler` is a sampler handle, and is used in descriptor updates for types `VK_DESCRIPTOR_TYPE_SAMPLER` and `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` if the binding being updated does not use immutable samplers.

- `imageView` is VK_NULL_HANDLE or an image view handle, and is used in descriptor updates for types `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`.

- `imageLayout` is the layout that the image subresources accessible from `imageView` will be in at the time this descriptor is accessed. `imageLayout` is used in descriptor updates for types `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`.

Members of `VkDescriptorImageInfo` that are not used in an update (as described above) are ignored.

Valid Usage

- VUID-VkDescriptorImageInfo-imageView-06712
  `imageView` must not be a 2D array image view created from a 3D image

- VUID-VkDescriptorImageInfo-imageView-07795
  If `imageView` is a 2D view created from a 3D image, then `descriptorType` must be `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`

- VUID-VkDescriptorImageInfo-imageView-07796
  If `imageView` is a 2D view created from a 3D image, then the image must have been created with `VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT` set

- VUID-VkDescriptorImageInfo-descriptorType-06713
  If the `image2DViewOf3D` feature is not enabled and `descriptorType` is `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE` then `imageView` must not be a 2D view created from a 3D image

- VUID-VkDescriptorImageInfo-descriptorType-06714
  If the `sampler2DViewOf3D` feature is not enabled and `descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE` or `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` then `imageView` must not be a 2D view created from a 3D image

- VUID-VkDescriptorImageInfo-imageView-01976
  If `imageView` is created from a depth/stencil image, the `aspectMask` used to create the `imageView` must include either `VK_IMAGE_ASPECT_DEPTH_BIT` or `VK_IMAGE_ASPECT_STENCIL_BIT` but not both

- VUID-VkDescriptorImageInfo-imageLayout-00344
  `imageLayout` must match the actual VkImageLayout of each subresource accessible from `imageView` at the time this descriptor is accessed as defined by the image layout matching rules

- VUID-VkDescriptorImageInfo-sampler-01564
  If `sampler` is used and the VkFormat of the image is a multi-planar format, the image must have been created with `VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT`, and the `aspectMask` of the `imageView` must be a valid multi-planar aspect mask

- VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450
  If the `VK_KHR_portability_subset` extension is enabled, and VkPhysicalDevicePortabilitySubsetFeaturesKHR::`mutableComparisonSamplers` is `VK_FALSE`, then `sampler` must have been created with VkSamplerCreateInfo::`compareEnable` set to `VK_FALSE`

Valid Usage (Implicit)

- VUID-VkDescriptorImageInfo-commonparent
  Both of `imageView`, and `sampler` that are valid handles of non-ignored parameters must have been created, allocated, or retrieved from the same VkDevice

If the `descriptorType` member of VkWriteDescriptorSet is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then the data to write to the descriptor set is specified through a `VkWriteDescriptorSetInlineUniformBlock` structure included in the `pNext` chain of `VkWriteDescriptorSet`.

The `VkWriteDescriptorSetInlineUniformBlock` structure is defined as:

    // Provided by VK_VERSION_1_3
    typedef struct VkWriteDescriptorSetInlineUniformBlock {
        VkStructureType    sType;
        const void*        pNext;
        uint32_t           dataSize;
        const void*        pData;
    } VkWriteDescriptorSetInlineUniformBlock;

or the equivalent

    // Provided by VK_EXT_inline_uniform_block
    typedef VkWriteDescriptorSetInlineUniformBlock VkWriteDescriptorSetInlineUniformBlockEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `dataSize` is the number of bytes of inline uniform block data pointed to by `pData`.

- `pData` is a pointer to `dataSize` number of bytes of data to write to the inline uniform block.

Valid Usage

- VUID-VkWriteDescriptorSetInlineUniformBlock-dataSize-02222
  `dataSize` must be an integer multiple of `4`

Valid Usage (Implicit)

- VUID-VkWriteDescriptorSetInlineUniformBlock-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK`

- VUID-VkWriteDescriptorSetInlineUniformBlock-pData-parameter
  `pData` must be a valid pointer to an array of `dataSize` bytes

- VUID-VkWriteDescriptorSetInlineUniformBlock-dataSize-arraylength
  `dataSize` must be greater than `0`

The `VkWriteDescriptorSetAccelerationStructureKHR` structure is defined as:

    // Provided by VK_KHR_acceleration_structure
    typedef struct VkWriteDescriptorSetAccelerationStructureKHR {
        VkStructureType                      sType;
        const void*                          pNext;
        uint32_t                             accelerationStructureCount;
        const VkAccelerationStructureKHR*    pAccelerationStructures;
    } VkWriteDescriptorSetAccelerationStructureKHR;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `accelerationStructureCount` is the number of elements in `pAccelerationStructures`.

- `pAccelerationStructures` is a pointer to an array of VkAccelerationStructureKHR structures specifying the acceleration structures to update.

Valid Usage

- VUID-VkWriteDescriptorSetAccelerationStructureKHR-accelerationStructureCount-02236
  `accelerationStructureCount` must be equal to `descriptorCount` in the extended structure

- VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-03579
  Each acceleration structure in `pAccelerationStructures` must have been created with a `type` of `VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR` or `VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR`

- VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-03580
  If the `nullDescriptor` feature is not enabled, each element of `pAccelerationStructures` must not be VK_NULL_HANDLE

Valid Usage (Implicit)

- VUID-VkWriteDescriptorSetAccelerationStructureKHR-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR`

- VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-parameter
  `pAccelerationStructures` must be a valid pointer to an array of `accelerationStructureCount` valid or VK_NULL_HANDLE VkAccelerationStructureKHR handles

- VUID-VkWriteDescriptorSetAccelerationStructureKHR-accelerationStructureCount-arraylength
  `accelerationStructureCount` must be greater than `0`

The `VkWriteDescriptorSetAccelerationStructureNV` structure is defined as:

    // Provided by VK_NV_ray_tracing
    typedef struct VkWriteDescriptorSetAccelerationStructureNV {
        VkStructureType                     sType;
        const void*                         pNext;
        uint32_t                            accelerationStructureCount;
        const VkAccelerationStructureNV*    pAccelerationStructures;
    } VkWriteDescriptorSetAccelerationStructureNV;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `accelerationStructureCount` is the number of elements in `pAccelerationStructures`.

- `pAccelerationStructures` is a pointer to an array of VkAccelerationStructureNV structures specifying the acceleration structures to update.

Valid Usage

- VUID-VkWriteDescriptorSetAccelerationStructureNV-accelerationStructureCount-03747
  `accelerationStructureCount` must be equal to `descriptorCount` in the extended structure

- VUID-VkWriteDescriptorSetAccelerationStructureNV-pAccelerationStructures-03748
  Each acceleration structure in `pAccelerationStructures` must have been created with `VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR`

- VUID-VkWriteDescriptorSetAccelerationStructureNV-pAccelerationStructures-03749
  If the `nullDescriptor` feature is not enabled, each member of `pAccelerationStructures` must not be VK_NULL_HANDLE

Valid Usage (Implicit)

- VUID-VkWriteDescriptorSetAccelerationStructureNV-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV`

- VUID-VkWriteDescriptorSetAccelerationStructureNV-pAccelerationStructures-parameter
  `pAccelerationStructures` must be a valid pointer to an array of `accelerationStructureCount` valid or VK_NULL_HANDLE VkAccelerationStructureNV handles

- VUID-VkWriteDescriptorSetAccelerationStructureNV-accelerationStructureCount-arraylength
  `accelerationStructureCount` must be greater than `0`

The `VkCopyDescriptorSet` structure is defined as:

    // Provided by VK_VERSION_1_0
    typedef struct VkCopyDescriptorSet {
        VkStructureType    sType;
        const void*        pNext;
        VkDescriptorSet    srcSet;
        uint32_t           srcBinding;
        uint32_t           srcArrayElement;
        VkDescriptorSet    dstSet;
        uint32_t           dstBinding;
        uint32_t           dstArrayElement;
        uint32_t           descriptorCount;
    } VkCopyDescriptorSet;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `srcSet`, `srcBinding`, and `srcArrayElement` are the source set, binding, and array element, respectively. If the descriptor binding identified by `srcSet` and `srcBinding` has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `srcArrayElement` specifies the starting byte offset within the binding to copy from.

- `dstSet`, `dstBinding`, and `dstArrayElement` are the destination set, binding, and array element, respectively. If the descriptor binding identified by `dstSet` and `dstBinding` has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `dstArrayElement` specifies the starting byte offset within the binding to copy to.

- `descriptorCount` is the number of descriptors to copy from the source to destination. If `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 VkWriteDescriptorSet above. If the descriptor binding identified by `srcSet` and `srcBinding` has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `descriptorCount` specifies the number of bytes to copy and the remaining array elements in the source or destination binding refer to the remaining number of bytes in those.

If the `VkDescriptorSetLayoutBinding` for `dstBinding` is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` and `srcBinding` is not `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the new active descriptor type becomes the descriptor type of `srcBinding`. If both `VkDescriptorSetLayoutBinding` for `srcBinding` and `dstBinding` are `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the active descriptor type in each source descriptor is copied into the corresponding destination descriptor. The active descriptor type can be different for each source descriptor.

| Note The intention is that copies to and from mutable descriptors is a simple memcpy. Copies between non-mutable and mutable descriptors are expected to require one memcpy per descriptor to handle the difference in size, but this use case with more than one `descriptorCount` is considered rare.

Valid Usage

- VUID-VkCopyDescriptorSet-srcBinding-00345
  `srcBinding` must be a valid binding within `srcSet`

- VUID-VkCopyDescriptorSet-srcArrayElement-00346
  The sum of `srcArrayElement` and `descriptorCount` must be less than or equal to the number of array elements in the descriptor set binding specified by `srcBinding`, and all applicable consecutive bindings, as described by consecutive binding updates

- VUID-VkCopyDescriptorSet-dstBinding-00347
  `dstBinding` must be a valid binding within `dstSet`

- VUID-VkCopyDescriptorSet-dstArrayElement-00348
  The sum of `dstArrayElement` and `descriptorCount` must be less than or equal to the number of array elements in the descriptor set binding specified by `dstBinding`, and all applicable consecutive bindings, as described by consecutive binding updates

- VUID-VkCopyDescriptorSet-dstBinding-02632
  The type of `dstBinding` within `dstSet` must be equal to the type of `srcBinding` within `srcSet`

- VUID-VkCopyDescriptorSet-srcSet-00349
  If `srcSet` is equal to `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 consecutive binding updates

- VUID-VkCopyDescriptorSet-srcBinding-02223
  If the descriptor type of the descriptor set binding specified by `srcBinding` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, `srcArrayElement` must be an integer multiple of `4`

- VUID-VkCopyDescriptorSet-dstBinding-02224
  If the descriptor type of the descriptor set binding specified by `dstBinding` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, `dstArrayElement` must be an integer multiple of `4`

- VUID-VkCopyDescriptorSet-srcBinding-02225
  If the descriptor type of the descriptor set binding specified by either `srcBinding` or `dstBinding` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, `descriptorCount` must be an integer multiple of `4`

- VUID-VkCopyDescriptorSet-srcSet-01918
  If `srcSet`’s layout was created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` flag set, then `dstSet`’s layout must also have been created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` flag set

- VUID-VkCopyDescriptorSet-srcSet-04885
  If `srcSet`’s layout was created with neither `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` nor `VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT` flags set, then `dstSet`’s layout must have been created without the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT` flag set

- VUID-VkCopyDescriptorSet-srcSet-01920
  If the descriptor pool from which `srcSet` was allocated was created with the `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` flag set, then the descriptor pool from which `dstSet` was allocated must also have been created with the `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` flag set

- VUID-VkCopyDescriptorSet-srcSet-04887
  If the descriptor pool from which `srcSet` was allocated was created with neither `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` nor `VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT` flags set, then the descriptor pool from which `dstSet` was allocated must have been created without the `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT` flag set

- VUID-VkCopyDescriptorSet-dstBinding-02753
  If the descriptor type of the descriptor set binding specified by `dstBinding` is `VK_DESCRIPTOR_TYPE_SAMPLER`, then `dstSet` must not have been allocated with a layout that included immutable samplers for `dstBinding`

- VUID-VkCopyDescriptorSet-dstSet-04612
  If `VkDescriptorSetLayoutBinding` for `dstSet` at `dstBinding` is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the new active descriptor type must exist in the corresponding `pMutableDescriptorTypeLists` list for `dstBinding` if the new active descriptor type is not `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

- VUID-VkCopyDescriptorSet-srcSet-04613
  If `VkDescriptorSetLayoutBinding` for `srcSet` at `srcBinding` is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT` and the `VkDescriptorSetLayoutBinding` for `dstSet` at `dstBinding` is not `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the active descriptor type for the source descriptor must match the descriptor type of `dstBinding`

- VUID-VkCopyDescriptorSet-dstSet-04614
  If `VkDescriptorSetLayoutBinding` for `dstSet` at `dstBinding` is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, and the new active descriptor type is `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`, the `pMutableDescriptorTypeLists` for `srcBinding` and `dstBinding` must match exactly

Valid Usage (Implicit)

- VUID-VkCopyDescriptorSet-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET`

- VUID-VkCopyDescriptorSet-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkCopyDescriptorSet-srcSet-parameter
  `srcSet` must be a valid VkDescriptorSet handle

- VUID-VkCopyDescriptorSet-dstSet-parameter
  `dstSet` must be a valid VkDescriptorSet handle

- VUID-VkCopyDescriptorSet-commonparent
  Both of `dstSet`, and `srcSet` must have been created, allocated, or retrieved from the same VkDevice

#### 14.2.5. Descriptor Update Templates

A descriptor update template specifies a mapping from descriptor update information in host memory to descriptors in a descriptor set. It is designed to avoid passing redundant information to the driver when frequently updating the same set of descriptors in descriptor sets.

Descriptor update template objects are represented by `VkDescriptorUpdateTemplate` handles:

    // Provided by VK_VERSION_1_1
    VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate)

or the equivalent

    // Provided by VK_KHR_descriptor_update_template
    typedef VkDescriptorUpdateTemplate VkDescriptorUpdateTemplateKHR;

#### 14.2.6. Descriptor Set Updates with Templates

Updating a large `VkDescriptorSet` array can be an expensive operation since an application must specify one VkWriteDescriptorSet structure for each descriptor or descriptor array to update, each of which re-specifies the same state when updating the same descriptor in multiple descriptor sets. For cases when an application wishes to update the same set of descriptors in multiple descriptor sets allocated using the same `VkDescriptorSetLayout`, vkUpdateDescriptorSetWithTemplate can be used as a replacement for vkUpdateDescriptorSets.

`VkDescriptorUpdateTemplate` allows implementations to convert a set of descriptor update operations on a single descriptor set to an internal format that, in conjunction with vkUpdateDescriptorSetWithTemplate or vkCmdPushDescriptorSetWithTemplateKHR , can be more efficient compared to calling vkUpdateDescriptorSets or vkCmdPushDescriptorSetKHR . The descriptors themselves are not specified in the `VkDescriptorUpdateTemplate`, rather, offsets into an application provided pointer to host memory are specified, which are combined with a pointer passed to vkUpdateDescriptorSetWithTemplate or vkCmdPushDescriptorSetWithTemplateKHR . This allows large batches of updates to be executed without having to convert application data structures into a strictly-defined Vulkan data structure.

To create a descriptor update template, call:

    // Provided by VK_VERSION_1_1
    VkResult vkCreateDescriptorUpdateTemplate(
        VkDevice                                    device,
        const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkDescriptorUpdateTemplate*                 pDescriptorUpdateTemplate);

or the equivalent command

    // Provided by VK_KHR_descriptor_update_template
    VkResult vkCreateDescriptorUpdateTemplateKHR(
        VkDevice                                    device,
        const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkDescriptorUpdateTemplate*                 pDescriptorUpdateTemplate);

- `device` is the logical device that creates the descriptor update template.

- `pCreateInfo` is a pointer to a VkDescriptorUpdateTemplateCreateInfo structure specifying the set of descriptors to update with a single call to vkCmdPushDescriptorSetWithTemplateKHR or vkUpdateDescriptorSetWithTemplate.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

- `pDescriptorUpdateTemplate` is a pointer to a `VkDescriptorUpdateTemplate` handle in which the resulting descriptor update template object is returned.

Valid Usage (Implicit)

- VUID-vkCreateDescriptorUpdateTemplate-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkCreateDescriptorUpdateTemplate-pCreateInfo-parameter
  `pCreateInfo` must be a valid pointer to a valid VkDescriptorUpdateTemplateCreateInfo structure

- VUID-vkCreateDescriptorUpdateTemplate-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkCreateDescriptorUpdateTemplate-pDescriptorUpdateTemplate-parameter
  `pDescriptorUpdateTemplate` must be a valid pointer to a VkDescriptorUpdateTemplate handle

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

The VkDescriptorUpdateTemplateCreateInfo structure is defined as:

    // Provided by VK_VERSION_1_1
    typedef struct VkDescriptorUpdateTemplateCreateInfo {
        VkStructureType                           sType;
        const void*                               pNext;
        VkDescriptorUpdateTemplateCreateFlags     flags;
        uint32_t                                  descriptorUpdateEntryCount;
        const VkDescriptorUpdateTemplateEntry*    pDescriptorUpdateEntries;
        VkDescriptorUpdateTemplateType            templateType;
        VkDescriptorSetLayout                     descriptorSetLayout;
        VkPipelineBindPoint                       pipelineBindPoint;
        VkPipelineLayout                          pipelineLayout;
        uint32_t                                  set;
    } VkDescriptorUpdateTemplateCreateInfo;

or the equivalent

    // Provided by VK_KHR_descriptor_update_template
    typedef VkDescriptorUpdateTemplateCreateInfo VkDescriptorUpdateTemplateCreateInfoKHR;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `flags` is reserved for future use.

- `descriptorUpdateEntryCount` is the number of elements in the `pDescriptorUpdateEntries` array.

- `pDescriptorUpdateEntries` is a pointer to an array of VkDescriptorUpdateTemplateEntry structures describing the descriptors to be updated by the descriptor update template.

- `templateType` Specifies the type of the descriptor update template. If set to `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET` it can only be used to update descriptor sets with a fixed `descriptorSetLayout`. If set to `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR` it can only be used to push descriptor sets using the provided `pipelineBindPoint`, `pipelineLayout`, and `set` number.

- `descriptorSetLayout` is the descriptor set layout used to build the descriptor update template. All descriptor sets which are going to be updated through the newly created descriptor update template must be created with a layout that matches (is the same as, or defined identically to) this layout. This parameter is ignored if `templateType` is not `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET`.

- `pipelineBindPoint` is a VkPipelineBindPoint indicating the type of the pipeline that will use the descriptors. This parameter is ignored if `templateType` is not `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR`

- `pipelineLayout` is a VkPipelineLayout object used to program the bindings. This parameter is ignored if `templateType` is not `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR`

- `set` is the set number of the descriptor set in the pipeline layout that will be updated. This parameter is ignored if `templateType` is not `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR`

Valid Usage

- VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00350
  If `templateType` is `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET`, `descriptorSetLayout` must be a valid `VkDescriptorSetLayout` handle

- VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00351
  If `templateType` is `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR`, `pipelineBindPoint` must be a valid VkPipelineBindPoint value

- VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00352
  If `templateType` is `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR`, `pipelineLayout` must be a valid `VkPipelineLayout` handle

- VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00353
  If `templateType` is `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR`, `set` must be the unique set number in the pipeline layout that uses a descriptor set layout that was created with `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`

- VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-04615
  If `templateType` is `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET`, `descriptorSetLayout` must not contain a binding with type `VK_DESCRIPTOR_TYPE_MUTABLE_EXT`

Valid Usage (Implicit)

- VUID-VkDescriptorUpdateTemplateCreateInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO`

- VUID-VkDescriptorUpdateTemplateCreateInfo-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkDescriptorUpdateTemplateCreateInfo-flags-zerobitmask
  `flags` must be `0`

- VUID-VkDescriptorUpdateTemplateCreateInfo-pDescriptorUpdateEntries-parameter
  `pDescriptorUpdateEntries` must be a valid pointer to an array of `descriptorUpdateEntryCount` valid VkDescriptorUpdateTemplateEntry structures

- VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-parameter
  `templateType` must be a valid VkDescriptorUpdateTemplateType value

- VUID-VkDescriptorUpdateTemplateCreateInfo-descriptorUpdateEntryCount-arraylength
  `descriptorUpdateEntryCount` must be greater than `0`

- VUID-VkDescriptorUpdateTemplateCreateInfo-commonparent
  Both of `descriptorSetLayout`, and `pipelineLayout` that are valid handles of non-ignored parameters must have been created, allocated, or retrieved from the same VkDevice

    // Provided by VK_VERSION_1_1
    typedef VkFlags VkDescriptorUpdateTemplateCreateFlags;

or the equivalent

    // Provided by VK_KHR_descriptor_update_template
    typedef VkDescriptorUpdateTemplateCreateFlags VkDescriptorUpdateTemplateCreateFlagsKHR;

`VkDescriptorUpdateTemplateCreateFlags` is a bitmask type for setting a mask, but is currently reserved for future use.

The descriptor update template type is determined by the VkDescriptorUpdateTemplateCreateInfo::`templateType` property, which takes the following values:

    // Provided by VK_VERSION_1_1
    typedef enum VkDescriptorUpdateTemplateType {
        VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0,
      // Provided by VK_VERSION_1_1 with VK_KHR_push_descriptor, VK_KHR_descriptor_update_template with VK_KHR_push_descriptor
        VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1,
      // Provided by VK_KHR_descriptor_update_template
        VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
    } VkDescriptorUpdateTemplateType;

or the equivalent

    // Provided by VK_KHR_descriptor_update_template
    typedef VkDescriptorUpdateTemplateType VkDescriptorUpdateTemplateTypeKHR;

- `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET` specifies that the descriptor update template will be used for descriptor set updates only.

- `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR` specifies that the descriptor update template will be used for push descriptor updates only.

The `VkDescriptorUpdateTemplateEntry` structure is defined as:

    // Provided by VK_VERSION_1_1
    typedef struct VkDescriptorUpdateTemplateEntry {
        uint32_t            dstBinding;
        uint32_t            dstArrayElement;
        uint32_t            descriptorCount;
        VkDescriptorType    descriptorType;
        size_t              offset;
        size_t              stride;
    } VkDescriptorUpdateTemplateEntry;

or the equivalent

    // Provided by VK_KHR_descriptor_update_template
    typedef VkDescriptorUpdateTemplateEntry VkDescriptorUpdateTemplateEntryKHR;

- `dstBinding` is the descriptor binding to update when using this descriptor update template.

- `dstArrayElement` is the starting element in the array belonging to `dstBinding`. If the descriptor binding identified by `dstBinding` has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `dstArrayElement` specifies the starting byte offset to update.

- `descriptorCount` is the number of descriptors to update. If `descriptorCount` is greater than the number of remaining array elements in the destination binding, those affect consecutive bindings in a manner similar to VkWriteDescriptorSet above. If the descriptor binding identified by `dstBinding` has a descriptor type of `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then `descriptorCount` specifies the number of bytes to update and the remaining array elements in the destination binding refer to the remaining number of bytes in it.

- `descriptorType` is a VkDescriptorType specifying the type of the descriptor.

- `offset` is the offset in bytes of the first binding in the raw data structure.

- `stride` is the stride in bytes between two consecutive array elements of the descriptor update information in the raw data structure. The actual pointer ptr for each array element j of update entry i is computed using the following formula:

          const char *ptr = (const char *)pData + pDescriptorUpdateEntries[i].offset + j * pDescriptorUpdateEntries[i].stride

  The stride is useful in case the bindings are stored in structs along with other data. If `descriptorType` is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK` then the value of `stride` is ignored and the stride is assumed to be `1`, i.e. the descriptor update information for them is always specified as a contiguous range.

Valid Usage

- VUID-VkDescriptorUpdateTemplateEntry-dstBinding-00354
  `dstBinding` must be a valid binding in the descriptor set layout implicitly specified when using a descriptor update template to update descriptors

- VUID-VkDescriptorUpdateTemplateEntry-dstArrayElement-00355
  `dstArrayElement` and `descriptorCount` must be less than or equal to the number of array elements in the descriptor set binding implicitly specified when using a descriptor update template to update descriptors, and all applicable consecutive bindings, as described by consecutive binding updates

- VUID-VkDescriptorUpdateTemplateEntry-descriptor-02226
  If `descriptor` type is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, `dstArrayElement` must be an integer multiple of `4`

- VUID-VkDescriptorUpdateTemplateEntry-descriptor-02227
  If `descriptor` type is `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, `descriptorCount` must be an integer multiple of `4`

Valid Usage (Implicit)

- VUID-VkDescriptorUpdateTemplateEntry-descriptorType-parameter
  `descriptorType` must be a valid VkDescriptorType value

To destroy a descriptor update template, call:

    // Provided by VK_VERSION_1_1
    void vkDestroyDescriptorUpdateTemplate(
        VkDevice                                    device,
        VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
        const VkAllocationCallbacks*                pAllocator);

or the equivalent command

    // Provided by VK_KHR_descriptor_update_template
    void vkDestroyDescriptorUpdateTemplateKHR(
        VkDevice                                    device,
        VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
        const VkAllocationCallbacks*                pAllocator);

- `device` is the logical device that has been used to create the descriptor update template

- `descriptorUpdateTemplate` is the descriptor update template to destroy.

- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.

Valid Usage

- VUID-vkDestroyDescriptorUpdateTemplate-descriptorSetLayout-00356
  If `VkAllocationCallbacks` were provided when `descriptorUpdateTemplate` was created, a compatible set of callbacks must be provided here

- VUID-vkDestroyDescriptorUpdateTemplate-descriptorSetLayout-00357
  If no `VkAllocationCallbacks` were provided when `descriptorUpdateTemplate` was created, `pAllocator` must be `NULL`

Valid Usage (Implicit)

- VUID-vkDestroyDescriptorUpdateTemplate-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkDestroyDescriptorUpdateTemplate-descriptorUpdateTemplate-parameter
  If `descriptorUpdateTemplate` is not VK_NULL_HANDLE, `descriptorUpdateTemplate` must be a valid VkDescriptorUpdateTemplate handle

- VUID-vkDestroyDescriptorUpdateTemplate-pAllocator-parameter
  If `pAllocator` is not `NULL`, `pAllocator` must be a valid pointer to a valid VkAllocationCallbacks structure

- VUID-vkDestroyDescriptorUpdateTemplate-descriptorUpdateTemplate-parent
  If `descriptorUpdateTemplate` is a valid handle, it must have been created, allocated, or retrieved from `device`

Host Synchronization

- Host access to `descriptorUpdateTemplate` must be externally synchronized

Once a `VkDescriptorUpdateTemplate` has been created, descriptor sets can be updated by calling:

    // Provided by VK_VERSION_1_1
    void vkUpdateDescriptorSetWithTemplate(
        VkDevice                                    device,
        VkDescriptorSet                             descriptorSet,
        VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
        const void*                                 pData);

or the equivalent command

    // Provided by VK_KHR_descriptor_update_template
    void vkUpdateDescriptorSetWithTemplateKHR(
        VkDevice                                    device,
        VkDescriptorSet                             descriptorSet,
        VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
        const void*                                 pData);

- `device` is the logical device that updates the descriptor set.

- `descriptorSet` is the descriptor set to update

- `descriptorUpdateTemplate` is a VkDescriptorUpdateTemplate object specifying the update mapping between `pData` and the descriptor set to update.

- `pData` is a pointer to memory containing one or more VkDescriptorImageInfo, VkDescriptorBufferInfo, or VkBufferView structures or VkAccelerationStructureKHR or VkAccelerationStructureNV handles used to write the descriptors.

Valid Usage

- VUID-vkUpdateDescriptorSetWithTemplate-pData-01685
  `pData` must be a valid pointer to a memory containing one or more valid instances of VkDescriptorImageInfo, VkDescriptorBufferInfo, or VkBufferView in a layout defined by `descriptorUpdateTemplate` when it was created with vkCreateDescriptorUpdateTemplate

- VUID-vkUpdateDescriptorSetWithTemplate-descriptorSet-06995
  Host access to `descriptorSet` must be externally synchronized unless explicitly denoted otherwise for specific flags

Valid Usage (Implicit)

- VUID-vkUpdateDescriptorSetWithTemplate-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkUpdateDescriptorSetWithTemplate-descriptorSet-parameter
  `descriptorSet` must be a valid VkDescriptorSet handle

- VUID-vkUpdateDescriptorSetWithTemplate-descriptorUpdateTemplate-parameter
  `descriptorUpdateTemplate` must be a valid VkDescriptorUpdateTemplate handle

- VUID-vkUpdateDescriptorSetWithTemplate-descriptorUpdateTemplate-parent
  `descriptorUpdateTemplate` must have been created, allocated, or retrieved from `device`

API example

    struct AppBufferView {
        VkBufferView bufferView;
        uint32_t     applicationRelatedInformation;
    };

    struct AppDataStructure
    {
        VkDescriptorImageInfo  imageInfo;          // a single image info
        VkDescriptorBufferInfo bufferInfoArray[3]; // 3 buffer infos in an array
        AppBufferView          bufferView[2];      // An application defined structure containing a bufferView
        // ... some more application related data
    };

    const VkDescriptorUpdateTemplateEntry descriptorUpdateTemplateEntries[] =
    {
        // binding to a single image descriptor
        {
            0,                                           // binding
            0,                                           // dstArrayElement
            1,                                           // descriptorCount
            VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,   // descriptorType
            offsetof(AppDataStructure, imageInfo),       // offset
            0                                            // stride is not required if descriptorCount is 1
        },

        // binding to an array of buffer descriptors
        {
            1,                                           // binding
            0,                                           // dstArrayElement
            3,                                           // descriptorCount
            VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,           // descriptorType
            offsetof(AppDataStructure, bufferInfoArray), // offset
            sizeof(VkDescriptorBufferInfo)               // stride, descriptor buffer infos are compact
        },

        // binding to an array of buffer views
        {
            2,                                           // binding
            0,                                           // dstArrayElement
            2,                                           // descriptorCount
            VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,     // descriptorType
            offsetof(AppDataStructure, bufferView) +
              offsetof(AppBufferView, bufferView),       // offset
            sizeof(AppBufferView)                        // stride, bufferViews do not have to be compact
        },
    };

    // create a descriptor update template for descriptor set updates
    const VkDescriptorUpdateTemplateCreateInfo createInfo =
    {
        VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,  // sType
        NULL,                                                      // pNext
        0,                                                         // flags
        3,                                                         // descriptorUpdateEntryCount
        descriptorUpdateTemplateEntries,                           // pDescriptorUpdateEntries
        VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,         // templateType
        myLayout,                                                  // descriptorSetLayout
        0,                                                         // pipelineBindPoint, ignored by given templateType
        0,                                                         // pipelineLayout, ignored by given templateType
        0,                                                         // set, ignored by given templateType
    };

    VkDescriptorUpdateTemplate myDescriptorUpdateTemplate;
    myResult = vkCreateDescriptorUpdateTemplate(
        myDevice,
        &createInfo,
        NULL,
        &myDescriptorUpdateTemplate);

    AppDataStructure appData;

    // fill appData here or cache it in your engine
    vkUpdateDescriptorSetWithTemplate(myDevice, myDescriptorSet, myDescriptorUpdateTemplate, &appData);

#### 14.2.7. Descriptor Set Binding

To bind one or more descriptor sets to a command buffer, call:

    // Provided by VK_VERSION_1_0
    void vkCmdBindDescriptorSets(
        VkCommandBuffer                             commandBuffer,
        VkPipelineBindPoint                         pipelineBindPoint,
        VkPipelineLayout                            layout,
        uint32_t                                    firstSet,
        uint32_t                                    descriptorSetCount,
        const VkDescriptorSet*                      pDescriptorSets,
        uint32_t                                    dynamicOffsetCount,
        const uint32_t*                             pDynamicOffsets);

- `commandBuffer` is the command buffer that the descriptor sets will be bound to.

- `pipelineBindPoint` is a VkPipelineBindPoint indicating the type of the pipeline that will use the descriptors. There is a separate set of bind points for each pipeline type, so binding one does not disturb the others.

- `layout` is a VkPipelineLayout object used to program the bindings.

- `firstSet` is the set number of the first descriptor set to be bound.

- `descriptorSetCount` is the number of elements in the `pDescriptorSets` array.

- `pDescriptorSets` is a pointer to an array of handles to VkDescriptorSet objects describing the descriptor sets to bind to.

- `dynamicOffsetCount` is the number of dynamic offsets in the `pDynamicOffsets` array.

- `pDynamicOffsets` is a pointer to an array of `uint32_t` values specifying dynamic offsets.

`vkCmdBindDescriptorSets` binds descriptor sets `pDescriptorSets`[0..`descriptorSetCount`-1] to set numbers [`firstSet`..`firstSet`+`descriptorSetCount`-1] for subsequent bound pipeline commands set by `pipelineBindPoint`. Any bindings that were previously applied via these sets , or calls to vkCmdSetDescriptorBufferOffsetsEXT or vkCmdBindDescriptorBufferEmbeddedSamplersEXT, are no longer valid.

Once bound, a descriptor set affects rendering of subsequent commands that interact with the given pipeline type in the command buffer until either a different set is bound to the same set number, or the set is disturbed as described in 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 drawing or dispatching 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.

When consuming a descriptor, a descriptor is considered valid if the descriptor is not undefined as described by descriptor set allocation. If the `nullDescriptor` feature is enabled, a null descriptor is also considered valid. A descriptor that was disturbed by Pipeline Layout Compatibility, or was never bound by `vkCmdBindDescriptorSets` is not considered valid. If a pipeline accesses a descriptor either statically or dynamically depending on the VkDescriptorBindingFlagBits, the consuming descriptor type in the pipeline must match the VkDescriptorType in VkDescriptorSetLayoutCreateInfo for the descriptor to be considered valid. If a descriptor is a mutable descriptor, the consuming descriptor type in the pipeline must match the active descriptor type for the descriptor to be considered valid.

| Note Further validation may be carried out beyond validation for descriptor types, e.g. Texel Input Validation.

If any of the sets being bound include dynamic uniform or storage buffers, then `pDynamicOffsets` includes one element for each array element in each dynamic descriptor type binding in each set. Values are taken from `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. `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 `pDynamicOffsets`, and the base address of the buffer plus base offset in the descriptor set. The range of the dynamic uniform and storage buffer bindings is the buffer range as specified in the descriptor set.

Each of the `pDescriptorSets` must be compatible with the pipeline layout specified by `layout`. The layout used to program the bindings must also be compatible with the pipeline used in subsequent bound pipeline commands with that pipeline type, as defined in the Pipeline Layout Compatibility section.

The descriptor set contents bound by a call to `vkCmdBindDescriptorSets` may be consumed at the following times:

- For descriptor bindings created with the `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT` bit set, the contents may be consumed when the command buffer is submitted to a queue, or during shader execution of the resulting draws and dispatches, or any time in between. Otherwise,

- during host execution of the command, or during shader execution of the resulting draws and dispatches, or any time in between.

Thus, the contents of a descriptor set binding must not be altered (overwritten by an update command, or freed) between the first point in time that it may be consumed, and when the command completes executing on the queue.

The contents of `pDynamicOffsets` are consumed immediately during execution of `vkCmdBindDescriptorSets`. Once all pending uses have completed, it is legal to update and reuse a descriptor set.

Valid Usage

- VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358
  Each element of `pDescriptorSets` must have been allocated with a `VkDescriptorSetLayout` that matches (is the same as, or identically defined as) the `VkDescriptorSetLayout` at set n in `layout`, where n is the sum of `firstSet` and the index into `pDescriptorSets`

- VUID-vkCmdBindDescriptorSets-dynamicOffsetCount-00359
  `dynamicOffsetCount` must be equal to the total number of dynamic descriptors in `pDescriptorSets`

- VUID-vkCmdBindDescriptorSets-firstSet-00360
  The sum of `firstSet` and `descriptorSetCount` must be less than or equal to VkPipelineLayoutCreateInfo::`setLayoutCount` provided when `layout` was created

- VUID-vkCmdBindDescriptorSets-pipelineBindPoint-00361
  `pipelineBindPoint` must be supported by the `commandBuffer`’s parent `VkCommandPool`’s queue family

- VUID-vkCmdBindDescriptorSets-pDynamicOffsets-01971
  Each element of `pDynamicOffsets` which corresponds to a descriptor binding with type `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` must be a multiple of `VkPhysicalDeviceLimits`::`minUniformBufferOffsetAlignment`

- VUID-vkCmdBindDescriptorSets-pDynamicOffsets-01972
  Each element of `pDynamicOffsets` which corresponds to a descriptor binding with type `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` must be a multiple of `VkPhysicalDeviceLimits`::`minStorageBufferOffsetAlignment`

- VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979
  For each dynamic uniform or storage buffer binding in `pDescriptorSets`, the sum of the effective offset and the range of the binding must be less than or equal to the size of the buffer

- VUID-vkCmdBindDescriptorSets-pDescriptorSets-06715
  For each dynamic uniform or storage buffer binding in `pDescriptorSets`, if the range was set with `VK_WHOLE_SIZE` then `pDynamicOffsets` which corresponds to the descriptor binding must be 0

- VUID-vkCmdBindDescriptorSets-pDescriptorSets-04616
  Each element of `pDescriptorSets` must not have been allocated from a `VkDescriptorPool` with the `VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT` flag set

- VUID-vkCmdBindDescriptorSets-graphicsPipelineLibrary-06754
  If `graphicsPipelineLibrary` is not enabled, each element of `pDescriptorSets` must be a valid VkDescriptorSet

- VUID-vkCmdBindDescriptorSets-pDescriptorSets-08010
  Each element of `pDescriptorSets` must have been allocated with a `VkDescriptorSetLayout` which was not created with `VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT`

Valid Usage (Implicit)

- VUID-vkCmdBindDescriptorSets-commandBuffer-parameter
  `commandBuffer` must be a valid VkCommandBuffer handle

- VUID-vkCmdBindDescriptorSets-pipelineBindPoint-parameter
  `pipelineBindPoint` must be a valid VkPipelineBindPoint value

- VUID-vkCmdBindDescriptorSets-layout-parameter
  `layout` must be a valid VkPipelineLayout handle

- VUID-vkCmdBindDescriptorSets-pDescriptorSets-parameter
  `pDescriptorSets` must be a valid pointer to an array of `descriptorSetCount` valid or VK_NULL_HANDLE VkDescriptorSet handles

- VUID-vkCmdBindDescriptorSets-pDynamicOffsets-parameter
  If `dynamicOffsetCount` is not `0`, `pDynamicOffsets` must be a valid pointer to an array of `dynamicOffsetCount` `uint32_t` values

- VUID-vkCmdBindDescriptorSets-commandBuffer-recording
  `commandBuffer` must be in the recording state

- VUID-vkCmdBindDescriptorSets-commandBuffer-cmdpool
  The `VkCommandPool` that `commandBuffer` was allocated from must support graphics, or compute operations

- VUID-vkCmdBindDescriptorSets-videocoding
  This command must only be called outside of a video coding scope

- VUID-vkCmdBindDescriptorSets-descriptorSetCount-arraylength
  `descriptorSetCount` must be greater than `0`

- VUID-vkCmdBindDescriptorSets-commonparent
  Each of `commandBuffer`, `layout`, and the elements of `pDescriptorSets` that are valid handles of non-ignored parameters must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization

- Host access to `commandBuffer` must be externally synchronized

- Host access to the `VkCommandPool` that `commandBuffer` was allocated from must be externally synchronized

Command Properties

Command Buffer Levels | Render Pass Scope | Video Coding Scope | Supported Queue Types | Command Type
--- | --- | --- | --- | ---
Primary Secondary | Both | Outside | Graphics Compute | State

#### 14.2.8. Push Descriptor Updates

In addition to allocating descriptor sets and binding them to a command buffer, an application can record descriptor updates into the command buffer.

To push descriptor updates into a command buffer, call:

    // Provided by VK_KHR_push_descriptor
    void vkCmdPushDescriptorSetKHR(
        VkCommandBuffer                             commandBuffer,
        VkPipelineBindPoint                         pipelineBindPoint,
        VkPipelineLayout                            layout,
        uint32_t                                    set,
        uint32_t                                    descriptorWriteCount,
        const VkWriteDescriptorSet*                 pDescriptorWrites);

- `commandBuffer` is the command buffer that the descriptors will be recorded in.

- `pipelineBindPoint` is a VkPipelineBindPoint indicating the type of the pipeline that will use the descriptors. There is a separate set of push descriptor bindings for each pipeline type, so binding one does not disturb the others.

- `layout` is a VkPipelineLayout object used to program the bindings.

- `set` is the set number of the descriptor set in the pipeline layout that will be updated.

- `descriptorWriteCount` is the number of elements in the `pDescriptorWrites` array.

- `pDescriptorWrites` is a pointer to an array of VkWriteDescriptorSet structures describing the descriptors to be updated.

Push descriptors are a small bank of descriptors whose storage is internally managed by the command buffer rather than being written into a descriptor set and later bound to a command buffer. Push descriptors allow for incremental updates of descriptors without managing the lifetime of descriptor sets.

When a command buffer begins recording, all push descriptors are undefined. Push descriptors can be updated incrementally and cause shaders to use the updated descriptors for subsequent bound pipeline commands with the pipeline type set by `pipelineBindPoint` until the descriptor is overwritten, or else until the set is disturbed as described in Pipeline Layout Compatibility. When the set is disturbed or push descriptors with a different descriptor set layout are set, all push descriptors are undefined.

Push descriptors that are statically used by a pipeline must not be undefined at the time that a drawing or dispatching command is recorded to execute using that pipeline. This includes immutable sampler descriptors, which must be pushed before they are accessed by a pipeline (the immutable samplers are pushed, rather than the samplers in `pDescriptorWrites`). Push descriptors that are not statically used can remain undefined.

Push descriptors do not use dynamic offsets. Instead, the corresponding non-dynamic descriptor types can be used and the `offset` member of VkDescriptorBufferInfo can be changed each time the descriptor is written.

Each element of `pDescriptorWrites` is interpreted as in VkWriteDescriptorSet, except the `dstSet` member is ignored.

To push an immutable sampler, use a VkWriteDescriptorSet with `dstBinding` and `dstArrayElement` selecting the immutable sampler’s binding. If the descriptor type is `VK_DESCRIPTOR_TYPE_SAMPLER`, the `pImageInfo` parameter is ignored and the immutable sampler is taken from the push descriptor set layout in the pipeline layout. If the descriptor type is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, the `sampler` member of the `pImageInfo` parameter is ignored and the immutable sampler is taken from the push descriptor set layout in the pipeline layout.

Valid Usage

- VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363
  `pipelineBindPoint` must be supported by the `commandBuffer`’s parent `VkCommandPool`’s queue family

- VUID-vkCmdPushDescriptorSetKHR-set-00364
  `set` must be less than VkPipelineLayoutCreateInfo::`setLayoutCount` provided when `layout` was created

- VUID-vkCmdPushDescriptorSetKHR-set-00365
  `set` must be the unique set number in the pipeline layout that uses a descriptor set layout that was created with `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`

- VUID-vkCmdPushDescriptorSetKHR-pDescriptorWrites-06494
  For each element i where `pDescriptorWrites`[i].`descriptorType` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, or `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, `pDescriptorWrites`[i].`pImageInfo` must be a valid pointer to an array of `pDescriptorWrites`[i].`descriptorCount` valid `VkDescriptorImageInfo` structures

Valid Usage (Implicit)

- VUID-vkCmdPushDescriptorSetKHR-commandBuffer-parameter
  `commandBuffer` must be a valid VkCommandBuffer handle

- VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-parameter
  `pipelineBindPoint` must be a valid VkPipelineBindPoint value

- VUID-vkCmdPushDescriptorSetKHR-layout-parameter
  `layout` must be a valid VkPipelineLayout handle

- VUID-vkCmdPushDescriptorSetKHR-pDescriptorWrites-parameter
  `pDescriptorWrites` must be a valid pointer to an array of `descriptorWriteCount` valid VkWriteDescriptorSet structures

- VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
  `commandBuffer` must be in the recording state

- VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool
  The `VkCommandPool` that `commandBuffer` was allocated from must support graphics, or compute operations

- VUID-vkCmdPushDescriptorSetKHR-videocoding
  This command must only be called outside of a video coding scope

- VUID-vkCmdPushDescriptorSetKHR-descriptorWriteCount-arraylength
  `descriptorWriteCount` must be greater than `0`

- VUID-vkCmdPushDescriptorSetKHR-commonparent
  Both of `commandBuffer`, and `layout` must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization

- Host access to `commandBuffer` must be externally synchronized

- Host access to the `VkCommandPool` that `commandBuffer` was allocated from must be externally synchronized

Command Properties

Command Buffer Levels | Render Pass Scope | Video Coding Scope | Supported Queue Types | Command Type
--- | --- | --- | --- | ---
Primary Secondary | Both | Outside | Graphics Compute | State

#### 14.2.9. Push Descriptor Updates with Descriptor Update Templates

It is also possible to use a descriptor update template to specify the push descriptors to update. To do so, call:

    // Provided by VK_VERSION_1_1 with VK_KHR_push_descriptor, VK_KHR_descriptor_update_template with VK_KHR_push_descriptor
    void vkCmdPushDescriptorSetWithTemplateKHR(
        VkCommandBuffer                             commandBuffer,
        VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
        VkPipelineLayout                            layout,
        uint32_t                                    set,
        const void*                                 pData);

- `commandBuffer` is the command buffer that the descriptors will be recorded in.

- `descriptorUpdateTemplate` is a descriptor update template defining how to interpret the descriptor information in `pData`.

- `layout` is a VkPipelineLayout object used to program the bindings. It must be compatible with the layout used to create the `descriptorUpdateTemplate` handle.

- `set` is the set number of the descriptor set in the pipeline layout that will be updated. This must be the same number used to create the `descriptorUpdateTemplate` handle.

- `pData` is a pointer to memory containing descriptors for the templated update.

Valid Usage

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-commandBuffer-00366
  The `pipelineBindPoint` specified during the creation of the descriptor update template must be supported by the `commandBuffer`’s parent `VkCommandPool`’s queue family

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-pData-01686
  `pData` must be a valid pointer to a memory containing one or more valid instances of VkDescriptorImageInfo, VkDescriptorBufferInfo, or VkBufferView in a layout defined by `descriptorUpdateTemplate` when it was created with vkCreateDescriptorUpdateTemplate

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-layout-07993
  `layout` must be compatible with the layout used to create `descriptorUpdateTemplate`

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-descriptorUpdateTemplate-07994
  `descriptorUpdateTemplate` must have been created with a `templateType` of `VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR`

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-set-07995
  `set` must be the same value used to create `descriptorUpdateTemplate`

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-set-07304
  `set` must be less than VkPipelineLayoutCreateInfo::`setLayoutCount` provided when `layout` was created

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-set-07305
  `set` must be the unique set number in the pipeline layout that uses a descriptor set layout that was created with `VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR`

Valid Usage (Implicit)

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-commandBuffer-parameter
  `commandBuffer` must be a valid VkCommandBuffer handle

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-descriptorUpdateTemplate-parameter
  `descriptorUpdateTemplate` must be a valid VkDescriptorUpdateTemplate handle

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-layout-parameter
  `layout` must be a valid VkPipelineLayout handle

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-commandBuffer-recording
  `commandBuffer` must be in the recording state

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-commandBuffer-cmdpool
  The `VkCommandPool` that `commandBuffer` was allocated from must support graphics, or compute operations

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-videocoding
  This command must only be called outside of a video coding scope

- VUID-vkCmdPushDescriptorSetWithTemplateKHR-commonparent
  Each of `commandBuffer`, `descriptorUpdateTemplate`, and `layout` must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization

- Host access to `commandBuffer` must be externally synchronized

- Host access to the `VkCommandPool` that `commandBuffer` was allocated from must be externally synchronized

Command Properties

Command Buffer Levels | Render Pass Scope | Video Coding Scope | Supported Queue Types | Command Type
--- | --- | --- | --- | ---
Primary Secondary | Both | Outside | Graphics Compute | State

API example

    struct AppDataStructure
    {
        VkDescriptorImageInfo  imageInfo;          // a single image info
        // ... some more application related data
    };

    const VkDescriptorUpdateTemplateEntry descriptorUpdateTemplateEntries[] =
    {
        // binding to a single image descriptor
        {
            0,                                           // binding
            0,                                           // dstArrayElement
            1,                                           // descriptorCount
            VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,   // descriptorType
            offsetof(AppDataStructure, imageInfo),       // offset
            0                                            // stride is not required if descriptorCount is 1
        }
    };

    // create a descriptor update template for push descriptor set updates
    const VkDescriptorUpdateTemplateCreateInfo createInfo =
    {
        VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,  // sType
        NULL,                                                      // pNext
        0,                                                         // flags
        1,                                                         // descriptorUpdateEntryCount
        descriptorUpdateTemplateEntries,                           // pDescriptorUpdateEntries
        VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR,   // templateType
        0,                                                         // descriptorSetLayout, ignored by given templateType
        VK_PIPELINE_BIND_POINT_GRAPHICS,                           // pipelineBindPoint
        myPipelineLayout,                                          // pipelineLayout
        0,                                                         // set
    };

    VkDescriptorUpdateTemplate myDescriptorUpdateTemplate;
    myResult = vkCreateDescriptorUpdateTemplate(
        myDevice,
        &createInfo,
        NULL,
        &myDescriptorUpdateTemplate);

    AppDataStructure appData;
    // fill appData here or cache it in your engine
    vkCmdPushDescriptorSetWithTemplateKHR(myCmdBuffer, myDescriptorUpdateTemplate, myPipelineLayout, 0,&appData);

#### 14.2.10. 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.

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

To update push constants, call:

    // Provided by VK_VERSION_1_0
    void vkCmdPushConstants(
        VkCommandBuffer                             commandBuffer,
        VkPipelineLayout                            layout,
        VkShaderStageFlags                          stageFlags,
        uint32_t                                    offset,
        uint32_t                                    size,
        const void*                                 pValues);

- `commandBuffer` is the command buffer in which the push constant update will be recorded.

- `layout` is the pipeline layout used to program the push constant updates.

- `stageFlags` is a bitmask of VkShaderStageFlagBits specifying the shader stages that will use the push constants in the updated range.

- `offset` is the start offset of the push constant range to update, in units of bytes.

- `size` is the size of the push constant range to update, in units of bytes.

- `pValues` is a pointer to an array of `size` bytes containing the new push constant values.

When a command buffer begins recording, all push constant values are undefined. Reads of undefined push constant values by the executing shader return undefined values.

Push constant values can be updated incrementally, causing shader stages in `stageFlags` to read the new data from `pValues` for push constants modified by this command, while still reading the previous data for push constants not modified by this command. When a bound pipeline command is issued, the bound pipeline’s layout must be compatible with the layouts used to set the values of all push constants in the pipeline layout’s push constant ranges, as described in Pipeline Layout Compatibility. Binding a pipeline with a layout that is not compatible with the push constant layout does not disturb the push constant values.

| Note As `stageFlags` needs to include all flags the relevant push constant ranges were created with, any flags that are not supported by the queue family that the VkCommandPool used to allocate `commandBuffer` was created on are ignored.

Valid Usage

- VUID-vkCmdPushConstants-offset-01795
  For each byte in the range specified by `offset` and `size` and for each shader stage in `stageFlags`, there must be a push constant range in `layout` that includes that byte and that stage

- VUID-vkCmdPushConstants-offset-01796
  For each byte in the range specified by `offset` and `size` and for each push constant range that overlaps that byte, `stageFlags` must include all stages in that push constant range’s VkPushConstantRange::`stageFlags`

- VUID-vkCmdPushConstants-offset-00368
  `offset` must be a multiple of `4`

- VUID-vkCmdPushConstants-size-00369
  `size` must be a multiple of `4`

- VUID-vkCmdPushConstants-offset-00370
  `offset` must be less than `VkPhysicalDeviceLimits`::`maxPushConstantsSize`

- VUID-vkCmdPushConstants-size-00371
  `size` must be less than or equal to `VkPhysicalDeviceLimits`::`maxPushConstantsSize` minus `offset`

Valid Usage (Implicit)

- VUID-vkCmdPushConstants-commandBuffer-parameter
  `commandBuffer` must be a valid VkCommandBuffer handle

- VUID-vkCmdPushConstants-layout-parameter
  `layout` must be a valid VkPipelineLayout handle

- VUID-vkCmdPushConstants-stageFlags-parameter
  `stageFlags` must be a valid combination of VkShaderStageFlagBits values

- VUID-vkCmdPushConstants-stageFlags-requiredbitmask
  `stageFlags` must not be `0`

- VUID-vkCmdPushConstants-pValues-parameter
  `pValues` must be a valid pointer to an array of `size` bytes

- VUID-vkCmdPushConstants-commandBuffer-recording
  `commandBuffer` must be in the recording state

- VUID-vkCmdPushConstants-commandBuffer-cmdpool
  The `VkCommandPool` that `commandBuffer` was allocated from must support graphics, or compute operations

- VUID-vkCmdPushConstants-videocoding
  This command must only be called outside of a video coding scope

- VUID-vkCmdPushConstants-size-arraylength
  `size` must be greater than `0`

- VUID-vkCmdPushConstants-commonparent
  Both of `commandBuffer`, and `layout` must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization

- Host access to `commandBuffer` must be externally synchronized

- Host access to the `VkCommandPool` that `commandBuffer` was allocated from must be externally synchronized

Command Properties

Command Buffer Levels | Render Pass Scope | Video Coding Scope | Supported Queue Types | Command Type
--- | --- | --- | --- | ---
Primary Secondary | Both | Outside | Graphics Compute | State

### 14.3. Physical Storage Buffer Access

To query a 64-bit buffer device address value through which buffer memory can be accessed in a shader, call:

    // Provided by VK_VERSION_1_2
    VkDeviceAddress vkGetBufferDeviceAddress(
        VkDevice                                    device,
        const VkBufferDeviceAddressInfo*            pInfo);

or the equivalent command

    // Provided by VK_KHR_buffer_device_address
    VkDeviceAddress vkGetBufferDeviceAddressKHR(
        VkDevice                                    device,
        const VkBufferDeviceAddressInfo*            pInfo);

or the equivalent command

    // Provided by VK_EXT_buffer_device_address
    VkDeviceAddress vkGetBufferDeviceAddressEXT(
        VkDevice                                    device,
        const VkBufferDeviceAddressInfo*            pInfo);

- `device` is the logical device that the buffer was created on.

- `pInfo` is a pointer to a VkBufferDeviceAddressInfo structure specifying the buffer to retrieve an address for.

The 64-bit return value is an address of the start of `pInfo->buffer`. The address range starting at this value and whose size is the size of the buffer can be used in a shader to access the memory bound to that buffer, 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. A value of zero is reserved as a “null” pointer and must not be returned as a valid buffer device address. All loads, stores, and atomics in a shader through `PhysicalStorageBuffer` pointers must access addresses in the address range of some buffer.

If the buffer was created with a non-zero value of VkBufferOpaqueCaptureAddressCreateInfo::`opaqueCaptureAddress` or VkBufferDeviceAddressCreateInfoEXT::`deviceAddress`, the return value will be the same address that was returned at capture time.

The returned address must satisfy the alignment requirement specified by VkMemoryRequirements::`alignment` for the buffer in VkBufferDeviceAddressInfo::`buffer`.

If multiple VkBuffer objects are bound to overlapping ranges of VkDeviceMemory, implementations may return address ranges which overlap. In this case, it is ambiguous which VkBuffer is associated with any given device address. For purposes of valid usage, if multiple VkBuffer objects can be attributed to a device address, a VkBuffer is selected such that valid usage passes, if it exists.

Valid Usage

- VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324
  The `bufferDeviceAddress` or `VkPhysicalDeviceBufferDeviceAddressFeaturesEXT`::`bufferDeviceAddress` feature must be enabled

- VUID-vkGetBufferDeviceAddress-device-03325
  If `device` was created with multiple physical devices, then the `bufferDeviceAddressMultiDevice` or `VkPhysicalDeviceBufferDeviceAddressFeaturesEXT`::`bufferDeviceAddressMultiDevice` feature must be enabled

Valid Usage (Implicit)

- VUID-vkGetBufferDeviceAddress-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetBufferDeviceAddress-pInfo-parameter
  `pInfo` must be a valid pointer to a valid VkBufferDeviceAddressInfo structure

The `VkBufferDeviceAddressInfo` structure is defined as:

    // Provided by VK_VERSION_1_2
    typedef struct VkBufferDeviceAddressInfo {
        VkStructureType    sType;
        const void*        pNext;
        VkBuffer           buffer;
    } VkBufferDeviceAddressInfo;

or the equivalent

    // Provided by VK_KHR_buffer_device_address
    typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR;

or the equivalent

    // Provided by VK_EXT_buffer_device_address
    typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `buffer` specifies the buffer whose address is being queried.

Valid Usage

- VUID-VkBufferDeviceAddressInfo-buffer-02600
  If `buffer` is non-sparse and was not created with the `VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT` flag, then it must be bound completely and contiguously to a single `VkDeviceMemory` object

- VUID-VkBufferDeviceAddressInfo-buffer-02601
  `buffer` must have been created with `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT`

Valid Usage (Implicit)

- VUID-VkBufferDeviceAddressInfo-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO`

- VUID-VkBufferDeviceAddressInfo-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkBufferDeviceAddressInfo-buffer-parameter
  `buffer` must be a valid VkBuffer handle

To query a 64-bit buffer opaque capture address, call:

    // Provided by VK_VERSION_1_2
    uint64_t vkGetBufferOpaqueCaptureAddress(
        VkDevice                                    device,
        const VkBufferDeviceAddressInfo*            pInfo);

or the equivalent command

    // Provided by VK_KHR_buffer_device_address
    uint64_t vkGetBufferOpaqueCaptureAddressKHR(
        VkDevice                                    device,
        const VkBufferDeviceAddressInfo*            pInfo);

- `device` is the logical device that the buffer was created on.

- `pInfo` is a pointer to a VkBufferDeviceAddressInfo structure specifying the buffer to retrieve an address for.

The 64-bit return value is an opaque capture address of the start of `pInfo->buffer`.

If the buffer was created with a non-zero value of VkBufferOpaqueCaptureAddressCreateInfo::`opaqueCaptureAddress` the return value must be the same address.

Valid Usage

- VUID-vkGetBufferOpaqueCaptureAddress-None-03326
  The `bufferDeviceAddress` feature must be enabled

- VUID-vkGetBufferOpaqueCaptureAddress-device-03327
  If `device` was created with multiple physical devices, then the `bufferDeviceAddressMultiDevice` feature must be enabled

Valid Usage (Implicit)

- VUID-vkGetBufferOpaqueCaptureAddress-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetBufferOpaqueCaptureAddress-pInfo-parameter
  `pInfo` must be a valid pointer to a valid VkBufferDeviceAddressInfo structure

### 14.4. Descriptor Buffers

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

#### 14.4.1. 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.

To determine the amount of memory needed to store all descriptors with a given layout, call:

    // Provided by VK_EXT_descriptor_buffer
    void vkGetDescriptorSetLayoutSizeEXT(
        VkDevice                                    device,
        VkDescriptorSetLayout                       layout,
        VkDeviceSize*                               pLayoutSizeInBytes);

- `device` is the logical device that gets the size.

- `layout` is the descriptor set layout being queried.

- `pLayoutSizeInBytes` is a pointer to VkDeviceSize where the size in bytes will be written.

The size of a descriptor set layout will be at least as large as the sum total of the size of all descriptors in the layout, and may be larger. This size represents the amount of memory that will be required to store all of the descriptors for this layout in memory, when placed according to the layout’s offsets as obtained by vkGetDescriptorSetLayoutBindingOffsetEXT.

If any `binding` in `layout` is `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`, the returned size includes space for the maximum `descriptorCount` descriptors as declared for that `binding`. To compute the required size of a descriptor set with a `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`:

  size = offset + descriptorSize × variableDescriptorCount

where offset is obtained by vkGetDescriptorSetLayoutBindingOffsetEXT and descriptorSize is the size of the relevant descriptor as obtained from VkPhysicalDeviceDescriptorBufferPropertiesEXT, and variableDescriptorCount is the equivalent of VkDescriptorSetVariableDescriptorCountAllocateInfo::`pDescriptorCounts`. For `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`, variableDescriptorCount is the size in bytes for the inline uniform block, and descriptorSize is 1.

If VkPhysicalDeviceDescriptorBufferPropertiesEXT::`combinedImageSamplerDescriptorSingleArray` is `VK_FALSE` and the variable descriptor type is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, variableDescriptorCount is always considered to be the upper bound.

Valid Usage

- VUID-vkGetDescriptorSetLayoutSizeEXT-None-08011
  The `descriptorBuffer` feature must be enabled

- VUID-vkGetDescriptorSetLayoutSizeEXT-layout-08012
  `layout` must have been created with the VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT flag set

Valid Usage (Implicit)

- VUID-vkGetDescriptorSetLayoutSizeEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetDescriptorSetLayoutSizeEXT-layout-parameter
  `layout` must be a valid VkDescriptorSetLayout handle

- VUID-vkGetDescriptorSetLayoutSizeEXT-pLayoutSizeInBytes-parameter
  `pLayoutSizeInBytes` must be a valid pointer to a VkDeviceSize value

- VUID-vkGetDescriptorSetLayoutSizeEXT-layout-parent
  `layout` must have been created, allocated, or retrieved from `device`

To get the offset of a binding within a descriptor set layout in memory, call:

    // Provided by VK_EXT_descriptor_buffer
    void vkGetDescriptorSetLayoutBindingOffsetEXT(
        VkDevice                                    device,
        VkDescriptorSetLayout                       layout,
        uint32_t                                    binding,
        VkDeviceSize*                               pOffset);

- `device` is the logical device that gets the offset.

- `layout` is the descriptor set layout being queried.

- `binding` is the binding number being queried.

- `pOffset` is a pointer to VkDeviceSize where the byte offset of the binding will be written.

Each binding in a descriptor set layout is assigned an offset in memory by the implementation. When a shader accesses a resource with that binding, it will access the bound descriptor buffer from that offset to look for its descriptor. This command provides an application with that offset, so that descriptors can be placed in the correct locations. The precise location accessed by a shader for a given descriptor is as follows:

  location = bufferAddress + setOffset + descriptorOffset
  (arrayElement * descriptorSize)

where bufferAddress and setOffset are the base address and offset for the identified descriptor set as specified by vkCmdBindDescriptorBuffersEXT and vkCmdSetDescriptorBufferOffsetsEXT, descriptorOffset is the offset for the binding returned by this command, arrayElement is the index into the array specified in the shader, and descriptorSize is the size of the relevant descriptor as obtained from VkPhysicalDeviceDescriptorBufferPropertiesEXT. Applications are responsible for placing valid descriptors at the expected location in order for a shader to access it. The overall offset added to bufferAddress to calculate location must be less than VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxSamplerDescriptorBufferRange` for samplers and VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxResourceDescriptorBufferRange` for resources.

If any `binding` in `layout` is `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`, that `binding` must have the largest offset of any `binding`.

A descriptor `binding` with type `VK_DESCRIPTOR_TYPE_MUTABLE_VALVE` can be used. Any potential types in VkMutableDescriptorTypeCreateInfoVALVE::`pDescriptorTypes` for `binding` share the same offset. If the size of the mutable descriptor is larger than the size of a concrete descriptor type being accessed, the padding area is ignored by the implementation.

Valid Usage

- VUID-vkGetDescriptorSetLayoutBindingOffsetEXT-None-08013
  The `descriptorBuffer` feature must be enabled

- VUID-vkGetDescriptorSetLayoutBindingOffsetEXT-layout-08014
  `layout` must have been created with the VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT flag set

Valid Usage (Implicit)

- VUID-vkGetDescriptorSetLayoutBindingOffsetEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetDescriptorSetLayoutBindingOffsetEXT-layout-parameter
  `layout` must be a valid VkDescriptorSetLayout handle

- VUID-vkGetDescriptorSetLayoutBindingOffsetEXT-pOffset-parameter
  `pOffset` must be a valid pointer to a VkDeviceSize value

- VUID-vkGetDescriptorSetLayoutBindingOffsetEXT-layout-parent
  `layout` must have been created, allocated, or retrieved from `device`

To get descriptor data to place in a buffer, call:

    // Provided by VK_EXT_descriptor_buffer
    void vkGetDescriptorEXT(
        VkDevice                                    device,
        const VkDescriptorGetInfoEXT*               pDescriptorInfo,
        size_t                                      dataSize,
        void*                                       pDescriptor);

- `device` is the logical device that gets the descriptor.

- `pDescriptorInfo` is a pointer to a VkDescriptorGetInfoEXT structure specifying the parameters of the descriptor to get.

- `dataSize` is the amount of the descriptor data to get in bytes.

- `pDescriptor` is a pointer to a user-allocated buffer where the descriptor will be written.

The size of the data for each descriptor type is determined by the value in VkPhysicalDeviceDescriptorBufferPropertiesEXT. This value also defines the stride in bytes for arrays of that descriptor type.

If the VkPhysicalDeviceDescriptorBufferPropertiesEXT::`combinedImageSamplerDescriptorSingleArray` property is `VK_FALSE` the implementation requires an array of `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` descriptors to be written into a descriptor buffer as an array of image descriptors, immediately followed by an array of sampler descriptors. Applications must write the first VkPhysicalDeviceDescriptorBufferPropertiesEXT::`sampledImageDescriptorSize` bytes of the data returned through `pDescriptor` to the first array, and the remaining VkPhysicalDeviceDescriptorBufferPropertiesEXT::`samplerDescriptorSize` bytes of the data to the second array. For variable-sized descriptor bindings of `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` descriptors, the two arrays each have a size equal to the upper bound `descriptorCount` of that binding.

A descriptor obtained by this command references the underlying VkImageView or VkSampler, and these objects must not be destroyed before the last time a descriptor is dynamically accessed. For descriptor types which consume an address instead of an object, the underlying VkBuffer is referenced instead.

Valid Usage

- VUID-vkGetDescriptorEXT-None-08015
  The `descriptorBuffer` feature must be enabled

- VUID-vkGetDescriptorEXT-dataSize-08125
  `dataSize` must equal the size of a descriptor of type VkDescriptorGetInfoEXT::`type` determined by the value in VkPhysicalDeviceDescriptorBufferPropertiesEXT, or VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT::`combinedImageSamplerDensityMapDescriptorSize` if `pDescriptorInfo` specifies a `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` whose VkSampler was created with `VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT` set

- VUID-vkGetDescriptorEXT-pDescriptor-08016
  `pDescriptor` must be a valid pointer to an array of at least `dataSize` bytes

Valid Usage (Implicit)

- VUID-vkGetDescriptorEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetDescriptorEXT-pDescriptorInfo-parameter
  `pDescriptorInfo` must be a valid pointer to a valid VkDescriptorGetInfoEXT structure

- VUID-vkGetDescriptorEXT-pDescriptor-parameter
  `pDescriptor` must be a valid pointer to an array of `dataSize` bytes

- VUID-vkGetDescriptorEXT-dataSize-arraylength
  `dataSize` must be greater than `0`

Information about the descriptor to get is passed in a `VkDescriptorGetInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkDescriptorGetInfoEXT {
        VkStructureType        sType;
        const void*            pNext;
        VkDescriptorType       type;
        VkDescriptorDataEXT    data;
    } VkDescriptorGetInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `type` is the type of descriptor to get.

- `data` is a structure containing the information needed to get the descriptor.

Valid Usage

- VUID-VkDescriptorGetInfoEXT-type-08018
  `type` must not be `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`, `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC` or `VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK`

- VUID-VkDescriptorGetInfoEXT-type-08019
  If `type` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, the `pCombinedImageSampler->sampler` member of `data` must be a VkSampler created on `device`

- VUID-VkDescriptorGetInfoEXT-type-08020
  If `type` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, the `pCombinedImageSampler->imageView` member of `data` must be a VkImageView created on `device`, or VK_NULL_HANDLE

- VUID-VkDescriptorGetInfoEXT-type-08021
  If `type` is `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, the `pInputAttachmentImage->imageView` member of `data` must be a VkImageView created on `device`

- VUID-VkDescriptorGetInfoEXT-type-08022
  If `type` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, and if `pSampledImage` is not `NULL`, the `pSampledImage->imageView` member of `data` must be a VkImageView created on `device`, or VK_NULL_HANDLE

- VUID-VkDescriptorGetInfoEXT-type-08023
  If `type` is `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and if `pStorageImage` is not `NULL`, the `pStorageImage->imageView` member of `data` must be a VkImageView created on `device`, or VK_NULL_HANDLE

- VUID-VkDescriptorGetInfoEXT-type-08024
  If `type` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`, `pUniformTexelBuffer` is not `NULL` and `pUniformTexelBuffer->address` is not zero, `pUniformTexelBuffer->address` must be an address within a VkBuffer created on `device`

- VUID-VkDescriptorGetInfoEXT-type-08025
  If `type` is `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, `pStorageTexelBuffer` is not `NULL` and `pStorageTexelBuffer->address` is not zero, `pStorageTexelBuffer->address` must be an address within a VkBuffer created on `device`

- VUID-VkDescriptorGetInfoEXT-type-08026
  If `type` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, `pUniformBuffer` is not `NULL` and `pUniformBuffer->address` is not zero, `pUniformBuffer->address` must be an address within a VkBuffer created on `device`

- VUID-VkDescriptorGetInfoEXT-type-08027
  If `type` is `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, `pStorageBuffer` is not `NULL` and `pStorageBuffer->address` is not zero, `pStorageBuffer->address` must be an address within a VkBuffer created on `device`

- VUID-VkDescriptorGetInfoEXT-type-08028
  If `type` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR` and `accelerationStructure` is not `0`, `accelerationStructure` must contain the address of a VkAccelerationStructureKHR created on `device`

- VUID-VkDescriptorGetInfoEXT-type-08029
  If `type` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV` and `accelerationStructure` is not `0`, `accelerationStructure` must contain the handle of a VkAccelerationStructureNV created on `device`, returned by vkGetAccelerationStructureHandleNV

Valid Usage (Implicit)

- VUID-VkDescriptorGetInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT`

- VUID-VkDescriptorGetInfoEXT-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkDescriptorGetInfoEXT-type-parameter
  `type` must be a valid VkDescriptorType value

- VUID-VkDescriptorGetInfoEXT-pSampler-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_SAMPLER`, the `pSampler` member of `data` must be a valid pointer to a valid VkSampler handle

- VUID-VkDescriptorGetInfoEXT-pCombinedImageSampler-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, the `pCombinedImageSampler` member of `data` must be a valid pointer to a valid VkDescriptorImageInfo structure

- VUID-VkDescriptorGetInfoEXT-pInputAttachmentImage-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT`, the `pInputAttachmentImage` member of `data` must be a valid pointer to a valid VkDescriptorImageInfo structure

- VUID-VkDescriptorGetInfoEXT-pSampledImage-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, and if `pSampledImage` is not `NULL`, the `pSampledImage` member of `data` must be a valid pointer to a valid VkDescriptorImageInfo structure

- VUID-VkDescriptorGetInfoEXT-pStorageImage-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and if `pStorageImage` is not `NULL`, the `pStorageImage` member of `data` must be a valid pointer to a valid VkDescriptorImageInfo structure

- VUID-VkDescriptorGetInfoEXT-pUniformTexelBuffer-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`, and if `pUniformTexelBuffer` is not `NULL`, the `pUniformTexelBuffer` member of `data` must be a valid pointer to a valid VkDescriptorAddressInfoEXT structure

- VUID-VkDescriptorGetInfoEXT-pStorageTexelBuffer-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, and if `pStorageTexelBuffer` is not `NULL`, the `pStorageTexelBuffer` member of `data` must be a valid pointer to a valid VkDescriptorAddressInfoEXT structure

- VUID-VkDescriptorGetInfoEXT-pUniformBuffer-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, and if `pUniformBuffer` is not `NULL`, the `pUniformBuffer` member of `data` must be a valid pointer to a valid VkDescriptorAddressInfoEXT structure

- VUID-VkDescriptorGetInfoEXT-pStorageBuffer-parameter
  If `type` is `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, and if `pStorageBuffer` is not `NULL`, the `pStorageBuffer` member of `data` must be a valid pointer to a valid VkDescriptorAddressInfoEXT structure

Data describing the descriptor is passed in a `VkDescriptorDataEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef union VkDescriptorDataEXT {
        const VkSampler*                     pSampler;
        const VkDescriptorImageInfo*         pCombinedImageSampler;
        const VkDescriptorImageInfo*         pInputAttachmentImage;
        const VkDescriptorImageInfo*         pSampledImage;
        const VkDescriptorImageInfo*         pStorageImage;
        const VkDescriptorAddressInfoEXT*    pUniformTexelBuffer;
        const VkDescriptorAddressInfoEXT*    pStorageTexelBuffer;
        const VkDescriptorAddressInfoEXT*    pUniformBuffer;
        const VkDescriptorAddressInfoEXT*    pStorageBuffer;
        VkDeviceAddress                      accelerationStructure;
    } VkDescriptorDataEXT;

- `pSampler` is a pointer to a VkSampler handle specifying the parameters of a `VK_DESCRIPTOR_TYPE_SAMPLER` descriptor.

- `pCombinedImageSampler` is a pointer to a VkDescriptorImageInfo structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER` descriptor.

- `pInputAttachmentImage` is a pointer to a VkDescriptorImageInfo structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT` descriptor.

- `pSampledImage` is a pointer to a VkDescriptorImageInfo structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE` descriptor.

- `pStorageImage` is a pointer to a VkDescriptorImageInfo structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE` descriptor.

- `pUniformTexelBuffer` is a pointer to a VkDescriptorAddressInfoEXT structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER` descriptor.

- `pStorageTexelBuffer` is a pointer to a VkDescriptorAddressInfoEXT structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` descriptor.

- `pUniformBuffer` is a pointer to a VkDescriptorAddressInfoEXT structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` descriptor.

- `pStorageBuffer` is a pointer to a VkDescriptorAddressInfoEXT structure specifying the parameters of a `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` descriptor.

- `accelerationStructure` is the address of a VkAccelerationStructureKHR specifying the parameters of a `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR` descriptor , or a VkAccelerationStructureNV handle specifying the parameters of a `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV` descriptor.

If the `nullDescriptor` feature is enabled, `pSampledImage`, `pStorageImage`, `pUniformTexelBuffer`, `pStorageTexelBuffer`, `pUniformBuffer`, and `pStorageBuffer` can each be `NULL`. Loads from a null descriptor return zero values and stores and atomics to a null descriptor are discarded.

If the `nullDescriptor` feature is enabled, `accelerationStructure` can be `0`. A null acceleration structure descriptor results in the miss shader being invoked.

Valid Usage

- VUID-VkDescriptorDataEXT-type-08030
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, and `pUniformBuffer->address` is the address of a non-sparse buffer, then that buffer must be bound completely and contiguously to a single `VkDeviceMemory` object

- VUID-VkDescriptorDataEXT-type-08031
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, and `pStorageBuffer->address` is the address of a non-sparse buffer, then that buffer must be bound completely and contiguously to a single `VkDeviceMemory` object

- VUID-VkDescriptorDataEXT-type-08032
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`, and `pUniformTexelBuffer->address` is the address of a non-sparse buffer, then that buffer must be bound completely and contiguously to a single `VkDeviceMemory` object

- VUID-VkDescriptorDataEXT-type-08033
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, and `pStorageTexelBuffer->address` is the address of a non-sparse buffer, then that buffer must be bound completely and contiguously to a single `VkDeviceMemory` object

- VUID-VkDescriptorDataEXT-type-08034
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER`, and the `nullDescriptor` feature is not enabled, `pCombinedImageSampler->imageView` must not be VK_NULL_HANDLE

- VUID-VkDescriptorDataEXT-type-08035
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE`, and the `nullDescriptor` feature is not enabled, `pSampledImage` must not be `NULL` and `pSampledImage->imageView` must not be VK_NULL_HANDLE

- VUID-VkDescriptorDataEXT-type-08036
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_STORAGE_IMAGE`, and the `nullDescriptor` feature is not enabled, `pStorageImage` must not be `NULL` and `pStorageImage->imageView` must not be VK_NULL_HANDLE

- VUID-VkDescriptorDataEXT-type-08037
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`, and the `nullDescriptor` feature is not enabled, `pUniformTexelBuffer` must not be `NULL`

- VUID-VkDescriptorDataEXT-type-08038
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`, and the `nullDescriptor` feature is not enabled, `pStorageTexelBuffer` must not be `NULL`

- VUID-VkDescriptorDataEXT-type-08039
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, and the `nullDescriptor` feature is not enabled, `pUniformBuffer` must not be `NULL`

- VUID-VkDescriptorDataEXT-type-08040
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, and the `nullDescriptor` feature is not enabled, `pStorageBuffer` must not be `NULL`

- VUID-VkDescriptorDataEXT-type-08041
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR`, and the `nullDescriptor` feature is not enabled, `accelerationStructure` must not be `0`

- VUID-VkDescriptorDataEXT-type-08042
  If VkDescriptorGetInfoEXT:`type` is `VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV`, and the `nullDescriptor` feature is not enabled, `accelerationStructure` must not be `0`

Data describing a `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER`, `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER`, `VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`, or `VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER` descriptor is passed in a `VkDescriptorAddressInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkDescriptorAddressInfoEXT {
        VkStructureType    sType;
        void*              pNext;
        VkDeviceAddress    address;
        VkDeviceSize       range;
        VkFormat           format;
    } VkDescriptorAddressInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `address` is either `0` or a device address at an offset in a buffer, where the base address can be queried from vkGetBufferDeviceAddress.

- `range` is the size in bytes of the buffer or buffer view used by the descriptor.

- `format` is the format of the data elements in the buffer view and is ignored for buffers.

Valid Usage

- VUID-VkDescriptorAddressInfoEXT-address-08043
  If the `nullDescriptor` feature is not enabled, `address` must not be zero

- VUID-VkDescriptorAddressInfoEXT-None-08044
  If `address` is not zero, `address` must be a valid device address at an offset within a VkBuffer

- VUID-VkDescriptorAddressInfoEXT-range-08045
  `range` must be less than or equal to the size of the buffer containing `address` minus the offset of `address` from the base address of the buffer

- VUID-VkDescriptorAddressInfoEXT-range-08046
  `range` must not be `VK_WHOLE_SIZE`

Valid Usage (Implicit)

- VUID-VkDescriptorAddressInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT`

- VUID-VkDescriptorAddressInfoEXT-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkDescriptorAddressInfoEXT-format-parameter
  `format` must be a valid VkFormat value

If the `nullDescriptor` feature is enabled, `address` can be zero. Loads from a null descriptor return zero values and stores and atomics to a null descriptor are discarded.

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.

| Note 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.

| Note 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.

#### 14.4.2. 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.

To bind descriptor buffers to a command buffer, call:

    // Provided by VK_EXT_descriptor_buffer
    void vkCmdBindDescriptorBuffersEXT(
        VkCommandBuffer                             commandBuffer,
        uint32_t                                    bufferCount,
        const VkDescriptorBufferBindingInfoEXT*     pBindingInfos);

- `commandBuffer` is the command buffer that the descriptor buffers will be bound to.

- `bufferCount` is the number of elements in the `pBindingInfos` array.

- `pBindingInfos` is a pointer to an array of VkDescriptorBufferBindingInfoEXT structures.

`vkCmdBindDescriptorBuffersEXT` causes any offsets previously set by vkCmdSetDescriptorBufferOffsetsEXT that use the bindings numbered [`0`.. `bufferCount`-1] to be no longer valid for subsequent bound pipeline commands. Any previously bound buffers at binding points greater than or equal to `bufferCount` are unbound.

Valid Usage

- VUID-vkCmdBindDescriptorBuffersEXT-None-08047
  The `descriptorBuffer` feature must be enabled

- VUID-vkCmdBindDescriptorBuffersEXT-maxSamplerDescriptorBufferBindings-08048
  There must be no more than VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxSamplerDescriptorBufferBindings` descriptor buffers containing sampler descriptor data bound

- VUID-vkCmdBindDescriptorBuffersEXT-maxResourceDescriptorBufferBindings-08049
  There must be no more than VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxResourceDescriptorBufferBindings` descriptor buffers containing resource descriptor data bound

- VUID-vkCmdBindDescriptorBuffersEXT-None-08050
  There must be no more than `1` descriptor buffer bound that was created with the `VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT` bit set

- VUID-vkCmdBindDescriptorBuffersEXT-bufferCount-08051
  `bufferCount` must be less than or equal to VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxDescriptorBufferBindings`

- VUID-vkCmdBindDescriptorBuffersEXT-pBindingInfos-08052
  For any element of `pBindingInfos`, if the buffer from which `address` was queried is non-sparse then it must be bound completely and contiguously to a single VkDeviceMemory object

- VUID-vkCmdBindDescriptorBuffersEXT-pBindingInfos-08053
  For any element of `pBindingInfos`, the buffer from which `address` was queried must have been created with the `VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT` bit set if it contains sampler descriptor data

- VUID-vkCmdBindDescriptorBuffersEXT-pBindingInfos-08054
  For any element of `pBindingInfos`, the buffer from which `address` was queried must have been created with the `VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT` bit set if it contains resource descriptor data

- VUID-vkCmdBindDescriptorBuffersEXT-pBindingInfos-08055
  For any element of `pBindingInfos`, `usage` must match the buffer from which `address` was queried

Valid Usage (Implicit)

- VUID-vkCmdBindDescriptorBuffersEXT-commandBuffer-parameter
  `commandBuffer` must be a valid VkCommandBuffer handle

- VUID-vkCmdBindDescriptorBuffersEXT-pBindingInfos-parameter
  `pBindingInfos` must be a valid pointer to an array of `bufferCount` valid VkDescriptorBufferBindingInfoEXT structures

- VUID-vkCmdBindDescriptorBuffersEXT-commandBuffer-recording
  `commandBuffer` must be in the recording state

- VUID-vkCmdBindDescriptorBuffersEXT-commandBuffer-cmdpool
  The `VkCommandPool` that `commandBuffer` was allocated from must support graphics, or compute operations

- VUID-vkCmdBindDescriptorBuffersEXT-videocoding
  This command must only be called outside of a video coding scope

- VUID-vkCmdBindDescriptorBuffersEXT-bufferCount-arraylength
  `bufferCount` must be greater than `0`

Host Synchronization

- Host access to `commandBuffer` must be externally synchronized

- Host access to the `VkCommandPool` that `commandBuffer` was allocated from must be externally synchronized

Command Properties

Command Buffer Levels | Render Pass Scope | Video Coding Scope | Supported Queue Types | Command Type
--- | --- | --- | --- | ---
Primary Secondary | Both | Outside | Graphics Compute | State

Data describing a descriptor buffer binding is passed in a `VkDescriptorBufferBindingInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkDescriptorBufferBindingInfoEXT {
        VkStructureType       sType;
        void*                 pNext;
        VkDeviceAddress       address;
        VkBufferUsageFlags    usage;
    } VkDescriptorBufferBindingInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `address` is the device address defining the descriptor buffer to be bound.

- `usage` is the VkBufferCreateInfo::`usage` for the buffer from which `address` was queried.

Valid Usage

- VUID-VkDescriptorBufferBindingInfoEXT-bufferlessPushDescriptors-08056
  If `VkPhysicalDeviceDescriptorBufferPropertiesEXT`::`bufferlessPushDescriptors` is `VK_FALSE`, and `usage` contains VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT, then the `pNext` chain must include a VkDescriptorBufferBindingPushDescriptorBufferHandleEXT structure

- VUID-VkDescriptorBufferBindingInfoEXT-address-08057
  `address` must be aligned to VkPhysicalDeviceDescriptorBufferPropertiesEXT::`descriptorBufferOffsetAlignment`

- VUID-VkDescriptorBufferBindingInfoEXT-usage-08122
  If `usage` includes `VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT`, `address` must be an address within a valid buffer that was created with `VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT`

- VUID-VkDescriptorBufferBindingInfoEXT-usage-08123
  If `usage` includes `VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT`, `address` must be an address within a valid buffer that was created with `VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT`

- VUID-VkDescriptorBufferBindingInfoEXT-usage-08124
  If `usage` includes `VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT`, `address` must be an address within a valid buffer that was created with `VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT`

Valid Usage (Implicit)

- VUID-VkDescriptorBufferBindingInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT`

- VUID-VkDescriptorBufferBindingInfoEXT-pNext-pNext
  `pNext` must be `NULL` or a pointer to a valid instance of VkDescriptorBufferBindingPushDescriptorBufferHandleEXT

- VUID-VkDescriptorBufferBindingInfoEXT-sType-unique
  The `sType` value of each struct in the `pNext` chain must be unique

- VUID-VkDescriptorBufferBindingInfoEXT-usage-parameter
  `usage` must be a valid combination of VkBufferUsageFlagBits values

- VUID-VkDescriptorBufferBindingInfoEXT-usage-requiredbitmask
  `usage` must not be `0`

When the `VkPhysicalDeviceDescriptorBufferPropertiesEXT`::`bufferlessPushDescriptors` property is `VK_FALSE`, the `VkBuffer` handle of the buffer for push descriptors is passed in a `VkDescriptorBufferBindingPushDescriptorBufferHandleEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkDescriptorBufferBindingPushDescriptorBufferHandleEXT {
        VkStructureType    sType;
        void*              pNext;
        VkBuffer           buffer;
    } VkDescriptorBufferBindingPushDescriptorBufferHandleEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `buffer` is the `VkBuffer` handle of the buffer for push descriptors.

Valid Usage

- VUID-VkDescriptorBufferBindingPushDescriptorBufferHandleEXT-bufferlessPushDescriptors-08059
  `VkPhysicalDeviceDescriptorBufferPropertiesEXT`::`bufferlessPushDescriptors` must be `VK_FALSE`

Valid Usage (Implicit)

- VUID-VkDescriptorBufferBindingPushDescriptorBufferHandleEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_PUSH_DESCRIPTOR_BUFFER_HANDLE_EXT`

- VUID-VkDescriptorBufferBindingPushDescriptorBufferHandleEXT-buffer-parameter
  `buffer` must be a valid VkBuffer handle

To set descriptor buffer offsets in a command buffer, call:

    // Provided by VK_EXT_descriptor_buffer
    void vkCmdSetDescriptorBufferOffsetsEXT(
        VkCommandBuffer                             commandBuffer,
        VkPipelineBindPoint                         pipelineBindPoint,
        VkPipelineLayout                            layout,
        uint32_t                                    firstSet,
        uint32_t                                    setCount,
        const uint32_t*                             pBufferIndices,
        const VkDeviceSize*                         pOffsets);

- `commandBuffer` is the command buffer in which the descriptor buffer offsets will be set.

- `pipelineBindPoint` is a VkPipelineBindPoint indicating the type of the pipeline that will use the descriptors.

- `layout` is a VkPipelineLayout object used to program the bindings.

- `firstSet` is the number of the first set to be bound.

- `setCount` is the number of elements in the `pBufferIndices` and `pOffsets` arrays.

- `pBufferIndices` is a pointer to an array of indices into the descriptor buffer binding points set by vkCmdBindDescriptorBuffersEXT.

- `pOffsets` is a pointer to an array of VkDeviceSize offsets to apply to the bound descriptor buffers.

`vkCmdSetDescriptorBufferOffsetsEXT` binds `setCount` pairs of descriptor buffers, specified by indices into the binding points bound using vkCmdBindDescriptorBuffersEXT, and buffer offsets to set numbers [`firstSet`..`firstSet`+`descriptorSetCount`-1] for subsequent bound pipeline commands set by `pipelineBindPoint`. Set [`firstSet` + i] is bound to the descriptor buffer at binding `pBufferIndices`[i] at an offset of `pOffsets`[i]. Any bindings that were previously applied via these sets, or calls to vkCmdBindDescriptorSets, are no longer valid. Other sets will also be invalidated upon calling this command if `layout` differs from the pipeline layout used to bind those other sets, as described in Pipeline Layout Compatibility.

After binding descriptors, applications can modify descriptor memory either by performing writes on the host or with device commands. When descriptor memory is updated with device commands, visibility for the shader stage accessing a descriptor is ensured with the `VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT` access flag. Implementations must not access resources referenced by these descriptors unless they are dynamically accessed by shaders. Descriptors bound with this call can be undefined if they are not dynamically accessed by shaders.

Implementations may read descriptor data for any statically accessed descriptor if the `binding` in `layout` is not declared with the `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT` flag. If the `binding` in `layout` is declared with `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT`, implementations must not read descriptor data that is not dynamically accessed.

Applications must ensure that any descriptor which the implementation may read must be in-bounds of the underlying descriptor buffer binding.

| Note Applications can freely decide how large a variable descriptor buffer binding is, so it may not be safe to read such descriptor payloads statically. The intention of these rules is to allow implementations to speculatively prefetch descriptor payloads where feasible.

Dynamically accessing a resource through descriptor data from an unbound region of a sparse partially-resident buffer will result in invalid descriptor data being read, and therefore undefined behavior.

| Note For descriptors written by the host, visibility is implied through the automatic visibility operation on queue submit, and there is no need to consider `VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT`. Explicit synchronization for descriptors is only required when descriptors are updated on the device.

| Note The requirements above imply that all descriptor bindings have been defined with the equivalent of `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT`, `VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT` and `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT`, but enabling those features is not required to get this behavior.

Valid Usage

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-None-08060
  The `descriptorBuffer` feature must be enabled

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pOffsets-08061
  The offsets in `pOffsets` must be aligned to VkPhysicalDeviceDescriptorBufferPropertiesEXT::`descriptorBufferOffsetAlignment`

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pOffsets-08063
  The offsets in `pOffsets` must be small enough such that any descriptor binding referenced by `layout` without the `VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT` flag computes a valid address inside the underlying VkBuffer

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pOffsets-08126
  The offsets in `pOffsets` must be small enough such that any location accessed by a shader as a sampler descriptor must be within VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxSamplerDescriptorBufferRange` of the sampler descriptor buffer binding

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pOffsets-08127
  The offsets in `pOffsets` must be small enough such that any location accessed by a shader as a resource descriptor must be within VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxResourceDescriptorBufferRange` of the resource descriptor buffer binding

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pBufferIndices-08064
  Each element of `pBufferIndices` must be less than VkPhysicalDeviceDescriptorBufferPropertiesEXT::`maxDescriptorBufferBindings`

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pBufferIndices-08065
  Each element of `pBufferIndices` must reference a valid descriptor buffer binding set by a previous call to vkCmdBindDescriptorBuffersEXT in `commandBuffer`

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-firstSet-08066
  The sum of `firstSet` and `setCount` must be less than or equal to VkPipelineLayoutCreateInfo::`setLayoutCount` provided when `layout` was created

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pipelineBindPoint-08067
  `pipelineBindPoint` must be supported by the `commandBuffer`’s parent `VkCommandPool`’s queue family

Valid Usage (Implicit)

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-commandBuffer-parameter
  `commandBuffer` must be a valid VkCommandBuffer handle

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pipelineBindPoint-parameter
  `pipelineBindPoint` must be a valid VkPipelineBindPoint value

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-layout-parameter
  `layout` must be a valid VkPipelineLayout handle

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pBufferIndices-parameter
  `pBufferIndices` must be a valid pointer to an array of `setCount` `uint32_t` values

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-pOffsets-parameter
  `pOffsets` must be a valid pointer to an array of `setCount` VkDeviceSize values

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-commandBuffer-recording
  `commandBuffer` must be in the recording state

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-commandBuffer-cmdpool
  The `VkCommandPool` that `commandBuffer` was allocated from must support graphics, or compute operations

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-videocoding
  This command must only be called outside of a video coding scope

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-setCount-arraylength
  `setCount` must be greater than `0`

- VUID-vkCmdSetDescriptorBufferOffsetsEXT-commonparent
  Both of `commandBuffer`, and `layout` must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization

- Host access to `commandBuffer` must be externally synchronized

- Host access to the `VkCommandPool` that `commandBuffer` was allocated from must be externally synchronized

Command Properties

Command Buffer Levels | Render Pass Scope | Video Coding Scope | Supported Queue Types | Command Type
--- | --- | --- | --- | ---
Primary Secondary | Both | Outside | Graphics Compute | State

To bind an embedded immutable sampler set to a command buffer, call:

    // Provided by VK_EXT_descriptor_buffer
    void vkCmdBindDescriptorBufferEmbeddedSamplersEXT(
        VkCommandBuffer                             commandBuffer,
        VkPipelineBindPoint                         pipelineBindPoint,
        VkPipelineLayout                            layout,
        uint32_t                                    set);

- `commandBuffer` is the command buffer that the embedded immutable samplers will be bound to.

- `pipelineBindPoint` is a VkPipelineBindPoint indicating the type of the pipeline that will use the embedded immutable samplers.

- `layout` is a VkPipelineLayout object used to program the bindings.

- `set` is the number of the set to be bound.

`vkCmdBindDescriptorBufferEmbeddedSamplersEXT` binds the embedded immutable samplers in `set` of `layout` to `set` for the command buffer for subsequent bound pipeline commands set by `pipelineBindPoint`. Any previous binding to this set by vkCmdSetDescriptorBufferOffsetsEXT or this command is overwritten. Any sets that were last bound by a call to vkCmdBindDescriptorSets are invalidated upon calling this command. Other sets will also be invalidated upon calling this command if `layout` differs from the pipeline layout used to bind those other sets, as described in Pipeline Layout Compatibility.

Valid Usage

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-None-08068
  The `descriptorBuffer` feature must be enabled

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-pipelineBindPoint-08069
  `pipelineBindPoint` must be supported by the `commandBuffer`’s parent `VkCommandPool`’s queue family

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-set-08070
  The VkDescriptorSetLayout at index `set` when `layout` was created must have been created with the `VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT` bit set

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-set-08071
  `set` must be less than or equal to VkPipelineLayoutCreateInfo::`setLayoutCount` provided when `layout` was created

Valid Usage (Implicit)

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-commandBuffer-parameter
  `commandBuffer` must be a valid VkCommandBuffer handle

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-pipelineBindPoint-parameter
  `pipelineBindPoint` must be a valid VkPipelineBindPoint value

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-layout-parameter
  `layout` must be a valid VkPipelineLayout handle

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-commandBuffer-recording
  `commandBuffer` must be in the recording state

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-commandBuffer-cmdpool
  The `VkCommandPool` that `commandBuffer` was allocated from must support graphics, or compute operations

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-videocoding
  This command must only be called outside of a video coding scope

- VUID-vkCmdBindDescriptorBufferEmbeddedSamplersEXT-commonparent
  Both of `commandBuffer`, and `layout` must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization

- Host access to `commandBuffer` must be externally synchronized

- Host access to the `VkCommandPool` that `commandBuffer` was allocated from must be externally synchronized

Command Properties

Command Buffer Levels | Render Pass Scope | Video Coding Scope | Supported Queue Types | Command Type
--- | --- | --- | --- | ---
Primary Secondary | Both | Outside | Graphics Compute | State

#### 14.4.3. 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.

#### 14.4.4. 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.

#### 14.4.5. 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.

To get the opaque descriptor data for a buffer, call:

    // Provided by VK_EXT_descriptor_buffer
    VkResult vkGetBufferOpaqueCaptureDescriptorDataEXT(
        VkDevice                                    device,
        const VkBufferCaptureDescriptorDataInfoEXT* pInfo,
        void*                                       pData);

- `device` is the logical device that gets the data.

- `pInfo` is a pointer to a VkBufferCaptureDescriptorDataInfoEXT structure specifying the buffer.

- `pData` is a pointer to a user-allocated buffer where the data will be written.

Valid Usage

- VUID-vkGetBufferOpaqueCaptureDescriptorDataEXT-None-08072
  The `descriptorBufferCaptureReplay` feature must be enabled

- VUID-vkGetBufferOpaqueCaptureDescriptorDataEXT-pData-08073
  `pData` must point to a buffer that is at least VkPhysicalDeviceDescriptorBufferPropertiesEXT::`bufferCaptureReplayDescriptorDataSize` bytes in size

- VUID-vkGetBufferOpaqueCaptureDescriptorDataEXT-device-08074
  If `device` was created with multiple physical devices, then the `bufferDeviceAddressMultiDevice` feature must be enabled

Valid Usage (Implicit)

- VUID-vkGetBufferOpaqueCaptureDescriptorDataEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetBufferOpaqueCaptureDescriptorDataEXT-pInfo-parameter
  `pInfo` must be a valid pointer to a valid VkBufferCaptureDescriptorDataInfoEXT structure

- VUID-vkGetBufferOpaqueCaptureDescriptorDataEXT-pData-parameter
  `pData` must be a pointer value

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

Information about the buffer to get descriptor buffer capture data for is passed in a `VkBufferCaptureDescriptorDataInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkBufferCaptureDescriptorDataInfoEXT {
        VkStructureType    sType;
        const void*        pNext;
        VkBuffer           buffer;
    } VkBufferCaptureDescriptorDataInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `buffer` is the `VkBuffer` handle of the buffer to get opaque capture data for.

Valid Usage

- VUID-VkBufferCaptureDescriptorDataInfoEXT-buffer-08075
  `buffer` must have been created with `VK_BUFFER_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT` set in VkBufferCreateInfo::`flags`

Valid Usage (Implicit)

- VUID-VkBufferCaptureDescriptorDataInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_BUFFER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT`

- VUID-VkBufferCaptureDescriptorDataInfoEXT-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkBufferCaptureDescriptorDataInfoEXT-buffer-parameter
  `buffer` must be a valid VkBuffer handle

To get the opaque capture descriptor data for an image, call:

    // Provided by VK_EXT_descriptor_buffer
    VkResult vkGetImageOpaqueCaptureDescriptorDataEXT(
        VkDevice                                    device,
        const VkImageCaptureDescriptorDataInfoEXT*  pInfo,
        void*                                       pData);

- `device` is the logical device that gets the data.

- `pInfo` is a pointer to a VkImageCaptureDescriptorDataInfoEXT structure specifying the image.

- `pData` is a pointer to a user-allocated buffer where the data will be written.

Valid Usage

- VUID-vkGetImageOpaqueCaptureDescriptorDataEXT-None-08076
  The `descriptorBufferCaptureReplay` feature must be enabled

- VUID-vkGetImageOpaqueCaptureDescriptorDataEXT-pData-08077
  `pData` must point to a buffer that is at least VkPhysicalDeviceDescriptorBufferPropertiesEXT::`imageCaptureReplayDescriptorDataSize` bytes in size

- VUID-vkGetImageOpaqueCaptureDescriptorDataEXT-device-08078
  If `device` was created with multiple physical devices, then the `bufferDeviceAddressMultiDevice` feature must be enabled

Valid Usage (Implicit)

- VUID-vkGetImageOpaqueCaptureDescriptorDataEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetImageOpaqueCaptureDescriptorDataEXT-pInfo-parameter
  `pInfo` must be a valid pointer to a valid VkImageCaptureDescriptorDataInfoEXT structure

- VUID-vkGetImageOpaqueCaptureDescriptorDataEXT-pData-parameter
  `pData` must be a pointer value

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

Information about the image to get descriptor buffer capture data for is passed in a `VkImageCaptureDescriptorDataInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkImageCaptureDescriptorDataInfoEXT {
        VkStructureType    sType;
        const void*        pNext;
        VkImage            image;
    } VkImageCaptureDescriptorDataInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `image` is the `VkImage` handle of the image to get opaque capture data for.

Valid Usage

- VUID-VkImageCaptureDescriptorDataInfoEXT-image-08079
  `image` must have been created with `VK_IMAGE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT` set in VkImageCreateInfo::`flags`

Valid Usage (Implicit)

- VUID-VkImageCaptureDescriptorDataInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_IMAGE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT`

- VUID-VkImageCaptureDescriptorDataInfoEXT-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkImageCaptureDescriptorDataInfoEXT-image-parameter
  `image` must be a valid VkImage handle

To get the opaque capture descriptor data for an image view, call:

    // Provided by VK_EXT_descriptor_buffer
    VkResult vkGetImageViewOpaqueCaptureDescriptorDataEXT(
        VkDevice                                    device,
        const VkImageViewCaptureDescriptorDataInfoEXT* pInfo,
        void*                                       pData);

- `device` is the logical device that gets the data.

- `pInfo` is a pointer to a VkImageViewCaptureDescriptorDataInfoEXT structure specifying the image view.

- `pData` is a pointer to a user-allocated buffer where the data will be written.

Valid Usage

- VUID-vkGetImageViewOpaqueCaptureDescriptorDataEXT-None-08080
  The `descriptorBufferCaptureReplay` feature must be enabled

- VUID-vkGetImageViewOpaqueCaptureDescriptorDataEXT-pData-08081
  `pData` must point to a buffer that is at least VkPhysicalDeviceDescriptorBufferPropertiesEXT::`imageViewCaptureReplayDescriptorDataSize` bytes in size

- VUID-vkGetImageViewOpaqueCaptureDescriptorDataEXT-device-08082
  If `device` was created with multiple physical devices, then the `bufferDeviceAddressMultiDevice` feature must be enabled

Valid Usage (Implicit)

- VUID-vkGetImageViewOpaqueCaptureDescriptorDataEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetImageViewOpaqueCaptureDescriptorDataEXT-pInfo-parameter
  `pInfo` must be a valid pointer to a valid VkImageViewCaptureDescriptorDataInfoEXT structure

- VUID-vkGetImageViewOpaqueCaptureDescriptorDataEXT-pData-parameter
  `pData` must be a pointer value

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

Information about the image view to get descriptor buffer capture data for is passed in a `VkImageViewCaptureDescriptorDataInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkImageViewCaptureDescriptorDataInfoEXT {
        VkStructureType    sType;
        const void*        pNext;
        VkImageView        imageView;
    } VkImageViewCaptureDescriptorDataInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `imageView` is the `VkImageView` handle of the image view to get opaque capture data for.

Valid Usage

- VUID-VkImageViewCaptureDescriptorDataInfoEXT-imageView-08083
  `imageView` must have been created with `VK_IMAGE_VIEW_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT` set in VkImageViewCreateInfo::`flags`

Valid Usage (Implicit)

- VUID-VkImageViewCaptureDescriptorDataInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_IMAGE_VIEW_CAPTURE_DESCRIPTOR_DATA_INFO_EXT`

- VUID-VkImageViewCaptureDescriptorDataInfoEXT-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkImageViewCaptureDescriptorDataInfoEXT-imageView-parameter
  `imageView` must be a valid VkImageView handle

To get the opaque capture descriptor data for a sampler, call:

    // Provided by VK_EXT_descriptor_buffer
    VkResult vkGetSamplerOpaqueCaptureDescriptorDataEXT(
        VkDevice                                    device,
        const VkSamplerCaptureDescriptorDataInfoEXT* pInfo,
        void*                                       pData);

- `device` is the logical device that gets the data.

- `pInfo` is a pointer to a VkSamplerCaptureDescriptorDataInfoEXT structure specifying the sampler.

- `pData` is a pointer to a user-allocated buffer where the data will be written.

Valid Usage

- VUID-vkGetSamplerOpaqueCaptureDescriptorDataEXT-None-08084
  The `descriptorBufferCaptureReplay` feature must be enabled

- VUID-vkGetSamplerOpaqueCaptureDescriptorDataEXT-pData-08085
  `pData` must point to a buffer that is at least VkPhysicalDeviceDescriptorBufferPropertiesEXT::`samplerCaptureReplayDescriptorDataSize` bytes in size

- VUID-vkGetSamplerOpaqueCaptureDescriptorDataEXT-device-08086
  If `device` was created with multiple physical devices, then the `bufferDeviceAddressMultiDevice` feature must be enabled

Valid Usage (Implicit)

- VUID-vkGetSamplerOpaqueCaptureDescriptorDataEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetSamplerOpaqueCaptureDescriptorDataEXT-pInfo-parameter
  `pInfo` must be a valid pointer to a valid VkSamplerCaptureDescriptorDataInfoEXT structure

- VUID-vkGetSamplerOpaqueCaptureDescriptorDataEXT-pData-parameter
  `pData` must be a pointer value

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

Information about the sampler to get descriptor buffer capture data for is passed in a `VkSamplerCaptureDescriptorDataInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkSamplerCaptureDescriptorDataInfoEXT {
        VkStructureType    sType;
        const void*        pNext;
        VkSampler          sampler;
    } VkSamplerCaptureDescriptorDataInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `sampler` is the `VkSampler` handle of the sampler to get opaque capture data for.

Valid Usage

- VUID-VkSamplerCaptureDescriptorDataInfoEXT-sampler-08087
  `sampler` must have been created with `VK_SAMPLER_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT` set in VkSamplerCreateInfo::`flags`

Valid Usage (Implicit)

- VUID-VkSamplerCaptureDescriptorDataInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_SAMPLER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT`

- VUID-VkSamplerCaptureDescriptorDataInfoEXT-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkSamplerCaptureDescriptorDataInfoEXT-sampler-parameter
  `sampler` must be a valid VkSampler handle

To get the opaque capture descriptor data for an acceleration structure, call:

    // Provided by VK_EXT_descriptor_buffer with VK_KHR_acceleration_structure or VK_NV_ray_tracing
    VkResult vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT(
        VkDevice                                    device,
        const VkAccelerationStructureCaptureDescriptorDataInfoEXT* pInfo,
        void*                                       pData);

- `device` is the logical device that gets the data.

- `pInfo` is a pointer to a VkAccelerationStructureCaptureDescriptorDataInfoEXT structure specifying the acceleration structure.

- `pData` is a pointer to a user-allocated buffer where the data will be written.

Valid Usage

- VUID-vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT-None-08088
  The `descriptorBufferCaptureReplay` feature must be enabled

- VUID-vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT-pData-08089
  `pData` must point to a buffer that is at least VkPhysicalDeviceDescriptorBufferPropertiesEXT::`accelerationStructureCaptureReplayDescriptorDataSize` bytes in size

- VUID-vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT-device-08090
  If `device` was created with multiple physical devices, then the `bufferDeviceAddressMultiDevice` feature must be enabled

Valid Usage (Implicit)

- VUID-vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT-device-parameter
  `device` must be a valid VkDevice handle

- VUID-vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT-pInfo-parameter
  `pInfo` must be a valid pointer to a valid VkAccelerationStructureCaptureDescriptorDataInfoEXT structure

- VUID-vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT-pData-parameter
  `pData` must be a pointer value

Return Codes

Success

  - `VK_SUCCESS`

Failure

  - `VK_ERROR_OUT_OF_HOST_MEMORY`

  - `VK_ERROR_OUT_OF_DEVICE_MEMORY`

Information about the acceleration structure to get descriptor buffer capture data for is passed in a `VkAccelerationStructureCaptureDescriptorDataInfoEXT` structure:

    // Provided by VK_EXT_descriptor_buffer with VK_KHR_acceleration_structure or VK_NV_ray_tracing
    typedef struct VkAccelerationStructureCaptureDescriptorDataInfoEXT {
        VkStructureType               sType;
        const void*                   pNext;
        VkAccelerationStructureKHR    accelerationStructure;
        VkAccelerationStructureNV     accelerationStructureNV;
    } VkAccelerationStructureCaptureDescriptorDataInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `accelerationStructure` is the `VkAccelerationStructureKHR` handle of the acceleration structure to get opaque capture data for.

- `accelerationStructureNV` is the `VkAccelerationStructureNV` handle of the acceleration structure to get opaque capture data for.

Valid Usage

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-accelerationStructure-08091
  If `accelerationStructure` is not VK_NULL_HANDLE then `accelerationStructure` must have been created with `VK_ACCELERATION_STRUCTURE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT` set in VkAccelerationStructureCreateInfoKHR::`createFlags`

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-accelerationStructureNV-08092
  If `accelerationStructureNV` is not VK_NULL_HANDLE then `accelerationStructureNV` must have been created with `VK_ACCELERATION_STRUCTURE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT` set in VkAccelerationStructureCreateInfoNV::info::`flags`

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-accelerationStructure-08093
  If `accelerationStructure` is not VK_NULL_HANDLE then `accelerationStructureNV` must be VK_NULL_HANDLE

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-accelerationStructureNV-08094
  If `accelerationStructureNV` is not VK_NULL_HANDLE then `accelerationStructure` must be VK_NULL_HANDLE

Valid Usage (Implicit)

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT`

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-pNext-pNext
  `pNext` must be `NULL`

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-accelerationStructure-parameter
  If `accelerationStructure` is not VK_NULL_HANDLE, `accelerationStructure` must be a valid VkAccelerationStructureKHR handle

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-accelerationStructureNV-parameter
  If `accelerationStructureNV` is not VK_NULL_HANDLE, `accelerationStructureNV` must be a valid VkAccelerationStructureNV handle

- VUID-VkAccelerationStructureCaptureDescriptorDataInfoEXT-commonparent
  Both of `accelerationStructure`, and `accelerationStructureNV` that are valid handles of non-ignored parameters must have been created, allocated, or retrieved from the same VkDevice

The `VkOpaqueCaptureDescriptorDataCreateInfoEXT` structure is defined as:

    // Provided by VK_EXT_descriptor_buffer
    typedef struct VkOpaqueCaptureDescriptorDataCreateInfoEXT {
        VkStructureType    sType;
        const void*        pNext;
        const void*        opaqueCaptureDescriptorData;
    } VkOpaqueCaptureDescriptorDataCreateInfoEXT;

- `sType` is the type of this structure.

- `pNext` is `NULL` or a pointer to a structure extending this structure.

- `opaqueCaptureDescriptorData` is a pointer to a user-allocated buffer containing opaque capture data retrieved using vkGetBufferOpaqueCaptureDescriptorDataEXT, vkGetImageOpaqueCaptureDescriptorDataEXT, vkGetImageViewOpaqueCaptureDescriptorDataEXT, vkGetSamplerOpaqueCaptureDescriptorDataEXT, or vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT.

During replay, opaque descriptor capture data can be specified by adding a `VkOpaqueCaptureDescriptorDataCreateInfoEXT` structure to the relevant `pNext` chain of a VkBufferCreateInfo, VkImageCreateInfo, VkImageViewCreateInfo, VkSamplerCreateInfo, VkAccelerationStructureCreateInfoNV or VkAccelerationStructureCreateInfoKHR structure.

Valid Usage (Implicit)

- VUID-VkOpaqueCaptureDescriptorDataCreateInfoEXT-sType-sType
  `sType` must be `VK_STRUCTURE_TYPE_OPAQUE_CAPTURE_DESCRIPTOR_DATA_CREATE_INFO_EXT`

- VUID-VkOpaqueCaptureDescriptorDataCreateInfoEXT-opaqueCaptureDescriptorData-parameter
  `opaqueCaptureDescriptorData` must be a pointer value