Как я могу получить автоматические уникальные точки привязки счетчика атома (нет жестко закодированного привязки =)?

Во многих статьях описывается использование атомных счетчиков путем указания фиксированной точки привязки:

//Shader:
layout(binding = 0, offset = 0) uniform *********** myAtomicCounter;
//App code
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, myBufferHandle);

Здесь точка жесткого кодирования binding = 0 указывается как в шейдерном коде, так и в коде приложения. Я думаю, что эти статьи делают это так, потому что

Атоматическим счетчикам не назначено место и может не быть с помощью команд Uniform*. Связывание, смещения и шаги, принадлежащие атомным счетчикам программного объекта недействительны, а новые назначается после каждой успешной повторной ссылки. [shader_atomic_counters]

Вышеуказанное прекрасно, пока вы не захотите получить более модульный шейдерный код. Например, у меня есть два файла с шейдерным включением, каждый из которых нуждается в атомном счетчике, который я написал как подключаемый код, который не знает о другом. Ясно, что я не хочу указывать жестко закодированные точки привязки, и я бы хотел, чтобы приложение обрабатывало его автоматически. Мне все равно, какие точки привязки они используют, просто они не совпадают.

Атрибуты шейдера вершин похожи. Я могу принудительно привязать место привязки во время выполнения (glBindAttribLocation) до привязки шейдера или, альтернативно, OpenGL выбрать их для меня, а затем запросить результат (glGetAttribLocation). Я также могу выполнить поиск по всем атрибутам (glGetActiveAttrib).

Как я могу реализовать автоматические уникальные точки привязки для атомных счетчиков, поэтому они не жестко закодированы, и я могу комбинировать шейдерный код?

Я вижу несколько способов, которые могут быть возможны, но с ограничением не меняя их после ссылки:

  • Не указывайте точку привязки в шейдере и пусть OpenGL выбирает один при связывании. Я не знаю, сделает ли OpenGL это. Если это так, как вы запрашиваете, чтобы найти используемую точку привязки?
  • Запросить шейдерные объекты перед связыванием, чтобы найти атомные счетчики. Затем дайте им уникальные места привязки так же, как glBindAttribLocation для атрибутов. Есть ли механизм назначения точек привязки?
  • Разбор всего шейдерного кода, поиск атомных счетчиков и замена точек привязки с уникальными индексами в самом коде шейдера, возможно, с использованием макросов #define. Последнее средство. Я действительно не хочу этого делать.
2 ответа

В точке 1: Параметр binding layout для атомных счетчиков не является необязательным.

В точке 2: поскольку binding не является необязательным, нет смысла устанавливать его из кода OpenGL.

Итак, ваш единственный регресс - № 3.


Вы можете запросить для счетчиков атомов с помощью glGetActiveUniform. Затем получите индекс буфера и, наконец, точку привязки:

int atomicCounterIndex;
glGetActiveUniformsiv(programId, count, index, 
 GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX, &atomicCounterIndex);
glGetActiveAtomicCounterBufferiv(programId, atomicCounterIndex, 
 GL_ATOMIC_COUNTER_BUFFER_BINDING, &myBufferHandle)

Это работает с OpenGL 4.2, как указано в документах

licensed under cc by-sa 3.0 with attribution.