Descriptor Heaps

When the descriptorHeap feature is enabled, applications can use descriptor heaps to specify the descriptors that they will be accessing from shaders. Descriptor heaps are not objects, rather they are state that is bound to a command buffer indicating the device address of descriptors that can be accessed from a shader. There are two heaps available to the application - the sampler heap and the resource heap. The sampler heap contains sampler descriptors, the resource heap contains image, acceleration structure, tensor, and buffer descriptors.

Writing Descriptors

Descriptors can be obtained for the different heaps with commands that write sampler descriptors to host memory, with the application responsible for transferring those descriptors into device memory for access via heaps.

To write sampler descriptors to memory, call:

// Provided by VK_EXT_descriptor_heap
VkResult vkWriteSamplerDescriptorsEXT(
    VkDevice                                    device,
    uint32_t                                    samplerCount,
    const VkSamplerCreateInfo*                  pSamplers,
    const VkHostAddressRangeEXT*                pDescriptors);
  • device is the logical device that the descriptors are for.

  • samplerCount is the number of elements in pSamplers and pDescriptors.

  • pSamplers is a pointer to an array of VkSamplerCreateInfo structures defining properties of the sampler descriptors that will be written.

  • pDescriptors is a pointer to an array of VkHostAddressRangeEXT structures defining the host address ranges that will be written to for each descriptor.

Each descriptor will be written to pDescriptors[i]→address where i is the index of its create info in pSamplers.

Descriptors written using a fully identical VkSamplerCreateInfo structure on the same VkDevice will always return the same bit pattern. If the descriptorHeapCaptureReplay feature is enabled, descriptors written using a fully identical VkSamplerCreateInfo structure on a VkDevice created from the same VkPhysicalDevice with identical parameters will always return the same bit pattern.

YCBCR samplers must be embedded in a shader by using VkShaderDescriptorSetAndBindingMappingInfoEXT, they cannot be specified here.

Valid Usage
Valid Usage (Implicit)
  • VUID-vkWriteSamplerDescriptorsEXT-device-parameter
    device must be a valid VkDevice handle

  • VUID-vkWriteSamplerDescriptorsEXT-pSamplers-parameter
    pSamplers must be a valid pointer to an array of samplerCount valid VkSamplerCreateInfo structures

  • VUID-vkWriteSamplerDescriptorsEXT-pDescriptors-parameter
    pDescriptors must be a valid pointer to an array of samplerCount valid VkHostAddressRangeEXT structures

  • VUID-vkWriteSamplerDescriptorsEXT-samplerCount-arraylength
    samplerCount must be greater than 0

To write resource descriptors to memory, call:

// Provided by VK_EXT_descriptor_heap
VkResult vkWriteResourceDescriptorsEXT(
    VkDevice                                    device,
    uint32_t                                    resourceCount,
    const VkResourceDescriptorInfoEXT*          pResources,
    const VkHostAddressRangeEXT*                pDescriptors);
  • device is the logical device that the descriptors are for.

  • resourceCount is the number of elements in pResources and pDescriptors.

  • pResources is a pointer to an array of VkResourceDescriptorInfoEXT structures defining properties of the resource descriptors that will be written.

  • pDescriptors is a pointer to an array of VkHostAddressRangeEXT structures defining the host address ranges that will be written to for each descriptor.

Each descriptor will be written to pDescriptors[i]→address where i is the index of its create info in pResources.

If any image descriptor written by this command includes a VkSamplerYcbcrConversion, multiple descriptors will be written adjacent to each other for that descriptor, equal to VkSamplerYcbcrConversionImageFormatProperties::combinedImageSamplerDescriptorCount for the image.

If any image descriptor written by this command is for an image created with flags containing VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT, multiple descriptors will be written adjacent to each other for that descriptor, equal to VkSubsampledImageFormatPropertiesEXT::subsampledImageDescriptorCount for the image.

Descriptors using the same type and written using a fully identical VkTexelBufferDescriptorInfoEXT or VkDeviceAddressRangeEXT structure on the same VkDevice will always return the same bit pattern. If the descriptorHeapCaptureReplay feature is enabled, this applies to any VkDevice created with identical parameters from the same VkPhysicalDevice.

Recreating the same buffer descriptor during replay of a prior capture requires that the device address is the same, which requires additional data to be captured and provided during replay when creating a buffer and allocating memory for it.

Image descriptors using the same type and written using a fully identical VkImageDescriptorInfoEXT other than VkImageDescriptorInfoEXT::pView->image, where image was successfully created with VK_IMAGE_CREATE_DESCRIPTOR_HEAP_CAPTURE_REPLAY_BIT_EXT and a VkOpaqueCaptureDataCreateInfoEXT with data captured via vkGetImageOpaqueCaptureDataEXT from an image used previously, will write a descriptor with the same bit pattern if possible; if the same bit pattern cannot be generated, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS will be returned instead.

Tensor descriptors using the same type and written using a fully identical VkTensorViewCreateInfoARM other than VkTensorViewCreateInfoARM::tensor, where tensor was successfully created with VkOpaqueCaptureDataCreateInfoEXT with VK_TENSOR_CREATE_DESCRIPTOR_HEAP_CAPTURE_REPLAY_BIT_ARM and a VkOpaqueCaptureDataCreateInfoEXT with data captured via vkGetTensorOpaqueCaptureDataARM from a tensor used previously, will write a descriptor with the same bit pattern if possible; if the same bit pattern cannot be generated, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS will be returned instead.

Image creation is sufficiently complex that it may not be possible to recreate all possible descriptors from an image during replay, even if the image itself was successfully recreated. The conditions for this happening will be largely the same as those which could cause allocating a buffer with the same device address during replay to fail. Replay tools are advised to recreate captured descriptors for an image immediately after recreating the image itself wherever possible. The same is true for tensors.

Valid Usage
Valid Usage (Implicit)
  • VUID-vkWriteResourceDescriptorsEXT-device-parameter
    device must be a valid VkDevice handle

  • VUID-vkWriteResourceDescriptorsEXT-pResources-parameter
    pResources must be a valid pointer to an array of resourceCount valid VkResourceDescriptorInfoEXT structures

  • VUID-vkWriteResourceDescriptorsEXT-pDescriptors-parameter
    pDescriptors must be a valid pointer to an array of resourceCount valid VkHostAddressRangeEXT structures

  • VUID-vkWriteResourceDescriptorsEXT-resourceCount-arraylength
    resourceCount must be greater than 0

VkResourceDescriptorInfoEXT is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkResourceDescriptorInfoEXT {
    VkStructureType                sType;
    const void*                    pNext;
    VkDescriptorType               type;
    VkResourceDescriptorDataEXT    data;
} VkResourceDescriptorInfoEXT;
  • sType is a VkStructureType value identifying 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 VkResourceDescriptorDataEXT union defining the properties of a resource descriptor according to type

If type is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, data->pTexelBuffer is used to construct the descriptor.

If type is VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, data->pAddressRange is used to construct the descriptor. For acceleration structures, the size of the range is not used by the descriptor, and can be set to 0. If a non-zero size is provided though, it must be a valid range.

Applications may wish to provide a valid range as a way to check their own assumptions about the range they are binding; but it has no bearing on anything except validation. Implementations cannot make any assumptions based on the size of the provided range.

If type is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, data->pImage is used to construct the descriptor. If type is VK_DESCRIPTOR_TYPE_TENSOR_ARM, data->pTensorARM is used to construct the descriptor.

If the nullDescriptor feature is enabled, the corresponding element of data may be NULL to generate a null descriptor.

