Std430 layout for Uniform Blocks

I was considering (again) the inconvenience of not being able to use the tightly-packed std430 layout with UBOs (uniform blocks) in GLSL, though this is supported for SSBOs (buffer blocks).

So I got to digging…

Vulkan has this capability for its customization of GLSL:

And this extension is supported by the GPUs and GPU drivers I care about:

So how can I get at this in OpenGL? That is:

  • How can I determine in OpenGL whether the GPU + driver supports the std430 block in GLSL shaders?
1 Like

There’s no OpenGL extension for that. It’s purely a Vulkan feature. Just because a GPU can do a thing doesn’t mean that OpenGL offers a mechanism to let you to access it.

At this point, I think it’s reasonable to say that OpenGL as a specification is in maintenance mode. Khronos will fix spec bugs (eventually), but they aren’t spending a lot of time on desktop GL (and probably not a whole lot on ES). My evidence for this is:

  • The exactly zero effort being put into making OpenGL use ray-tracing hardware (rather than the very-non-zero effort being put into the same for Vulkan). Even NVIDIA, God of Making Really Complex OpenGL Extensions Just For Their Hardware basically told everyone that if you have a GL application that needs RTX… just use GL/Vulkan interop.
  • The relative lack of new ARB/KHR extensions for OpenGL (let alone a 4.7 version).
  • The fact that the OpenGL reference pages haven’t even been updated for version 4.6.

So I wouldn’t expect a whole lot of new GL extensions, even if they’re only making old features available.

Ok, thanks for confirming that there’s currently no extension for this (that we’re aware of).

In the interest of encouraging OpenGL developers to write ready-for-Vulkan GLSL shaders, it’d be helpful if Khronos or the vendors would offer a GL extension to allow the std430 layout on uniform blocks. Since the GPUs and core graphics drivers already support it, it’d likely be very low effort.

This would allow:

layout( std430 ) uniform;
layout( std430 ) buffer;

which would avoid wasting a bunch of space in UBOs due to std140s extreme padding of every field and array element to sizeof( vec4 ).

0(119) : error C3009: layout qualifier 'std430', incompatible with 'uniform blocks'

To the extent that this is reasonable to share shaders, given the stark differences in resource models between the two APIs, you can already do that. Vulkan doesn’t require scalar layout, so your shaders that use std140 in OpenGL can be ported to Vulkan just fine. In this regard, Vulkan is a superset of OpenGL’s functionality.

My point being: if you’re writing shader code for an OpenGL engine that will be ported to Vulkan (or will support both OpenGL and Vulkan), it’s absolutely silly and wasteful to have to target std140 packing for UBOs on the C++ side, because you’re going to want to target std430 under Vulkan.

There’s only 64KB of UBO space on some GPUs, and std430 allows you to make more efficient use of it, without code-obfuscating field and vector packing. It also avoids having more needless “#if VULKAN / #if OPENGL” divergence in both the C++ code and the shader code, further encouraging Vulkan portability.

If you’re supporting two APIs and don’t want a lot of #ifdefs and the like, then you support the lowest-common denominator functionality between them. It’s a tradeoff: a minor inefficiency or enhanced code sanity.

I’m not saying that it would be bad if the LCD were higher; I’m just saying that you shouldn’t get your hopes up.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.