4

Suppose that I have one shader storage buffer and want to have several views into it, e.g. like this:

layout(std430,binding=0) buffer FloatView { float floats[]; };
layout(std430,binding=0) buffer IntView { int ints[]; };

Is this legal GLSL? opengl.org says no:

Two blocks cannot use the same index.

However, I could not find such a statement in the GL 4.5 Core Spec or GLSL 4.50 Spec (or the ARB_shader_storage_buffer_object extension description) and my NVIDIA Driver seems to compile such code without errors or warnings.

1 Answers1

4

Does the OpenGL specification expressly forbid this? Apparently not. Or at least, if it does, I can't see where.

But that doesn't mean that it will work cross-platform. When dealing with OpenGL, it's always best to take the conservative path.

If you need to "cast" memory from one representation to another, you should just use separate binding points. It's safer.


There is some official word on this now. I filed a bug on this issue, and they've read it and decided some things. Specifically, the conclusion was:

  • There are separate binding namespaces for: atomic counters, images, textures, uniform buffers, and SSBOs.
  • We don't want to allow aliasing on any of them except atomic counters, where aliasing with different offsets (e.g. sharing a binding) is allowed.

In short, don't do this. Hopefully, the GLSL specification will be clarified in this regard.


This was "fixed" in the revision 7 of GLSL 4.5:

It is a compile-time or link-time error to use the same binding number for more than one uniform block or for more than one buffer block.

I say "fixed" because you can still perform aliasing manually via glUniform/ShaderStorageBlockBinding. And the specification doesn't say how this will work exactly.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Well, one thing that I am interested in is to save binding points for implementations with a low limit. One could for example use one buffer/binding as a dynamically sized struct of arrays by offering different views into it and only accessing non overlapping parts with each view. – Nobody moving away from SE Jan 14 '16 at 16:36
  • @Nobody: Khronos reported back; see the addendum on my post. – Nicol Bolas Jan 29 '16 at 18:36
  • I cannot say much against the official word. However, as I understand it there is already an aliasing problem. After all that's what `restrict` is for, isn't it? – Nobody moving away from SE Feb 01 '16 at 10:22
  • @Nobody: Regular aliasing is like having two pointer variables that happen to point to the same location in memory (or to overlapping locations). That's normal. What you're talking about is having two pointer variables where the *variables themselves* are different names for the same variable. – Nicol Bolas Feb 01 '16 at 13:59
  • I am aware of that but I don't see why they want to disallow aliasing in that way when they already allow it in another way. The only problem that I can see is to declare both `restrict`ed but it would be trivial to detect such errors and it is entirely the developers fault (its the same as using restrict and then use the same buffer). My stance is: I don't see any drawbacks of allowing it so why disallow it. (Obviously, there can be technical limitations that I am not aware of, so my question boils down to: what are the limitations that prevent this?) – Nobody moving away from SE Feb 04 '16 at 13:10
  • @Nobody: "*I am aware of that but I don't see why they want to disallow aliasing in that way when they already allow it in another way.*" I could just as easily pose the reverse question: why should they *allow* it? The only thing this allows you to do is access the same memory in different ways without burning more binding points. That's not a genuinely useful feature. If someone has reference the same binding point twice, the odds are far better that they made a *mistake*, that they meant to use two different units and made a typo. – Nicol Bolas Feb 04 '16 at 14:47