Applications can give resource descriptors a debug name in a similar way to naming an object, via the VkDebugUtilsObjectNameInfoEXT structure. However, as there is no actual object, this structure must be passed via the pNext chain of this structure, with a objectType of VK_OBJECT_TYPE_UNKNOWN and a objectHandle of VK_NULL_HANDLE. The name is attached to the unique set of descriptor bits written by the implementation, and writing the same bits again with new debug info may rename the original descriptor.

Implementations are not prevented from returning the same bits for different descriptors. This can result in multiple different resources mapping to the same name. A common case for this might be something like a uniform buffer and storage buffer with the same device address range.

If a descriptor becomes invalid due to the underlying resource becoming invalid, implementations may remove the name association.

Valid Usage
Valid Usage (Implicit)

The VkResourceDescriptorDataEXT union is defined as:

// Provided by VK_EXT_descriptor_heap
typedef union VkResourceDescriptorDataEXT {
    const VkImageDescriptorInfoEXT*          pImage;
    const VkTexelBufferDescriptorInfoEXT*    pTexelBuffer;
    const VkDeviceAddressRangeEXT*           pAddressRange;
    const VkTensorViewCreateInfoARM*         pTensorARM;
} VkResourceDescriptorDataEXT;

VkTexelBufferDescriptorInfoEXT is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkTexelBufferDescriptorInfoEXT {
    VkStructureType            sType;
    const void*                pNext;
    VkFormat                   format;
    VkDeviceAddressRangeEXT    addressRange;
} VkTexelBufferDescriptorInfoEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • format is the VkFormat of the descriptor.

  • addressRange is a VkDeviceAddressRangeEXT defining the range of data backing the descriptor.

Valid Usage
Valid Usage (Implicit)

VkImageDescriptorInfoEXT is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkImageDescriptorInfoEXT {
    VkStructureType                 sType;
    const void*                     pNext;
    const VkImageViewCreateInfo*    pView;
    VkImageLayout                   layout;
} VkImageDescriptorInfoEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • pView is an VkImageViewCreateInfo describing the descriptor.

  • layout is the VkImageLayout that the image view will be in when accessed as a descriptor.

Valid Usage
Valid Usage (Implicit)

Using Heaps

One descriptor heap of each type can be bound to a command buffer for use with shaders. When using descriptor heaps, pipelines must be created with VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT and shaders created with VK_SHADER_CREATE_DESCRIPTOR_HEAP_BIT_EXT in order to make use of the heaps.

When any heap state command is recorded to a command buffer, it immediately invalidates all descriptor set and descriptor buffer state set by vkCmdBindDescriptorSets2, vkCmdPushDescriptorSet2, vkCmdPushDescriptorSetWithTemplate2, vkCmdSetDescriptorBufferOffsets2EXT, vkCmdBindDescriptorBufferEmbeddedSamplers2EXT, vkCmdPushConstants2, vkCmdBindDescriptorSets, vkCmdPushDescriptorSet, vkCmdPushDescriptorSetWithTemplate, vkCmdBindDescriptorBuffersEXT, vkCmdSetDescriptorBufferOffsetsEXT, vkCmdBindDescriptorBufferEmbeddedSamplersEXT, or vkCmdPushConstants. Similarly, recording any of these commands immediately invalidates all state set by commands in this chapter.

Implementations may require storage in descriptor heaps for their own internal descriptors. Storage for these extra descriptors must be allocated by the application as part of each descriptor heap address range, and must not be accessed by the application while it is bound as a reserved range, in any command buffer, until all such command buffers are freed or reset. The amount of storage required by an implementation is advertised by minResourceHeapReservedRange for the resource heap, and minSamplerHeapReservedRange or minSamplerHeapReservedRangeWithEmbedded for the sampler heap (the latter being required when using embedded samplers).

Applications can set different heaps to use the same address ranges, but must take care to ensure that the reserved ranges for each heap do not overlap with each other or with user ranges.

To bind a sampler heap to a command buffer, call:

// Provided by VK_EXT_descriptor_heap
void vkCmdBindSamplerHeapEXT(
    VkCommandBuffer                             commandBuffer,
    const VkBindHeapInfoEXT*                    pBindInfo);
  • commandBuffer is the command buffer that the sampler heap will be bound to.

  • pBindInfo is a VkBindHeapInfoEXT specifying the device address range used for the heap and any implementation reservations.

Addresses in the range defined by pBindInfo->heapRange are bound as the sampler heap. The application can access samplers and data through this heap anywhere except for the reserved range specified by pBindInfo->reservedRangeOffset. Addresses in the range [pBindInfo->reservedRangeOffset, pBindInfo->reservedRangeOffset + minSamplerHeapReservedRange), or in the range [pBindInfo->reservedRangeOffset, pBindInfo->reservedRangeOffset + minSamplerHeapReservedRangeWithEmbedded) if embedded samplers will be used, are reserved for the implementation and must not be accessed by the application at any time from when this command is recorded until all command buffers with that range bound (even invalid ones) have been reset or freed.

Implementations may require a larger sampler heap reservation to store embedded sampler descriptors when used in a mapping, as advertised by minSamplerHeapReservedRangeWithEmbedded.

Shaders executed by commands recorded after this command can use the specified sampler heap to access resources. pBindInfo->heapRange.address will be available to shaders to access samplers and data through the SamplerHeapEXT BuiltIn or via shader bindings.

When vkCmdBindSamplerHeapEXT is recorded, it immediately invalidates all non-heap descriptor state. Similarly, recording any non-heap descriptor state commands immediately invalidates state set by this command.

Valid Usage
  • VUID-vkCmdBindSamplerHeapEXT-pBindInfo-11223
    The sum of pBindInfo->reservedRangeOffset and pBindInfo->reservedRangeSize must be less than or equal to pBindInfo->heapRange.size

  • VUID-vkCmdBindSamplerHeapEXT-pBindInfo-11224
    pBindInfo->reservedRangeSize must be greater than or equal to minSamplerHeapReservedRange

  • VUID-vkCmdBindSamplerHeapEXT-pBindInfo-11225
    pBindInfo->heapRange.size mustbe less than or equal to maxSamplerHeapSize

  • VUID-vkCmdBindSamplerHeapEXT-pBindInfo-11226
    pBindInfo->heapRange.address must be a multiple of samplerHeapAlignment

  • VUID-vkCmdBindSamplerHeapEXT-pBindInfo-11434
    pBindInfo->reservedRangeOffset must be a multiple of samplerDescriptorAlignment

  • VUID-vkCmdBindSamplerHeapEXT-pBindInfo-11228
    Memory bound to addresses in the range [pBindInfo->heapRange.address + pBindInfo->reservedRangeOffset, pBindInfo->heapRange.address + pBindInfo->reservedRangeOffset + pBindInfo->reservedRangeSize) must not be bound to any other command buffer as a reserved range for any heap unless the reserved range matches exactly and it is the same heap type

  • VUID-vkCmdBindSamplerHeapEXT-heapRange-11230
    heapRange must be a device address range allocated to the application from a buffer created with the VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT usage flag set

  • VUID-vkCmdBindSamplerHeapEXT-commandBuffer-11231
    If commandBuffer is a secondary command buffer, it must have begun with VkCommandBufferInheritanceDescriptorHeapInfoEXT::pSamplerHeapBindInfo equal to NULL

