描述符动态偏移
Vulkan 提供两种类型的描述符,允许在绑定时调整偏移量,如规范中所定义。
-
动态统一缓冲区 (
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
) -
动态存储缓冲区 (
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
)
示例
此示例将拥有 32 字节的缓冲区,其中 16 个字节将在 vkUpdateDescriptorSets
时设置。 在第一个示例中,我们将不添加任何动态偏移。
VkDescriptorSet descriptorSet; // allocated
VkBuffer buffer; // size of 32 bytes
VkDescriptorBufferInfo bufferInfo = {
buffer,
4, // offset
16 // range
};
VkWriteDescriptorSet writeInfo = {
.dstSet = descriptorSet,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
.pBufferInfo = bufferInfo
};
vkUpdateDescriptorSets(
1, // descriptorWriteCount,
&writeInfo // pDescriptorWrites,
);
// No dynamic offset
vkCmdBindDescriptorSets(
1, // descriptorSetCount,
&descriptorSet, // pDescriptorSets,
0, // dynamicOffsetCount
NULL // pDynamicOffsets
);
我们的缓冲区现在看起来如下所示

接下来,将在绑定时应用 8 字节的动态偏移。
uint32_t offsets[1] = { 8 };
vkCmdBindDescriptorSets(
1, // descriptorSetCount,
&descriptorSet, // pDescriptorSets,
1, // dynamicOffsetCount
offsets // pDynamicOffsets
);
我们的缓冲区现在看起来如下所示

使用 VK_WHOLE_SIZE 的示例
这次,将使用 VK_WHOLE_SIZE
值作为范围。 除了 VkDescriptorBufferInfo::range
之外,一切都与上面的示例相同。
VkDescriptorSet descriptorSet; // allocated
VkBuffer buffer; // size of 32 bytes
VkDescriptorBufferInfo info = {
buffer,
4, // offset
VK_WHOLE_SIZE // range
};
VkWriteDescriptorSet writeInfo = {
.dstSet = descriptorSet,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
.pBufferInfo = bufferInfo
};
vkUpdateDescriptorSets(
1, // descriptorWriteCount,
&writeInfo // pDescriptorWrites,
);
// No dynamic offset
vkCmdBindDescriptorSets(
1, // descriptorSetCount,
&descriptorSet, // pDescriptorSets,
0, // dynamicOffsetCount
NULL // pDynamicOffsets
);
我们的缓冲区现在看起来如下所示

这次,如果我们尝试应用动态偏移,将会遇到未定义的行为,并且验证层会给出错误
// Invalid
uint32_t offsets[1] = { 8 };
vkCmdBindDescriptorSets(
1, // descriptorSetCount,
&descriptorSet, // pDescriptorSets,
1, // dynamicOffsetCount
offsets // pDynamicOffsets
);
这是带有无效动态偏移的样子
