将缓冲区绑定到内存时使用正确的偏移量

Use correct offset when binding a buffer to a memory

我有一大块设备内存和多个要绑定的统一缓冲区。显然,我需要一个补偿。让我们看看 vkBindBufferMemory 的文档是怎么说的:

memoryOffset is the start offset of the region of memory which is to be bound to the buffer...

memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer

好的,这很清楚 - 我创建了多个使用相同标志的统一缓冲区,因此我可以对所有缓冲区使用相同的对齐方式。但是等等,规格中还有 vkBindBufferMemory 的另一个用法说明:

If buffer was created with the VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memoryOffset must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment

这很混乱。我可以安全地使用 VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment 来处理我的情况,还是应该将其与 VkMemoryRequirements::alignment 进行比较并选择最低的?

首先,快速说明:如果您想将 VkPhysicalDeviceLimits::minUniformBufferOffsetAlignmentVkMemoryRequirements::alignment 进行比较,那么您应该选择这两个值中的最大值,而不是最低(最小)值。

但在规范中我们还可以看到:

The implementation guarantees certain properties about the memory requirements returned by vkGetBufferMemoryRequirements and vkGetImageMemoryRequirements:

  • The alignment member is identical for all VkBuffer objects created with the same combination of values for the usage and flags members in the VkBufferCreateInfo structure passed to vkCreateBuffer.
  • The alignment member satisfies the buffer descriptor offset alignment requirements associated with the VkBuffer’s usage:
    • If usage included VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, alignment must be an integer multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment.
    • If usage included VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, alignment must be an integer multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment.
    • If usage included VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, alignment must be an integer multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment.

因此您不必比较它们,只需取 VkMemoryRequirements 结构中 vkGetBufferMemoryRequirements() 函数返回的对齐值(的倍数)。

根据以上信息,我认为VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment值在使用动态统一缓冲区时更为重要,因为在vkCmdBindDescriptorSets()函数调用期间提供的偏移值也必须是上述值的倍数值。