Valid Usage (Implicit)
  • VUID-vkCmdBindSamplerHeapEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdBindSamplerHeapEXT-pBindInfo-parameter
    pBindInfo must be a valid pointer to a valid VkBindHeapInfoEXT structure

  • VUID-vkCmdBindSamplerHeapEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdBindSamplerHeapEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support VK_QUEUE_COMPUTE_BIT, or VK_QUEUE_GRAPHICS_BIT operations

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

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

VK_QUEUE_COMPUTE_BIT
VK_QUEUE_GRAPHICS_BIT

State

Conditional Rendering

vkCmdBindSamplerHeapEXT is not affected by conditional rendering

To bind a resource heap to a command buffer, call:

// Provided by VK_EXT_descriptor_heap
void vkCmdBindResourceHeapEXT(
    VkCommandBuffer                             commandBuffer,
    const VkBindHeapInfoEXT*                    pBindInfo);
  • commandBuffer is the command buffer that the resource heap will be bound to.

  • pBindInfo is a VkBindHeapInfoEXT specifying the device address range used for the heap and any implementation reservations.

Addresses in the range defined by pBindInfo->heapRange are bound as the resource heap. The application can access resources and data through this heap anywhere except for the reserved range specified by pBindInfo->reservedRangeOffset. Addresses in the range [pBindInfo->reservedRangeOffset, pBindInfo->reservedRangeOffset + minResourceHeapReservedRange) are reserved for the implementation and must not be accessed by the application at any time from when this command is recorded until there are no command buffers with that range bound.

Shaders executed by commands recorded after this command can use the specified resource heap to access resources. pBindInfo->heapRange.address will be available to shaders to access resources through the ResourceHeapEXT BuiltIn or via shader bindings.

When vkCmdBindResourceHeapEXT is recorded, it immediately invalidates all non-heap descriptor state. Similarly, recording any non-heap descriptor state commands immediately invalidates state set by this command.

Valid Usage
  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-11232
    The sum of pBindInfo->reservedRangeOffset and pBindInfo->reservedRangeSize must be less than or equal to pBindInfo->heapRange.size

  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-11233
    pBindInfo->reservedRangeSize must be greater than or equal to minResourceHeapReservedRange

  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-11234
    pBindInfo->heapRange.size mustbe less than or equal to maxResourceHeapSize

  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-11235
    pBindInfo->heapRange.address must be a multiple of resourceHeapAlignment

  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-11435
    pBindInfo->reservedRangeOffset must be a multiple of bufferDescriptorAlignment

  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-11436
    pBindInfo->reservedRangeOffset must be a multiple of imageDescriptorAlignment

  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-11236
    Memory bound to addresses in the range [pBindInfo->heapRange.address + pBindInfo->reservedRangeOffset, pBindInfo->heapRange.address + pBindInfo->reservedRangeOffset + pBindInfo->reservedRangeSize) must not be bound to any other command buffer as a reserved range for any heap unless the reserved range matches exactly and it is the same heap type

  • VUID-vkCmdBindResourceHeapEXT-heapRange-11237
    heapRange must be a device address range allocated to the application from a buffer created with the VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT usage flag set

  • VUID-vkCmdBindResourceHeapEXT-commandBuffer-11238
    If commandBuffer is a secondary command buffer, it must have begun with VkCommandBufferInheritanceDescriptorHeapInfoEXT::pResourceHeapBindInfo equal to NULL

Valid Usage (Implicit)
  • VUID-vkCmdBindResourceHeapEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdBindResourceHeapEXT-pBindInfo-parameter
    pBindInfo must be a valid pointer to a valid VkBindHeapInfoEXT structure

  • VUID-vkCmdBindResourceHeapEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdBindResourceHeapEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support VK_QUEUE_COMPUTE_BIT, or VK_QUEUE_GRAPHICS_BIT operations

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

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

VK_QUEUE_COMPUTE_BIT
VK_QUEUE_GRAPHICS_BIT

State

Conditional Rendering

vkCmdBindResourceHeapEXT is not affected by conditional rendering

VkBindHeapInfoEXT is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkBindHeapInfoEXT {
    VkStructureType            sType;
    const void*                pNext;
    VkDeviceAddressRangeEXT    heapRange;
    VkDeviceSize               reservedRangeOffset;
    VkDeviceSize               reservedRangeSize;
} VkBindHeapInfoEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • heapRange is a VkDeviceAddressRangeEXT defining the device address range used for the heap, inclusive of the implementation reserved range.

  • reservedRangeOffset is the offset within heapRange to the start of the reserved range for the implementation.

  • reservedRangeSize is the size of the reserved range for the implementation within heapRange.

Valid Usage (Implicit)
SamplerHeapEXT

Decorating a variable with the SamplerHeapEXT built-in decoration will back it with the contents of the sampler heap bound by vkCmdBindSamplerHeapEXT.

Valid Usage
  • VUID-SamplerHeapEXT-SamplerHeapEXT-11239
    The variable decorated with SamplerHeapEXT must be declared using the UniformConstant Storage Class

ResourceHeapEXT

Decorating a variable with the ResourceHeapEXT built-in decoration will back it with the contents of the resource heap bound by vkCmdBindResourceHeapEXT.

Valid Usage
  • VUID-ResourceHeapEXT-ResourceHeapEXT-11241
    The variable decorated with ResourceHeapEXT must be declared using the UniformConstant Storage Class

Push Data

Push constants specified by vkCmdPushConstants or vkCmdPushConstants2KHR rely on descriptor set layout state, and are not compatible with descriptor heaps. A new push interface is provided for use with descriptor heaps:

To update push data when using descriptor heaps, call:

// Provided by VK_EXT_descriptor_heap
void vkCmdPushDataEXT(
    VkCommandBuffer                             commandBuffer,
    const VkPushDataInfoEXT*                    pPushDataInfo);
  • commandBuffer is the command buffer in which the push data update will be recorded.

  • pPushDataInfo is a pointer to a VkPushDataInfoEXT structure.

When vkCmdPushDataEXT is recorded, it immediately invalidates all non-heap descriptor state. Similarly, recording any non-heap descriptor state commands immediately invalidates state set by this command.

All push data is available to all shaders using the existing PushConstant Storage Class.

Device addresses in push data are intended as the fast path for shader-constant data that does not fit into push data directly. In order to maximize performance of constant data inputs, addresses should be aligned to minUniformBufferOffsetAlignment, and decorated with Alignment and NonWritable in the shader when using physical pointers.

Valid Usage (Implicit)
  • VUID-vkCmdPushDataEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdPushDataEXT-pPushDataInfo-parameter
    pPushDataInfo must be a valid pointer to a valid VkPushDataInfoEXT structure

  • VUID-vkCmdPushDataEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdPushDataEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support VK_QUEUE_COMPUTE_BIT, or VK_QUEUE_GRAPHICS_BIT operations

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

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

VK_QUEUE_COMPUTE_BIT
VK_QUEUE_GRAPHICS_BIT

State

Conditional Rendering

vkCmdPushDataEXT is not affected by conditional rendering

The VkPushDataInfoEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkPushDataInfoEXT {
    VkStructureType               sType;
    const void*                   pNext;
    uint32_t                      offset;
    VkHostAddressRangeConstEXT    data;
} VkPushDataInfoEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • offset is the start offset of the push data range to update, in units of bytes.

  • data is the host address range containing the push data to update.

Valid Usage
  • VUID-VkPushDataInfoEXT-offset-11243
    The sum of offset and data.size must be less than or equal to maxPushDataSize

  • VUID-VkPushDataInfoEXT-offset-11418
    offset must be a multiple of 4

  • VUID-VkPushDataInfoEXT-data-11419
    data.size must be a multiple of 4

