Индексирование вершин в геометрическом шейдере и производительность SSBO - PullRequest
0 голосов
/ 23 марта 2020

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

  1. Запускаем VS -> TCS -> TES -> GS набор шейдерных этапов на нескольких треугольники (пятна). TES / TCS производят дополнительные мозаичные треугольники.
  2. Создайте простой SSBO, состоящий из достаточно большого количества элементов vec4. SSBO будет хранить результат тесселяции, т. Е. Координаты тесселяемых вершин
  3. . Во время прогона 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

Спасибо!

...