4

I am looking into OpenGL Uniform Buffer Objects and Shader Storage Buffers. I think the question applies to both of them, but let's just focus on UBOs.

Tutorials seem to be saying that "block index" and "binding point index" are different things, and if I have more than one UBO in a shader, I need to specify the binding index

layout(binding = 0) uniform first_buffer  {...};
layout(binding = 1) uniform second_buffer {...};

I get the impression that the block index is determined by the linker and can be read from glGetUniformBlockIndex, but the binding point index has to be hard-coded with arbitrary distinct binding=N in the layout, and a corresponding glBindBufferBase(GL_UNIFORM_BUFFER, N, ubo_handle), which strikes me as fragile and a nuisance.

What is the difference between a block index and a binding point?

Can I omit the binding=N in the layout? What happens then with glBindBufferBase?

Is this all the same for SSBOs?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
spraff
  • 32,570
  • 22
  • 121
  • 229
  • Think about the block index as the location index of a texture sampler uniform and the binding point is somehow like the texture unit. – Rabbid76 Sep 01 '19 at 07:13
  • See [Difference between glBindBuffer and glBindBufferBase](https://stackoverflow.com/questions/54955186/difference-between-glbindbuffer-and-glbindbufferbase) respectively [Is it safe to use the block index as the binding point for UniformBufferObject, ShaderStorageBufferObjects, etc?](https://stackoverflow.com/questions/25212650/is-it-safe-to-use-the-block-index-as-the-binding-point-for-uniformbufferobject/41276894) and see also [GLSL Tutorial – Uniform Blocks](http://www.lighthouse3d.com/tutorials/glsl-tutorial/uniform-blocks/) – Rabbid76 Sep 01 '19 at 07:19

1 Answers1

2

See OpenGL 4.6 API Core Profile Specification - 7.6 Uniform Variables

Named uniform blocks, as described in the OpenGL Shading Language Specification, store uniform values in the data store of a buffer object corresponding to the uniform block. Such blocks are assigned a uniform block index.

The block index is the "handle" for the active program resource of a shader program. If you have different shader programs with the "same" uniform block, then they may have different buffer indices.

A buffer is bound to the uniform block of a shader program the binding point (e.g. in shader by a Binding point Layout Qualifier). On the one side a uniform block (index) is associated to a binding point and on the other side a buffer is bound to the binding point (by glBindBufferBase). So one buffer can be bound to the uniform blocks of different programs.

While the buffer index is fixed and and can't be changed after the program is linked, the binding point is a dynamic value and can be changed by glUniformBlockBinding. When the program is linked, then the binding point is initialized by 0 or by the value which is set by the Binding point Layout Qualifier.

This principle is the same for a Shader Storage Buffer Object.

Related questions are:

Difference between glBindBuffer and glBindBufferBase
Is it safe to use the block index as the binding point for UniformBufferObject, ShaderStorageBufferObjects, etc?
How do I query the alignment/stride for an SSBO struct?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Can I let OpenGL determine the binding points and query them, instead of specifying them myself? (Like the block index or glGetAttribLocation?) – spraff Sep 01 '19 at 07:56
  • @spraff By default each binding point is 0. You've to set them in shader code (`layout(binding = ...)`) or by [`glUniformBlockBinding`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUniformBlockBinding.xhtml). – Rabbid76 Sep 01 '19 at 07:59
  • What's the rationale for that? It seems to me that once a program is linked, all its binding points can be automatically determined, then queried, so there would be no chance of screwing up the magic numbers. Why isn't it like that? – spraff Sep 01 '19 at 08:01
  • @spraff No, the program resource indices are set when the program is linked. But the binding points are dynamic. You can change the binding points at any time. e.g texture units are binding points, too. – Rabbid76 Sep 01 '19 at 08:02
  • How does that make sense? Once the program is compiled and linked, why would the binding points change? It's not like the code itself changes – spraff Sep 01 '19 at 08:17
  • @spraff You can change the binding point (of a uniform block) by `glUniformBlockBinding`. The binding point qualifier is just like an initialization. By default the initialization is 0, but you can change it by `binding = ` – Rabbid76 Sep 01 '19 at 08:20
  • Thanks for your time and patience, but I'm still confused. Does that mean all uniform blocks are by default initially bound to index 0? And what is the use-case for changing the binding point dynamically? – spraff Sep 01 '19 at 09:14
  • 1
    @spraff No! Did you read the answer and the comments? The index is not the binding point! This are different things. Each uniform block in a single program has its individual resource index, which is set when the program is linked and you don'T have to specify it. The binding point by default is 0 and can be use to bind it to a buffer. It is used to "connect" a uniform block in a linked program to a buffer object. – Rabbid76 Sep 01 '19 at 09:34