Valid Usage (Implicit)

Push Data Banks

When the pushConstantBank feature is enabled, applications can specify the hardware bank into which data is pushed using the VkPushConstantBankInfoNV structure.

The VkPushConstantBankInfoNV structure is defined as:

// Provided by VK_NV_push_constant_bank
typedef struct VkPushConstantBankInfoNV {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           bank;
} VkPushConstantBankInfoNV;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • bank is the index of the hardware bank into which the data is pushed.

This structure can be chained to VkPushDataInfoEXT, VkPushConstantsInfo, VkDescriptorSetAndBindingMappingEXT, and VkIndirectCommandsLayoutTokenEXT via the pNext chain to specify push constant bank placement:

This allows for more flexible push constant management in descriptor heap scenarios where shaders access different root descriptors with specific bank requirements.

Valid Usage
Valid Usage (Implicit)

Shader Bindings

While descriptor heaps can be accessed directly through the SamplerHeapEXT and ResourceHeapEXT built-ins, shaders using the existing DescriptorSet and Binding decorations can map these to heap offsets. In place of descriptor set layouts and pipeline layouts, information can be provided at pipeline or shader creation time to indicate how these bindings are mapped, through a combination of constants, push data, and indirections through device addresses. This interface provides significantly more flexibility than descriptor set layouts, enabling applications to specify precisely where they expect each descriptor to be.

The VkShaderDescriptorSetAndBindingMappingInfoEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkShaderDescriptorSetAndBindingMappingInfoEXT {
    VkStructureType                               sType;
    const void*                                   pNext;
    uint32_t                                      mappingCount;
    const VkDescriptorSetAndBindingMappingEXT*    pMappings;
} VkShaderDescriptorSetAndBindingMappingInfoEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • mappingCount is the number of elements in pMappings.

  • pMappings is a pointer to an array of VkDescriptorSetAndBindingMappingEXT structures specifying mappings for a set of descriptors

Including this structure in the pNext chain of VkPipelineShaderStageCreateInfo will set mappings for the shader defined by that structure. Similarly, including this structure in the pNext chain of a VkShaderCreateInfoEXT with a codeType of VK_SHADER_CODE_TYPE_SPIRV_EXT, will set mappings for that shader.

If this structure is not present, it is equivalent to setting mappingCount to 0.

Valid Usage
  • VUID-VkShaderDescriptorSetAndBindingMappingInfoEXT-pMappings-11244
    Any two elements of pMappings must not have the same value of descriptorSet, an overlapping range specified by firstBinding and bindingCount, and any overlapping bits in resourceMask

Valid Usage (Implicit)

The VkDescriptorSetAndBindingMappingEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorSetAndBindingMappingEXT {
    VkStructureType                     sType;
    const void*                         pNext;
    uint32_t                            descriptorSet;
    uint32_t                            firstBinding;
    uint32_t                            bindingCount;
    VkSpirvResourceTypeFlagsEXT         resourceMask;
    VkDescriptorMappingSourceEXT        source;
    VkDescriptorMappingSourceDataEXT    sourceData;
} VkDescriptorSetAndBindingMappingEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • descriptorSet is the value of DescriptorSet for resources that this mapping affects.

  • firstBinding is the first value of Binding of resources that this mapping affects.

  • bindingCount is the number of consecutive Binding values of resources that this mapping affects.

  • resourceMask is a mask of VkSpirvResourceTypeFlagBitsEXT values indicating which resource types are specified by this mapping.

  • source is a VkDescriptorMappingSourceEXT value specifying the method of mapping specified for the affected resources.

  • sourceData is a VkDescriptorMappingSourceDataEXT that provides the details of how each mapping is specified according to source.

Resources specified in a shader with a DescriptorSet decoration set to descriptorSet, a Binding decoration greater than or equal to firstBinding and less than the sum of firstBinding and bindingCount, and a resource type matching one of the bits in resourceMask will be mapped according to source and sourceData.

Applications are free to overspecify bindings that are not present; allowing reuse of the same mapping structures with multiple shaders, even when those shaders only partially reuse those mappings. This includes things like setting binding counts higher than the number used in the shader, specifying bindings that are not present in the shader, and setting resourceMask to all possible resources that may be encountered.

If source selects an element of sourceData defined by a structure, the description of that structure defines how resources are mapped. Source mappings using a single base type are defined here.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_CONSTANT_OFFSET_EXT, the resource will be backed by heap data as specified by constantOffset.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_PUSH_INDEX_EXT, the resource will be backed by heap data as specified by pushIndex.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_INDIRECT_INDEX_EXT, the resource will be backed by heap data as specified by indirectIndex.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_INDIRECT_INDEX_ARRAY_EXT, the resource will be backed by heap data as specified by indirectIndexArray.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_RESOURCE_HEAP_DATA_EXT, the resource will be backed by heap data as specified by heapData.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_DATA_EXT, the resource will be backed by push data at a range from pushDataOffset to the size of the resource, allowing a uniform buffer to be backed by push data access push data. Accessing data in the uniform buffer at an offset of shaderOffset in the shader will access push data at an offset equal to

offset = shaderOffset + pushDataOffset.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_ADDRESS_EXT, the resource will be backed by data pointed to by a device address in push data at an offset of pushAddressOffset. Accessing data via the mapped resource in the shader will access data backing the address specified in push data:

address = ((VkDeviceAddress*)pPushData)[pushAddressOffset/8]

where pPushData is the total set of push data specified by vkCmdPushDataEXT. If the shader resource is an acceleration structure, the address must be a valid acceleration structure address.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_INDIRECT_ADDRESS_EXT, the resource will be backed by heap data as specified by indirectAddress.

Accesses to resources using mappings to anything that is not a descriptor in a heap are not subject to robustness guarantees; resources for such mappings must not be accessed out of bounds.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_SHADER_RECORD_INDEX_EXT, the resource will be backed by heap data as specified by shaderRecordIndex.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_SHADER_RECORD_DATA_EXT, the resource will be backed by shader record data at a range from shaderRecordDataOffset to the size of the resource, allowing a uniform buffer to be used as a way to access shader record data. Accessing data in the uniform buffer at an offset shaderOffset in the shader will access shader record data at an offset equal to

offset = shaderOffset + shaderRecordDataOffset.

If source is VK_DESCRIPTOR_MAPPING_SOURCE_SHADER_RECORD_ADDRESS_EXT, the resource will be backed by data pointed to by a device address in the shader record at shaderRecordAddressOffset. Accessing data via the mapped resource in the shader will access data backing the address specified in shader record data:

address = ((VkDeviceAddress*)pShaderRecordData)[shaderRecordAddressOffset/8]

where pShaderRecord is the memory associated with a given shader as its shader record. If the shader resource is an acceleration structure, the address must be a valid acceleration structure address.

Accesses to resources using VK_DESCRIPTOR_MAPPING_SOURCE_SHADER_RECORD_ADDRESS_EXT mappings are not subject to robustness guarantees; data must not be accessed outside of the allocated memory range.

Mappings must be declared for all variables with a DescriptorSet and Binding in the shader resource interface.

Valid Usage
Valid Usage (Implicit)

Bits which can be set in VkDescriptorSetAndBindingMappingEXT::resourceMask, are:

