nikitablack
nikitablack

Reputation: 4663

Use correct offset when binding a buffer to a memory

I have a big chunk of device memory and multiple uniform buffers which I want to bind. Obviously, I need an offset. Let's see what the documentation for vkBindBufferMemory says:

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

Ok, that's clear - I have multiple uniform buffers created with the same flags so I can use the same alignment for all of them. But wait, there's another usage note for vkBindBufferMemory in specs:

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

That's confuing. Can I safely use VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment for my case or should I compare it with VkMemoryRequirements::alignment and choose the lowest?

Upvotes: 4

Views: 2008

Answers (1)

Ekzuzy
Ekzuzy

Reputation: 3437

First, a quick note: if You want to compare VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment with VkMemoryRequirements::alignment then You should choose the largest of these two values, not the lowest (smallest) value.

But in the spec we can also read:

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.

So You don't have to compare them but only take the (multiple of the) alignment value returned by the vkGetBufferMemoryRequirements() function in the VkMemoryRequirements structure.

Based on the above information, I think that VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment value is more important when using dynamic uniform buffers as the offset value provided during the vkCmdBindDescriptorSets() function call must also be a multiple of the above value.

Upvotes: 5

Related Questions