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 descriptors to a host address, with the application responsible for transferring those descriptors into device memory for access via heaps.

vkWriteSamplerDescriptorsEXTWrite sampler descriptors to memory
vkWriteResourceDescriptorsEXTWrite resource descriptors to memory
VkResourceDescriptorInfoEXTStructure describing a resource descriptor
VkResourceDescriptorDataEXTUnion specifying resource descriptor types
VkTexelBufferDescriptorInfoEXTStructure describing an image descriptor created from a buffer
VkImageDescriptorInfoEXTStructure describing an image descriptor created from an image

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.

vkCmdBindSamplerHeapEXTBinds a sampler heap to a command buffer
vkCmdBindResourceHeapEXTBinds a resource heap to a command buffer
VkBindHeapInfoEXTStructure describing a device address range and implementation reservation for a descriptor heap
SamplerHeapEXTPointer to the sampler heap
ResourceHeapEXTPointer to the resource heap

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:

vkCmdPushDataEXTUpdate the values of push data
VkPushDataInfoEXTStructure specifying a push data update operation

Push Data Banks

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

VkPushConstantBankInfoNVStructure specifying push constant bank information

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.

VkShaderDescriptorSetAndBindingMappingInfoEXTStructure specifying mappings from shader resources to descriptor heaps
VkDescriptorSetAndBindingMappingEXTStructure specifying mappings from a set of shader resources to a descriptor heap
VkSpirvResourceTypeFlagBitsEXTBitmask specifying different SPIR-V resource declarations
VkSpirvResourceTypeFlagsEXTA bitmask of VkSpirvResourceTypeFlagBitsEXT values
VkDescriptorMappingSourceEXTSpecifies the mapping source for a shader binding
VkDescriptorMappingSourceDataEXTUnion descriptor mapping source information
VkDescriptorMappingSourceConstantOffsetEXTStructure specifying mapping resources to a constant heap index
VkDescriptorMappingSourcePushIndexEXTStructure specifying mapping resources to a heap index in push data
VkDescriptorMappingSourceIndirectIndexEXTStructure specifying mapping resources to a heap index in indirect data
VkDescriptorMappingSourceIndirectIndexArrayEXTStructure specifying mapping resources to a heap index array in indirect data
VkDescriptorMappingSourceHeapDataEXTStructure specifying mapping a uniform buffer to heap data
VkDescriptorMappingSourceIndirectAddressEXTStructure specifying mapping a uniform buffer to an address specified indirectly
VkDescriptorMappingSourceShaderRecordIndexEXTStructure specifying mapping resources to a heap index in shader record data

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.

vkGetPhysicalDeviceDescriptorSizeEXTReport specific descriptor sizes for each descriptor type