// Provided by VK_EXT_descriptor_heap
typedef enum VkSpirvResourceTypeFlagBitsEXT {
    VK_SPIRV_RESOURCE_TYPE_ALL_EXT = 0x7FFFFFFF,
    VK_SPIRV_RESOURCE_TYPE_SAMPLER_BIT_EXT = 0x00000001,
    VK_SPIRV_RESOURCE_TYPE_SAMPLED_IMAGE_BIT_EXT = 0x00000002,
    VK_SPIRV_RESOURCE_TYPE_READ_ONLY_IMAGE_BIT_EXT = 0x00000004,
    VK_SPIRV_RESOURCE_TYPE_READ_WRITE_IMAGE_BIT_EXT = 0x00000008,
    VK_SPIRV_RESOURCE_TYPE_COMBINED_SAMPLED_IMAGE_BIT_EXT = 0x00000010,
    VK_SPIRV_RESOURCE_TYPE_UNIFORM_BUFFER_BIT_EXT = 0x00000020,
    VK_SPIRV_RESOURCE_TYPE_READ_ONLY_STORAGE_BUFFER_BIT_EXT = 0x00000040,
    VK_SPIRV_RESOURCE_TYPE_READ_WRITE_STORAGE_BUFFER_BIT_EXT = 0x00000080,
  // Provided by VK_EXT_descriptor_heap with VK_KHR_ray_tracing_pipeline or VK_NV_ray_tracing
    VK_SPIRV_RESOURCE_TYPE_ACCELERATION_STRUCTURE_BIT_EXT = 0x00000100,
  // Provided by VK_EXT_descriptor_heap with VK_ARM_tensors
    VK_SPIRV_RESOURCE_TYPE_TENSOR_BIT_ARM = 0x00000200,
} VkSpirvResourceTypeFlagBitsEXT;
// Provided by VK_EXT_descriptor_heap
typedef VkFlags VkSpirvResourceTypeFlagsEXT;

VkSpirvResourceTypeFlagsEXT is a bitmask type for setting a mask of zero or more VkSpirvResourceTypeFlagBitsEXT.

The possible mapping sources for a shader binding are:

// Provided by VK_EXT_descriptor_heap
typedef enum VkDescriptorMappingSourceEXT {
    VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_CONSTANT_OFFSET_EXT = 0,
    VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_PUSH_INDEX_EXT = 1,
    VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_INDIRECT_INDEX_EXT = 2,
    VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_INDIRECT_INDEX_ARRAY_EXT = 3,
    VK_DESCRIPTOR_MAPPING_SOURCE_RESOURCE_HEAP_DATA_EXT = 4,
    VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_DATA_EXT = 5,
    VK_DESCRIPTOR_MAPPING_SOURCE_PUSH_ADDRESS_EXT = 6,
    VK_DESCRIPTOR_MAPPING_SOURCE_INDIRECT_ADDRESS_EXT = 7,
  // Provided by VK_EXT_descriptor_heap with VK_KHR_ray_tracing_pipeline or VK_NV_ray_tracing
    VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_SHADER_RECORD_INDEX_EXT = 8,
  // Provided by VK_EXT_descriptor_heap with VK_KHR_ray_tracing_pipeline or VK_NV_ray_tracing
    VK_DESCRIPTOR_MAPPING_SOURCE_SHADER_RECORD_DATA_EXT = 9,
  // Provided by VK_EXT_descriptor_heap with VK_KHR_ray_tracing_pipeline or VK_NV_ray_tracing
    VK_DESCRIPTOR_MAPPING_SOURCE_SHADER_RECORD_ADDRESS_EXT = 10,
} VkDescriptorMappingSourceEXT;

The VkDescriptorMappingSourceDataEXT union is defined as:

// Provided by VK_EXT_descriptor_heap
typedef union VkDescriptorMappingSourceDataEXT {
    VkDescriptorMappingSourceConstantOffsetEXT        constantOffset;
    VkDescriptorMappingSourcePushIndexEXT             pushIndex;
    VkDescriptorMappingSourceIndirectIndexEXT         indirectIndex;
    VkDescriptorMappingSourceIndirectIndexArrayEXT    indirectIndexArray;
    VkDescriptorMappingSourceHeapDataEXT              heapData;
    uint32_t                                          pushDataOffset;
    uint32_t                                          pushAddressOffset;
    VkDescriptorMappingSourceIndirectAddressEXT       indirectAddress;
    VkDescriptorMappingSourceShaderRecordIndexEXT     shaderRecordIndex;
    uint32_t                                          shaderRecordDataOffset;
    uint32_t                                          shaderRecordAddressOffset;
} VkDescriptorMappingSourceDataEXT;
  • constantOffset is a VkDescriptorMappingSourceConstantOffsetEXT structure specifying the mapping for resources at a constant byte offset into a heap.

  • pushIndex is a VkDescriptorMappingSourcePushIndexEXT structure specifying the mapping for resources at an index into a heap source from push data.

  • indirectIndex is a VkDescriptorMappingSourceIndirectIndexEXT structure specifying the mapping for resources at an index into a heap source from an address in push data.

  • indirectIndexArray is a VkDescriptorMappingSourceIndirectIndexArrayEXT structure specifying the mapping for resources to an array of indices into a heap source from an address in push data.

  • heapData is a VkDescriptorMappingSourceHeapDataEXT structure specifying an offset into heap data for a uniform buffer to map to.

  • pushDataOffset an offset into push data for a uniform buffer to map to.

  • pushAddressOffset an offset into push data storing an address for a resource to map to.

  • indirectAddress is a VkDescriptorMappingSourceIndirectAddressEXT structure specifying an address in push data containing another address for a resource to map to.

  • shaderRecordIndex is a VkDescriptorMappingSourceShaderRecordIndexEXT structure specifying the mapping for resources at an index into a heap source from shader record data.

  • shaderRecordDataOffset an offset into shader record data for a uniform buffer to map to.

  • shaderRecordAddressOffset an offset into shader record data storing an address for a resource to map to.

The VkDescriptorMappingSourceConstantOffsetEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorMappingSourceConstantOffsetEXT {
    uint32_t                      heapOffset;
    uint32_t                      heapArrayStride;
    const VkSamplerCreateInfo*    pEmbeddedSampler;
    uint32_t                      samplerHeapOffset;
    uint32_t                      samplerHeapArrayStride;
} VkDescriptorMappingSourceConstantOffsetEXT;
  • heapOffset is a constant byte offset added to the heap address for the mapped resource or sampler.

  • heapArrayStride is a constant byte stride that multiplies the shader binding and array index.

  • pEmbeddedSampler is an optional VkSamplerCreateInfo structure specifying a sampler to embed into the shader, in place of looking the sampler up in a heap.

  • samplerHeapOffset is used only when mapping a combined image sampler, used in place of heapOffset to retrieve the sampler.

  • samplerHeapArrayStride is used only when mapping a combined image sampler, used in place of heapArrayStride to retrieve the sampler.

Resources using this mapping will be backed by a descriptor in the heap, at an offset calculated as

shaderIndex = (Binding - firstBinding) + arrayIndex

offset = heapOffset + (shaderIndex * heapArrayStride)

where Binding is the binding value in the shader, arrayIndex is the index into the array if the shader binding is declared as an array.

If the mapped resource is a OpTypeSampledImage, offset is instead calculated for the sampler as

offset = samplerHeapOffset + (shaderIndex * samplerHeapArrayStride)

If the mapped resource is a OpTypeSampler or OpTypeSampledImage, and pEmbeddedSampler is not NULL, the specified embedded sampler will be used rather than accessing the sampler heap.

