<p>I know that vertex attributes sourced from vertex buffers in OpenGL need to adhere to the basic alignment requirements of their base types, so e.g. 4 bytes for floats or uints. However, I am unable to find much clear information about the general alignment requirements of vertex attributes beyond (or rather below) that. Or put more concretely, <strong>are byte-sized attributes allowed to be aligned only to byte offsets</strong> (as well as being tightly packed as the only attributes in their buffer)?</p>
<p>There are some claims that each individual attribute should be 4-byte aligned, as in <a href="https://www.khronos.org/opengl/wiki/Vertex_Specification_Best_Practices" rel="nofollow noreferrer">this article from the GL wiki</a>. However, that article looks a little outdated in general and also doesn't really back these claims in any way (or clarify if that is a &quot;should&quot; or a &quot;shall&quot;). I wasn't really able to find something about it in the GL specification, but admittedly haven't read it end-to-end. So <strong>is there any clear statement if individual attributes are allowed to be byte-aligned/packed?</strong> While specific hardware experience would certainly be interesting, a clear yes/no from the spec would be optimal.</p>
<hr />
<p>Now I know such sub-word alignment, even if allowed, might not exhibit the best performance characteristics when compared to bigger chunks. However, performance isn't of the most critical concern here, rather than making the most of the available memory. I also could basically implement such tightly packed attributes myself by just putting them as <code>uint</code>s into an SSBO instead and pulling them myself in the vertex shader with some bit-twiddling on the vertex ID. But it would still be nice for the project workflow if it was reliably doable within the normal GL vertex attribute pipeline.</p>

CC BY-SA 4.0
2023-12-13T13:30:40.540Z
There are two "types" of alignment at play when we talk about vertex attribute alignment. First there is block alignment referring to how the attribute data structure itself is aligned.  Then there is alignment rules for the individual structures and the members inside it. These rules follow layout standards such as std140 or std430. std140 tends to be the most common.  If a block doesn't adhere to these rules, then the compiler adds padding to force adherence to the layout standard.  Where people get into trouble is they don't add similar padding to there data structures when uploading them.
pmw1234
CC BY-SA 4.0
2023-12-13T14:10:54.570Z
@pmw1234 Where do you gather from that attribute data needs to follow `std140` or `std430` alignment rules (afterall, I tell the GL explicitly how my data is layed out)? Assumptions like these are what I would prefer some actual specification sources for. Also, what compiler? There are no shaders or blocks at play here, unless you mean implicit vertex pulling code provided by the driver. If you could be a bit more specific about the terminology here, this might be fleshed out into an answer.
Christian Rau
CC BY-SA 4.0
2023-12-13T22:23:58.700Z
ahhh, I read to much into your question. Under Vulkan while no alignment rules exist per say data tends to get forced to vec4 alignment.  So a vec3 will get loaded into a vec4 register and that last bit of data is lost. Luckily the Vulkan spec lays down the rules pretty clearly. But for OpenGL I haven't seen a spec that lays out the alignment rules clearly. (not that it doesn't exist somewhere...) I bring up vulkan only because both OpenGL and Vulkan use GLSL and they tend to have many similar rules.
pmw1234
CC BY-SA 4.0
2023-12-13T22:34:02.800Z
So what am I trying to say?...While using a lot of small data types is doable they also explode to take up a lot of register space, and can even spill which is bad. Modern versions of glsl  allow component specific assignments. So you can fill every bit of data. But they all tend to be 4 btye in size. So (without documentation to back backup it up) I would suggest packing bytes into a 4 bytes data type and packing those into vec4 sized data. That would minimize register usage and maximize throughput.
pmw1234
<opengl><vertex-buffer-object>
Vertex attribute alignment <4 bytes
Christian Rau
# Vertex attribute alignment <4 bytes

(Asked by: username_0 on 2023-09-22)

I know that vertex attributes sourced from vertex buffers in OpenGL need to adhere to the basic alignment requirements of their base types, so e.g. 4 bytes for floats or uints. However, I am unable to find much clear information about the general alignment requirements of vertex attributes beyond (or rather below) that. Or put more concretely, **are byte-sized attributes allowed to be aligned only to byte offsets** (as well as being tightly packed as the only attributes in their buffer)?

There are some claims that each individual attribute should be 4-byte aligned, as in [this article from the GL wiki](https://www.khronos.org/opengl/wiki/Vertex_Specification_Best_Practices). However, that article looks a little outdated in general and also doesn't really back these claims in any way (or clarify if that is a "should" or a "shall"). I wasn't really able to find something about it in the GL specification, but admittedly haven't read it end-to-end. So **is there any clear statement if individual attributes are allowed to be byte-aligned/packed?** While specific hardware experience would certainly be interesting, a clear yes/no from the spec would be optimal.

---

Now I know such sub-word alignment, even if allowed, might not exhibit the best performance characteristics when compared to bigger chunks. However, performance isn't of the most critical concern here, rather than making the most of the available memory. I also could basically implement such tightly packed attributes myself by just putting them as `uint`s into an SSBO instead and pulling them myself in the vertex shader with some bit-twiddling on the vertex ID. But it would still be nice for the project workflow if it was reliably doable within the normal GL vertex attribute pipeline.

**Tags:** opengl, vertex-buffer-object

> **Comments:**
> **username_1**: There are two "types" of alignment at play when we talk about vertex attribute alignment. First there is block alignment referring to how the attribute data structure itself is aligned.  Then there is alignment rules for the individual structures and the members inside it. These rules follow layout standards such as std140 or std430. std140 tends to be the most common.  If a block doesn't adhere to these rules, then the compiler adds padding to force adherence to the layout standard.  Where people get into trouble is they don't add similar padding to there data structures when uploading them.  
> **username_0**: @username_1 Where do you gather from that attribute data needs to follow `std140` or `std430` alignment rules (afterall, I tell the GL explicitly how my data is layed out)? Assumptions like these are what I would prefer some actual specification sources for. Also, what compiler? There are no shaders or blocks at play here, unless you mean implicit vertex pulling code provided by the driver. If you could be a bit more specific about the terminology here, this might be fleshed out into an answer.  
> **username_1**: ahhh, I read to much into your question. Under Vulkan while no alignment rules exist per say data tends to get forced to vec4 alignment.  So a vec3 will get loaded into a vec4 register and that last bit of data is lost. Luckily the Vulkan spec lays down the rules pretty clearly. But for OpenGL I haven't seen a spec that lays out the alignment rules clearly. (not that it doesn't exist somewhere...) I bring up vulkan only because both OpenGL and Vulkan use GLSL and they tend to have many similar rules.  
> **username_1**: So what am I trying to say?...While using a lot of small data types is doable they also explode to take up a lot of register space, and can even spill which is bad. Modern versions of glsl  allow component specific assignments. So you can fill every bit of data. But they all tend to be 4 btye in size. So (without documentation to back backup it up) I would suggest packing bytes into a 4 bytes data type and packing those into vec4 sized data. That would minimize register usage and maximize throughput.  

---

## 0 answers

