About offset in descriptor heap

Hello,

in https://docs.vulkan.org/refpages/latest/refpages/source/VkDescriptorMappingSourceConstantOffsetEXT.html

shaderIndex = (Binding - firstBinding) + arrayIndex

offset = heapOffset + (shaderIndex * heapArrayStride)

for VkDescriptorMappingSourceConstantOffsetEXT

But, if Binding is 1 and arrayIndex is 1 and firstBinding is 0, shaderIndex is 2

also if Binding is 2 and arrayIndex is 0 and firstBinding is 0, shaderIndex is also 2

the offset calculation is not 1 to 1

So, I don’t understand why shaderIndex is calculated like this

Also, in VkDescriptorMappingSourcePushIndexEXT

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

I don’t understand how it is one-to-one

Could you please explain to me about this VkDescriptorMappingSourceDataEXT ?

Hello, in this struct, there is no member for array length of each binding

Why?

typedef struct VkDescriptorSetAndBindingMappingEXT {
VkStructureType sType;
const void* pNext;
uint32_t descriptorSet;
uint32_t firstBinding;
uint32_t bindingCount;
VkSpirvResourceTypeFlagsEXT resourceMask;
VkDescriptorMappingSourceEXT source;
VkDescriptorMappingSourceDataEXT sourceData;
} VkDescriptorSetAndBindingMappingEXT;

It is written that binding can have aliases

But I don’t know what this says

-=-=-=-

VkDescriptorMappingSourceEXT bindingCount alias

When setting VkDescriptorSetAndBindingMappingEXT, there are firstBinding and bindingCount fields.

The idea is that with a single mapping, you can apply the offsets for multiple bindings within a descriptor set.

For example, imagine the following shader:

layout(binding = 1) uniform sampler2D a[4];
layout(binding = 3) uniform sampler2D b;
layout(binding = 4) uniform sampler2D c;

If the mapping is configured as follows:

VkDescriptorSetAndBindingMappingEXT mapping;
mapping.firstBinding = 1;
mapping.bindingCount = 4; // Covers bindings 1, 2, 3, and 4
mapping.source = VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_CONSTANT_OFFSET_EXT;
mapping.sourceData.heapOffset = 0;
mapping.sourceData.heapArrayStride = 0x10;

Each binding can be viewed as an index into the mapping. The respective offsets for each descriptor are calculated as follows:

  • a[0] = 0x00

  • a[1] = 0x10

  • a[2] = 0x20

  • a[3] = 0x30

  • b = 0x20

  • c = 0x30

Note that both a[2] and b share the same descriptor offset here. This overlapping behavior is completely by design!