Valid Usage
Valid Usage (Implicit)
  • VUID-VkDescriptorMappingSourceConstantOffsetEXT-pEmbeddedSampler-parameter
    If pEmbeddedSampler is not NULL, pEmbeddedSampler must be a valid pointer to a valid VkSamplerCreateInfo structure

The VkDescriptorMappingSourcePushIndexEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorMappingSourcePushIndexEXT {
    uint32_t                      heapOffset;
    uint32_t                      pushOffset;
    uint32_t                      heapIndexStride;
    uint32_t                      heapArrayStride;
    const VkSamplerCreateInfo*    pEmbeddedSampler;
    VkBool32                      useCombinedImageSamplerIndex;
    uint32_t                      samplerHeapOffset;
    uint32_t                      samplerPushOffset;
    uint32_t                      samplerHeapIndexStride;
    uint32_t                      samplerHeapArrayStride;
} VkDescriptorMappingSourcePushIndexEXT;
  • heapOffset is a constant byte offset added to the heap address for the mapped resource or sampler.

  • pushOffset is an index into push data where an index into the heap for the mapped resource will be retrieved.

  • heapIndexStride is a constant byte stride that multiplies the index in push data.

  • heapArrayStride is a constant byte stride that multiplies the shader binding and array index.

  • pEmbeddedSampler is an optional VkSamplerCreateInfo structure specifying a sampler to embed into the shader, in place of looking the sampler up in a heap.

  • useCombinedImageSamplerIndex specifies whether the generated index value will be decoded as two packed indices if the mapped resource is an OpTypeSampledImage.

  • samplerHeapOffset is used only when mapping a combined image sampler, used in place of heapOffset to retrieve the sampler.

  • samplerPushOffset is used only when mapping a combined image sampler, used in place of pushOffset to retrieve the sampler.

  • samplerHeapIndexStride is used only when mapping a combined image sampler, used in place of heapIndexStride to retrieve the sampler.

  • samplerHeapArrayStride is used only when mapping a combined image sampler, used in place of heapArrayStride to retrieve the sampler.

Resources using this mapping will be backed by a descriptor in the heap, at an offset calculated as

pushIndex = ((uint32_t*)pPushData)[pushOffset/4]

shaderIndex = (Binding - firstBinding) + arrayIndex

offset = heapOffset + (pushIndex × heapIndexStride) + (shaderIndex × heapArrayStride)

where Binding is the binding value in the shader, arrayIndex is the index into the array if the shader binding is declared as an array, and pPushData is the total set of push data specified by vkCmdPushDataEXT.

If the mapped resource is a OpTypeSampledImage, offset is instead calculated for the sampler as

samplerPushIndex = ((uint32_t*)pPushData)[samplerPushOffset/4]

offset = samplerHeapOffset + (samplerPushIndex × samplerHeapIndexStride) + (shaderIndex × samplerHeapArrayStride)

If useCombinedImageSamplerIndex is VK_TRUE, and the mapped resource is a OpTypeSampledImage, pushIndex and samplerPushIndex in the above equations are instead calculated as

pushIndex = ((uint32_t*)pPushData)[pushOffset/4] & 0xFFFFF

samplerPushIndex = (((uint32_t*)pPushData)[pushOffset/4] >> 20) & 0xFFF

If the mapped resource is a OpTypeSampler or OpTypeSampledImage, and pEmbeddedSampler is not NULL, the specified embedded sampler will be used rather than accessing the sampler heap.

Valid Usage
Valid Usage (Implicit)
  • VUID-VkDescriptorMappingSourcePushIndexEXT-pEmbeddedSampler-parameter
    If pEmbeddedSampler is not NULL, pEmbeddedSampler must be a valid pointer to a valid VkSamplerCreateInfo structure

The VkDescriptorMappingSourceIndirectIndexEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorMappingSourceIndirectIndexEXT {
    uint32_t                      heapOffset;
    uint32_t                      pushOffset;
    uint32_t                      addressOffset;
    uint32_t                      heapIndexStride;
    uint32_t                      heapArrayStride;
    const VkSamplerCreateInfo*    pEmbeddedSampler;
    VkBool32                      useCombinedImageSamplerIndex;
    uint32_t                      samplerHeapOffset;
    uint32_t                      samplerPushOffset;
    uint32_t                      samplerAddressOffset;
    uint32_t                      samplerHeapIndexStride;
    uint32_t                      samplerHeapArrayStride;
} VkDescriptorMappingSourceIndirectIndexEXT;
  • heapOffset is a constant byte offset added to the heap address for the mapped resource or sampler.

  • pushOffset is an offset into push data where an the indirect address will be.

  • addressOffset is an index into the address in push data where an index into the heap for the mapped resource will be retrieved.

  • heapIndexStride is a constant byte stride that multiplies the index in indirect data.

  • heapArrayStride is a constant byte stride that multiplies the shader binding and array index.

  • pEmbeddedSampler is an optional VkSamplerCreateInfo structure specifying a sampler to embed into the shader, in place of looking the sampler up in a heap.

  • useCombinedImageSamplerIndex specifies whether the generated index value will be decoded as two packed indices if the mapped resource is an OpTypeSampledImage.

  • samplerHeapOffset is used only when mapping a combined image sampler, used in place of heapOffset to retrieve the sampler.

  • samplerPushOffset is used only when mapping a combined image sampler, used in place of pushOffset to retrieve the sampler.

  • samplerAddressOffset is used only when mapping a combined image sampler, used in place of addressOffset to retrieve the sampler.

  • samplerHeapIndexStride is used only when mapping a combined image sampler, used in place of heapIndexStride to retrieve the sampler.

  • samplerHeapArrayStride is used only when mapping a combined image sampler, used in place of heapArrayStride to retrieve the sampler.

Resources using this mapping will be backed by a descriptor in the heap, at an offset calculated as

uint32_t *indirectAddress = ((VkDeviceAddress*)pPushData)[pushOffset/8]

indirectIndex = indirectAddress[(addressOffset / 4)]

shaderIndex = (Binding - firstBinding) + arrayIndex

offset = heapOffset + (indirectIndex × heapIndexStride) + (shaderIndex × heapArrayStride)

where Binding is the binding value in the shader, arrayIndex is the index into the array if the shader binding is declared as an array, and pPushData is the total set of push data specified by vkCmdPushDataEXT. The value of the address in push data must be a multiple of 4. Index reads through indirectAddress are performed as non-volatile uniform buffer reads, and can be synchronized using VK_ACCESS_2_UNIFORM_READ_BIT. The value in memory must remain static while any shader invocation using this mapping is in flight to avoid a data race.

If the mapped resource is a OpTypeSampledImage, offset is instead calculated for the sampler as

uint32_t *samplerIndirectAddress = ((VkDeviceAddress*)pPushData)[samplerPushOffset/8]

samplerIndirectIndex = samplerIndirectAddress[(samplerAddressOffset / 4)]

offset = samplerHeapOffset + (samplerIndirectIndex × samplerHeapIndexStride) + (shaderIndex × samplerHeapArrayStride)

If useCombinedImageSamplerIndex is VK_TRUE, and the mapped resource is a OpTypeSampledImage, indirectIndex and samplerIndirectIndex in the above equations are instead calculated as

indirectIndex = indirectAddress[addressOffset/4] & 0xFFFFF

samplerIndirectIndex = indirectAddress[addressOffset/4] >> 20) & 0xFFF

If the mapped resource is a OpTypeSampler or OpTypeSampledImage, and pEmbeddedSampler is not NULL, the specified embedded sampler will be used rather than accessing the sampler heap.

