I have experienced a great deal confusion about the alignment of
uniform structs in GLSL bound to a Vulkan pipeline. For context, note that throughout I am using Vulkan 1.3 and the latest version of
glslangValidator to compile GLSL to SPIR-V (using the
I had assumed (it now appears mistakenly) that all structs bound this way would adhere to the binary layout described by the Vulkan spec here (). The spec explicitly states that the
Uniform storage class (which I assumed corresponded to the
uniform struct in GLSL but later started to question) uses the “scalar” alignment rules (this effectively means “packed” in most cases) for GPU’s with the
scalarBlockLayout attribute (which mine has). This conforms with my intuition and expectations as it usually matches the layout of C and C++ structs and does not require any padding to be inserted into array buffers which should match the native array layout of nearly all languages.
I quickly observed that this was not the layout actually being used, but only corresponded to it in some special cases (e.g. 4\times 4 matrices). By trial and error I determined that, for example, 2\times2 matrices require padding of the columns.
On later investigation I found that this page () in the OpenGL wiki states that
uniform cannot use the
std430 layout which the Vulkan spec claims to be describing. For the hell of it I tried explicitly annotating my block as
std430 and it indeed gives an error message informing me that I’m not allowed to do that for
uniform. I started adding the
std140 annotation which should guarantee that it matches the layout described in the OpenGL spec (). So far this seems to work.
So, in summary, I think I have found that when compiling for Vulkan
uniform block types use a format described in the OpenGL spec, while I still assume
buffer and other struct types use a format that matches what I am seeing in the Vulkan spec.
I would like to verify from anyone who would be kind enough to confirm that I am understanding this correctly, but I also feel like I’m still missing something because of the Vulkan specs explicit mention of
Uniform blocks. My current theory is that
Vulkan is that the Vulkan spec is describing SPIR-V but that the relationship between GLSL abstractions and the underlying SPIR-V output is far less obvious than I had assumed. Any additional context to clarify the situation would be appreciated. Thanks.
(Note: I had originally included a lot of helpful links but discourse is telling me “you can’t include links in your post”)