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

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

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

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

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

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

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

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

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

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

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

person jozxyqk    schedule 03.12.2014    source источник


Ответы (2)


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

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

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

person Nicol Bolas    schedule 14.12.2015

Вы можете запросить атомарные счетчики, используя 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, как указано в документы

person Daniel Bulla    schedule 30.04.2017