Valid Usage
  • VUID-VkDescriptorMappingSourceIndirectIndexEXT-pushOffset-11260
    pushOffset must be a multiple of 8

  • VUID-VkDescriptorMappingSourceIndirectIndexEXT-pushOffset-11261
    pushOffset must be less than or equal to maxPushDataSize - 8

  • VUID-VkDescriptorMappingSourceIndirectIndexEXT-addressOffset-11262
    addressOffset must be a multiple of 4

  • VUID-VkDescriptorMappingSourceIndirectIndexEXT-pEmbeddedSampler-11447
    If pEmbeddedSampler is a valid pointer to a VkSamplerCreateInfo, its borderColor must not be VK_BORDER_COLOR_FLOAT_CUSTOM_EXT or VK_BORDER_COLOR_INT_CUSTOM_EXT

  • VUID-VkDescriptorMappingSourceIndirectIndexEXT-pEmbeddedSampler-11403
    If pEmbeddedSampler is a valid pointer to a VkSamplerCreateInfo, and there is a VkDebugUtilsObjectNameInfoEXT structure in its pNext chain, its objectType must be VK_OBJECT_TYPE_UNKNOWN

Valid Usage (Implicit)
  • VUID-VkDescriptorMappingSourceIndirectIndexEXT-pEmbeddedSampler-parameter
    If pEmbeddedSampler is not NULL, pEmbeddedSampler must be a valid pointer to a valid VkSamplerCreateInfo structure

The VkDescriptorMappingSourceIndirectIndexArrayEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorMappingSourceIndirectIndexArrayEXT {
    uint32_t                      heapOffset;
    uint32_t                      pushOffset;
    uint32_t                      addressOffset;
    uint32_t                      heapIndexStride;
    const VkSamplerCreateInfo*    pEmbeddedSampler;
    VkBool32                      useCombinedImageSamplerIndex;
    uint32_t                      samplerHeapOffset;
    uint32_t                      samplerPushOffset;
    uint32_t                      samplerAddressOffset;
    uint32_t                      samplerHeapIndexStride;
} VkDescriptorMappingSourceIndirectIndexArrayEXT;
  • heapOffset is a constant byte offset added to the heap address for the mapped resource or sampler.

  • pushOffset is an offset into push data where an the indirect address will be.

  • addressOffset is an index into the address in push data where an index into the heap for the mapped resource will be retrieved.

  • heapIndexStride is a constant byte stride that multiplies the index in indirect data.

  • pEmbeddedSampler is an optional VkSamplerCreateInfo structure specifying a sampler to embed into the shader, in place of looking the sampler up in a heap.

  • useCombinedImageSamplerIndex specifies whether the generated index value will be decoded as two packed indices if the mapped resource is an OpTypeSampledImage.

  • samplerHeapOffset is used only when mapping a combined image sampler, used in place of heapOffset to retrieve the sampler.

  • samplerPushOffset is used only when mapping a combined image sampler, used in place of pushOffset to retrieve the sampler.

  • samplerAddressOffset is used only when mapping a combined image sampler, used in place of addressOffset to retrieve the sampler.

  • samplerHeapIndexStride is used only when mapping a combined image sampler, used in place of heapIndexStride to retrieve the sampler.

Resources using this mapping will be backed by a descriptor in the heap, at an offset calculated as

uint32_t *indirectAddress = ((VkDeviceAddress*)pPushData)[pushOffset/8]

shaderIndex = (Binding - firstBinding) + arrayIndex

indirectIndex = indirectAddress[(addressOffset / 4) + shaderIndex]

offset = heapOffset + (indirectIndex × heapIndexStride)

where Binding is the binding value in the shader, arrayIndex is the index into the array if the shader binding is declared as an array, and pPushData is the total set of push data specified by vkCmdPushDataEXT. The value of the address in push data must be a multiple of 4. Index reads through indirectAddress are performed as non-volatile uniform buffer reads, and can be synchronized using VK_ACCESS_2_UNIFORM_READ_BIT. The value in memory must remain static while any shader invocation using this mapping is in flight to avoid a data race.

If the mapped resource is a OpTypeSampledImage, offset is instead calculated for the sampler as

uint32_t *samplerIndirectAddress = ((VkDeviceAddress*)pPushData)[samplerPushOffset/8]

samplerIndirectIndex = samplerAddr[(samplerAddressOffset / 4) + shaderIndex]

offset = samplerHeapOffset + (samplerIndirectIndex × samplerHeapIndexStride)

If useCombinedImageSamplerIndex is VK_TRUE, and the mapped resource is a OpTypeSampledImage, indirectIndex and samplerIndirectIndex in the above equations are instead calculated as

indirectIndex = indirectAddress[addressOffset/4 + shaderIndex] & 0xFFFFF

samplerIndirectIndex = indirectAddress[addressOffset/4 + shaderIndex] >> 20) & 0xFFF

If the mapped resource is a OpTypeSampler or OpTypeSampledImage, and pEmbeddedSampler is not NULL, the specified embedded sampler will be used rather than accessing the sampler heap.

Valid Usage
  • VUID-VkDescriptorMappingSourceIndirectIndexArrayEXT-pushOffset-11359
    pushOffset must be a multiple of 8

  • VUID-VkDescriptorMappingSourceIndirectIndexArrayEXT-pushOffset-11360
    pushOffset must be less than or equal to maxPushDataSize - 8

  • VUID-VkDescriptorMappingSourceIndirectIndexArrayEXT-addressOffset-11361
    addressOffset must be a multiple of 4

  • VUID-VkDescriptorMappingSourceIndirectIndexArrayEXT-pEmbeddedSampler-11448
    If pEmbeddedSampler is a valid pointer to a VkSamplerCreateInfo, its borderColor must not be VK_BORDER_COLOR_FLOAT_CUSTOM_EXT or VK_BORDER_COLOR_INT_CUSTOM_EXT

  • VUID-VkDescriptorMappingSourceIndirectIndexArrayEXT-pEmbeddedSampler-11404
    If pEmbeddedSampler is a valid pointer to a VkSamplerCreateInfo, and there is a VkDebugUtilsObjectNameInfoEXT structure in its pNext chain, its objectType must be VK_OBJECT_TYPE_UNKNOWN

Valid Usage (Implicit)
  • VUID-VkDescriptorMappingSourceIndirectIndexArrayEXT-pEmbeddedSampler-parameter
    If pEmbeddedSampler is not NULL, pEmbeddedSampler must be a valid pointer to a valid VkSamplerCreateInfo structure

The VkDescriptorMappingSourceHeapDataEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorMappingSourceHeapDataEXT {
    uint32_t    heapOffset;
    uint32_t    pushOffset;
} VkDescriptorMappingSourceHeapDataEXT;
  • heapOffset is a constant byte offset added to the heap address for the mapped buffer.

  • pushOffset is an index into push data where an additional offset into the heap for the mapped resource will be retrieved.

Uniform buffers using this mapping will be backed directly by data in the heap. Accessing data in the uniform buffer at an offset of shaderOffset in the shader will access heap data at an offset equal to

offset = shaderOffset + heapOffset + ((uint32_t*)pPushData)[pushOffset/4]

where pPushData is the total set of push data specified by vkCmdPushDataEXT. Shader reads through the heap mapped in this way are performed according to the mapped resource.

