Search code examples
openglglslmodularityhardcoded

How can I get automatic unique atomic counter binding points (no hard coded binding=)?


Many articles describe using atomic counters by specifying a fixed binding point:

//Shader:
layout(binding = 0, offset = 0) uniform atomic_uint myAtomicCounter;

//App code
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, myBufferHandle);

Here, the hard coded binding point binding = 0 is specified in both the shader and application code. I guess these articles do it this way because,

Atomic counters are not assigned a location and may not be modified using the Uniform* commands. The bindings, offsets, and strides belonging to atomic counters of a program object are invalidated and new ones assigned after each successful re-link. [shader_atomic_counters]

The above is fine until you want some more modular shader code. For example I have two shader include files, each needing an atomic counter that I've written as pluggable code that doesn't know about the other. Clearly I don't want to specify hard coded binding points and I'd like the application to handle it automatically. I don't really care which binding points they use, just that they aren't the same.

Vertex shader attributes appear similar. I can force a binding location at runtime (glBindAttribLocation) before shader linking or alternatively let OpenGL choose them for me and then query the result (glGetAttribLocation). I can also search through all attributes (glGetActiveAttrib).

How can I implement automatic unique binding points for atomic counters, so they're not hard coded and I can mix shader code?

I can see a few ways this might be possible, still with the limitation of not changing them after linking:

  1. Don't specify the binding point in the shader and let OpenGL pick one when linking. I don't know if OpenGL will do this. If it does, how do you query to find the binding point used?
  2. Query the shader objects before linking to find atomic counters. Then give them unique binding locations just like glBindAttribLocation for attributes. Is there a mechanism to assign binding points?
  3. Parse all the shader code, looking for atomic counters and replace the binding points with unique indices in the shader code itself, perhaps using #define macros. A last resort. I really don't want to have to do this.

Solution

  • On point 1: The binding layout parameter for atomic counters is not optional.

    On point 2: Because binding is not optional, there's no point in being able to set it from OpenGL code.

    So your only recourse is #3.