Zebrafish
Zebrafish

Reputation: 13886

Question about Vulkan minimum buffer alignment

When I allocate and bind memory for a uniform buffer I make sure that it's aligned to the alignment required by whatever struct I am filling that buffer with. So I might have a buffer that holds an array:

struct UniformValues
{
    float value1;
    float value2;
};

layout (set = 0, binding = 0) uniform my_uniform
{
    UniformValues[100];
};

Does the device's "minUniformBufferOffsetAlignment" mean that if it's 16 that I need to pad that uniform struct's size to 16 bytes instead of what it is (likely 8 bytes big)? As it is if I want to either:

  1. Access element 2 in the shader.
  2. Bind element 2 as an offset when binding or writing the descriptor in my host-side code.

Then it won't be a 16-byte-aligned address.

If this is the case how do I pad my struct so that it's big enough for whatever device's minimum buffer alignment is if the device limits is discovered at runtime?

Upvotes: 0

Views: 1882

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473272

The minimum alignment doesn't care about your structs. It cares about the alignment that you give to any UBO descriptor binding offsets. This is about where you put the data in memory, not how the data gets laid out internally.

The thing you appear to be trying to do is that you want to have a bunch of structs contiguous in buffer memory and sub-select a UBO from any range (of some fixed length) from that storage. That's not a thing Vulkan requires that implementations let you do. The minimum offset requirement can forbid such a thing.

That being said, the largest minimum alignment is 256; Vulkan does not allow implementations to advertise larger ones. Since your struct is already 16 bytes in size in std140 (with a 16-byte array stride), your UBO can be specified to start at every 16th element.

Upvotes: 1

Related Questions