Valid Usage
  • VUID-VkDescriptorMappingSourceHeapDataEXT-heapOffset-11263
    heapOffset must be a multiple of minUniformBufferOffsetAlignment

  • VUID-VkDescriptorMappingSourceHeapDataEXT-pushOffset-11264
    pushOffset must be a multiple of 4

  • VUID-VkDescriptorMappingSourceHeapDataEXT-pushOffset-11265
    pushOffset must be less than or equal to maxPushDataSize - 4

The VkDescriptorMappingSourceIndirectAddressEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorMappingSourceIndirectAddressEXT {
    uint32_t    pushOffset;
    uint32_t    addressOffset;
} VkDescriptorMappingSourceIndirectAddressEXT;
  • pushOffset is a byte offset into push data where an indirect address containing the address for the mapped resource will be retrieved.

  • addressOffset is a byte offset into the indirect address where the address for the mapped resource will be retrieved.

Accessing data via the mapped resource in the shader will access data backing the address specified in the indirect address at the supplied offset:

indirectAddress = ((VkDeviceAddress*)pPushData)[pushOffset/8]

resourceAddress = ((VkDeviceAddress*)indirectAddress)[addressOffset/8]

where pPushData is the total set of push data specified by vkCmdPushDataEXT. Reads through indirectAddress are performed as non-volatile uniform buffer reads, and can be synchronized using VK_ACCESS_2_UNIFORM_READ_BIT. Shader reads through resourceAddress are performed according to the mapped resource. If the shader resource is an acceleration structure, the address must be a valid acceleration structure address.

Valid Usage
  • VUID-VkDescriptorMappingSourceIndirectAddressEXT-pushOffset-11266
    pushOffset must be a multiple of 8

  • VUID-VkDescriptorMappingSourceIndirectAddressEXT-pushOffset-11267
    pushOffset must be less than or equal to maxPushDataSize - 8

  • VUID-VkDescriptorMappingSourceIndirectAddressEXT-addressOffset-11268
    addressOffset must be a multiple of 8

The VkDescriptorMappingSourceShaderRecordIndexEXT structure is defined as:

// Provided by VK_EXT_descriptor_heap
typedef struct VkDescriptorMappingSourceShaderRecordIndexEXT {
    uint32_t                      heapOffset;
    uint32_t                      shaderRecordOffset;
    uint32_t                      heapIndexStride;
    uint32_t                      heapArrayStride;
    const VkSamplerCreateInfo*    pEmbeddedSampler;
    VkBool32                      useCombinedImageSamplerIndex;
    uint32_t                      samplerHeapOffset;
    uint32_t                      samplerShaderRecordOffset;
    uint32_t                      samplerHeapIndexStride;
    uint32_t                      samplerHeapArrayStride;
} VkDescriptorMappingSourceShaderRecordIndexEXT;
  • heapOffset is a constant byte offset added to the heap address for the mapped resource or sampler.

  • shaderRecordOffset is an index into shader record data where an index into the heap for the mapped resource will be retrieved.

  • heapIndexStride is a constant byte stride that multiplies the index in shader record data.

  • heapArrayStride is a constant byte stride that multiplies the shader binding and array index.

  • pEmbeddedSampler is an optional VkSamplerCreateInfo structure specifying a sampler to embed into the shader, in place of looking the sampler up in a heap.

  • useCombinedImageSamplerIndex specifies whether the generated index value will be decoded as two packed indices if the mapped resource is an OpTypeSampledImage.

  • samplerHeapOffset is used only when mapping a combined image sampler, used in place of heapOffset to retrieve the sampler.

  • samplerShaderRecordOffset is used only when mapping a combined image sampler, used in place of shaderRecordOffset to retrieve the sampler.

  • samplerHeapIndexStride is used only when mapping a combined image sampler, used in place of heapIndexStride to retrieve the sampler.

  • samplerHeapArrayStride is used only when mapping a combined image sampler, used in place of heapArrayStride to retrieve the sampler.

Resources using this mapping will be backed by a descriptor in the heap, at an offset calculated as

shaderRecordIndex = ((uint32_t*)pShaderRecordData)[shaderRecordOffset/4]

shaderIndex = (Binding - firstBinding) + arrayIndex

offset = heapOffset + (shaderRecordIndex × heapIndexStride) + (shaderIndex × heapArrayStride)

where Binding is the binding value in the shader, arrayIndex is the index into the array if the shader binding is declared as an array, and pShaderRecordData is the set of shader record data accessible to the shader.

If the mapped resource is a OpTypeSampledImage, offset is instead calculated for the sampler as

samplerShaderRecordIndex = ((uint32_t*)pShaderRecordData)[samplerShaderRecordOffset/4]

offset = samplerHeapOffset + (samplerShaderRecordIndex × samplerHeapIndexStride) + (shaderIndex × samplerHeapArrayStride)

If useCombinedImageSamplerIndex is VK_TRUE, and the mapped resource is a OpTypeSampledImage, shaderRecordIndex and samplerShaderRecordIndex in the above equations are instead calculated as

shaderRecordIndex = ((uint32_t*)pShaderRecordData)[shaderRecordOffset/4] & 0xFFFFF

samplerShaderRecordIndex = (((uint32_t*)pShaderRecordData)[shaderRecordOffset/4] >> 20) & 0xFFF

If the mapped resource is a OpTypeSampler or OpTypeSampledImage, and pEmbeddedSampler is not NULL, the specified embedded sampler will be used rather than accessing the sampler heap.

Valid Usage
Valid Usage (Implicit)
  • VUID-VkDescriptorMappingSourceShaderRecordIndexEXT-pEmbeddedSampler-parameter
    If pEmbeddedSampler is not NULL, pEmbeddedSampler must be a valid pointer to a valid VkSamplerCreateInfo structure

Packing descriptors more tightly

For simplicity, descriptor sizes are advertised and treated by default as equal to the advertised descriptor size limits:

However, for some specific use cases it is useful to be able to pack specific descriptors into memory more tightly than this when the implementation allows for this.

To query the size of heap descriptor for a specific VkDescriptorType, call:

// Provided by VK_EXT_descriptor_heap
VkDeviceSize vkGetPhysicalDeviceDescriptorSizeEXT(
    VkPhysicalDevice                            physicalDevice,
    VkDescriptorType                            descriptorType);
  • physicalDevice is the physical device from which to query the descriptor sizes.

  • descriptorType is a VkDescriptorType specifying the type of heap descriptor to query the size for.

The return value of this function will be a VkDeviceSize indicating the size in bytes (N) of a heap descriptor with a type equal to descriptorType. When a descriptor of this type is written by vkWriteResourceDescriptorsEXT or vkWriteSamplerDescriptorsEXT, only the first N bytes are written; the rest will not be accessed and can be safely discarded when copying descriptors around. Additionally, those first N bytes are the only bytes that will be accessed when the descriptor is accessed in the shader. N will never be larger than the applicable limits in VkPhysicalDeviceDescriptorHeapTensorPropertiesARM or VkPhysicalDeviceDescriptorHeapPropertiesEXT.

Values returned by this function have other requirements, so for example may not be power-of-two values.

This command is not intended for general use, and is for tools that already take advantage of tighter packing with other similar features (e.g. VK_EXT_descriptor_buffer) to optimize accesses in some cases. Applications can safely ignore this function and are advised to do so, to avoid depending on non-portable packing.

Valid Usage (Implicit)
  • VUID-vkGetPhysicalDeviceDescriptorSizeEXT-physicalDevice-parameter
    physicalDevice must be a valid VkPhysicalDevice handle

  • VUID-vkGetPhysicalDeviceDescriptorSizeEXT-descriptorType-parameter
    descriptorType must be a valid VkDescriptorType value