Я создаю шейдерную программу и среду хоста GL, которая бы выполняла относительно простую задачу:
- Запускаем VS -> TCS -> TES -> GS набор шейдерных этапов на нескольких треугольники (пятна). TES / TCS производят дополнительные мозаичные треугольники.
- Создайте простой SSBO, состоящий из достаточно большого количества элементов vec4. SSBO будет хранить результат тесселяции, т. Е. Координаты тесселяемых вершин
- . Во время прогона GS GS будет записывать вершины треугольника в SSBO таким образом, что отдельные вершины треугольника go с шагом три, т.е.
(triangle1, vert1)
, (triangle1, vert2)
, (triangle1, vert3)
, (triangle2, vert1)
, (triangle2, vert2)
, (triangle2, vert3)
, et c.
Чтобы проиндексировать мой SSBO, мне нужно как-то вывести "triangleID". Я внимательно прочитал спецификации GS / Tess и провел несколько экспериментов. Кажется, что встроенные входы GS просто не имеют его. Похоже, что gl_PrimitiveIDIn ссылается на исходный индекс треугольника, который виден в вершинном шейдере, и он не увеличивается во время тесселяции.
Наконец, я пришел к идее / обходному пути наличия другого SSBO, у которого был бы «примитивный счетчик». "это будет увеличиваться с atomicAdd(primCount, 1)
каждый раз, когда выполняется GS:
layout ( triangles ) in;
layout ( triangle_strip, max_vertices = 3 ) out;
layout(std140, binding = 1) buffer AuxSSBO {
int primCount;
int lock;
int pad2;
int pad3;
};
layout(std140, binding = 2) writeonly buffer TrianglesSSBO {
writeonly vec4 pos[];
};
void main() {
int idx = atomicAdd(primCount, 1);
for (int i = 0; i < 3; ++i) {
gl_Position = gl_in[i].gl_Position;
gl_PrimitiveID = gl_PrimitiveIDIn;
pos[3 * idx + i] = vec4(gl_Position.xyz, 1.0);
EmitVertex();
}
EndPrimitive();
}
Вчера я потратил кучу времени на совершенствование кода выше, так как в пути я получал всевозможные гоночные условия. Теперь, похоже, это помогает моему графическому процессору / драйверу, но я не совсем уверен, что это на 100% правильно.
Итак, мой первый вопрос:
- лучший способ вывести индекс треугольника в моем случае, и является ли код выше racing-cond бесплатным?
Мой второй вопрос касается производительности:
- У меня есть другая реализация моя задача, основанная на объектах и буферах обратной связи преобразования, и я должен сказать, что она работает в 4 раза быстрее (2,0 мс против 0,5 мс на кадр). Интересно, почему бэкэнд SSBO намного медленнее, чем аналог TF, и есть ли что-то, что я могу сделать, чтобы он работал быстрее?
PS Полный код здесь: https://pastebin.com/SagKZEyi
PSS Обновленный код с DrawArraysIndirect () находится здесь: https://gist.github.com/lhog/432af74ba41259e062f18910b5904684
Спасибо!