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 -V
flag).
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”)