Shared interface blocks in GLSL?

Is there any supported method in GLSL to share interface block definitions between UBO or SSBO bindings?

For example, this completely contrived example is valid, but redundant:

layout( binding = 1 ) uniform TexParams
{
    vec4   _a[ 8 ];
    uvec4  _b[ 8 ];

} Tex1UBO;

layout( binding = 2 ) uniform TexParams
{
    vec4   _a[ 8 ];
    uvec4  _b[ 8 ];

} Tex2UBO;

Here’s some invalid GLSL that hints at what I’m looking for:

struct TexParams
{
    vec4   _a[ 8 ];
    uvec4  _b[ 8 ];

};

layout( binding = 5 ) uniform TexParams  Tex1UBO;
layout( binding = 8 ) uniform TexParams  Tex2UBO;

(Yes I realize in this contrived example, I could combine these into a single UBO as an array, but that’s not the point.)

If that “invalid GLSL” is acceptable to you, then it’s not unreasonable to just do this:

layout( binding = 5 ) uniform TexParams1 { TexParams data; }  Tex1UBO;
layout( binding = 8 ) uniform TexParams2 { TexParams data; } Tex2UBO;

But remember: uniform blocks are defined by the block name, not the instance name. You cannot have two blocks with the same block name, as they would be the same block.

However, what makes a lot more sense is to create an array of blocks:

layout( binding = 1 ) uniform TexParams
{
    vec4   _a[ 8 ];
    uvec4  _b[ 8 ];

} TexUBO[2];

This will create two distinct blocks, named (in OpenGL) TexParams[0] and TexParams[1]. These blocks will consume bindings 1 and 2, and you can access them in GLSL through TexUBO[0] and TexUBO[1].

But arrayed blocks cannot be given arbitrary bindings from within GLSL. An array of blocks will consume a contiguous sequence of bindings starting at the given binding index, unless you change the bindings from OpenGL.

1 Like

Thanks for the tip, Alfonse.

That works, but has (for me) the slightly undesirable property of adding a nested scope for the purposes of accessing UBO state in the shader (e.g. Tex1UBO.data._a[0]).

However, cross-refing with the GLSL spec, that’s remedied by using this somewhat awkward syntax, allowing: Tex1UBO._a[0]).

layout( binding = 5 ) uniform TexParams1 { TexParams Tex1UBO; };
layout( binding = 8 ) uniform TexParams2 { TexParams Tex2UBO; };

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