Есть некоторые темы по оптимизации, на тему которых предлагаю подискутировать. В случае комментов, просьба писать, например: Тема "А" вопрос "2"
Тема "A".
Смотрю я на quick reference https://www.khronos.org/files/opengl45-quick-reference-card.pdf
1. Перед вершинным шейдером идёт некий Vertex Puller, собственно что это и для чего он нужен? Полагаю, что бы просто собрать в один пакет из всех VBO нужные данные для одной транзакции?
2. Если я вместо VBO для pos, normals, uvs и пр, буду использовать несколько SSBO и в вертексном шейдере буду читать из них, я проиграю в скорости? По идее, что VBO, что SSBO - лежать в global memory и по скорости не должны отличаться или нет?
Тема "Б"
1. У меня много мешей, но все они объединены в один большой VBO. Индексы не использую, не спрашивайте почему, просто считайте, что у каждого вертекса есть уникальные параметры. Так вот, если у меня нет индексов и есть один VBO, рисую через GL_TRIANGLES, есть ли смысл в использование команд glDrawArraysIndirect или же glMultiDrawArraysIndirect, если же достаточно простого одного вызовы glDrawArrays для всего VBO? Есть ли профит по скорости в более современных командах Multi/ Indirect в данном случае? Все параметры, необходимые для рендера, я могу передать через SSBO.
2. Есть ли возможность полностью отказать от вершинного шейдера и скомпилить только с GEOM и FRAG и что бы это работало? Есть ситуации, когда мне вершинный шейдер вообще не нужен, всё генерится в геом. шейдере, параметры через SSBO.
3. Если я в врешинном шейдере поставлю пустую функцию main(), то есть мне он вообще не нужен и я в нём ничего не делаю, будет ли он всё равно жрать ресурсы во время draw call-а ?
-=MASTER=-
в командах Multi/Indirect (как собственно и в glDrawArraysInstancedBaseInstance, на самом деле) есть профит в виде
typedef struct {
uint count;
uint instanceCount;
uint first;
uint baseInstance;
} DrawArraysIndirectCommand;
, позволяющего получать в шейдер идентификатор конкретного меша, используюя для этого glInstanceID, от которого можно потом танцевать при выборе данных из разнообразных массивов юниформов /ssbo и.т.д
Ну и да, ты меши разные с разными параметрами в своем огромном VBO как отличать друг от друга будешь?
nonamezerox
> есть профит в виде
nonamezerox
> uint baseInstance;
nonamezerox
> позволяющего получать в шейдер идентификатор конкретного меша
Смотри с другой стороны. По факту, ты всё равно передаёшь дополнительный буфер с параметрами для каждого меша, а почему бы не сделать то же самое, через SSBO?
Делаешь SSBO, размером с VBO со всеми вертексами, в этом SSBO каждая ячейка имеет простой ID (int) с указателем на второй SSBO, в котором и лежат параметры, материалы или что угодно другое... То есть в шейдере, ты по gl_VertexID узнаешь id вертекса, каждому такому ID соответствует ячейка в SSBO1, а в этой ячейке уже есть ID ячейки в SSBO2, которая уже может содержать полезные данные...
Ты можешь сделать то же самое, что и glDrawArraysInstancedBaseInstance, только без него и полностью кастомно, другое дело, что если делать, как говорю я - тебе придётся для каждого вертекса хранить ID, то есть доп 4 байта, но опять же, если у тебя есть уникальные параметры для каждого вертекса, без этого и не обойтись, да и не большая это цена.
P.S.: протестил SSBO вместо VAO + VBO = полёт нормальный :-) Всё, в топку эти VAO и прочую мутохрень, теперь вершины передаю только через SSBO, для которого пишу smart memory menager :-)
Тема "A". Пункт 2.
Протестил скорости подачи вертексов через VBO и через SSBO, они идентичны!!!
шейдер:
Не считая модели какого - то хрена, там 4000004 верткста для линий, которые рендерятся в чистую, то есть 2000002 линии. AMD Radeon 7850.
(там правда уже линии хреново прорисовываться начинаются, наверное из - за ботлнэка)
Как видно, FPS одинаковый, отличается немного время, ну так оно скачет, да и потом, всё зависит от угла обзора сцены.
Может конечно что - то изменится, если биндить посредствам VAO ещё и нормали, цвета какие - нибуть и с другой стороны так же биндить это отдельными SSBO...Хотя вряд ли, что VBO, что SSBO - лежать в global memory и скорость дуступ одинаковая.
В общем, прощай VBO! Да-здравствует SSBO :-)
P.S.: правда пустой VAO всё равно приходится биндить, иначе отказывается рендерить :-)
-=MASTER=-
> Протестил скорости подачи вертексов через VBO и через SSBO, они идентичны!!!
ты измеряешь филлрейт. ему нет никакого дела, как ты там вертексы передаёшь. если нормально измерить именно скорость передачи атрибутов, то разница будет заметной, хоть и не катастрофической, около 30%.
-=MASTER=-
> там 4000004 верткста для линий, которые рендерятся в чистую, то есть 2000002
> линии
А эти линии тоже разными методами рисуются?
Suslik
> если нормально измерить именно скорость передачи атрибутов, то разница будет
> заметной, хоть и не катастрофической, около 30%.
около 30 процентов в чью пользу? VBO быстрее?
Suslik
> ты измеряешь филлрейт
Хмм, я измеряю время на каждом кадре, отрисовался - щёлк, отрисовался второй - щёлк.. В это время по идее входит все, в том числе и скорости передачи атрибутов, или ты вообще о чём?
Dimich
> А эти линии тоже разными методами рисуются?
не, один вызов glDrawArrays на все линии, один SSBO
-=MASTER=-
> около 30 процентов в чью пользу? VBO быстрее?
>
конечно. у него аппаратный блок, который специально занят распаковкой атрибутов.
> Хмм, я измеряю время на каждом кадре, отрисовался - щёлк, отрисовался второй - щёлк.. В это время по идее входит все, в том числе и скорости передачи атрибутов, или ты вообще о чём?
в том-то и дело, что ты измеряешь всё время рендеринга в сумме, из которого у тебя 10% занимает распакова атрибутов и 90% — fillrate. уже настало время заканчивать задавать глупые вопросы и просто спросить у гугла, что это такое, первая ссылка. чтобы измерить производительность именно передачи атрибутов, нужно как минимум минимизировать площадь рисуемой геометрии на экране, например, отрисовывая все линии в одной точке, нулевого размера или вообще за экраном.
Suslik
> который специально занят распаковкой атрибутов.
Каких атрибутов то? О чём вообще речь? Есть у меня, допустим, два буфера, один с вершинами, а другой с нормалями для каждой из вершин.
Передам я два буфера через SSBO или через VBO, какая разница? Точнее, вот ты говоришь, разница есть, но в чём она заключается, если FPS такой же?
-=MASTER=-
> если FPS такой же?
Он же тебе говорит, что из-за филрейта ты разницу не видишь.
-=MASTER=-
> Каких атрибутов то?
вершинные атрибуты.
-=MASTER=-
> если FPS такой же
я тебе уже сказал, почему он такой же и чем он определяется.
Suslik
> вершинные атрибуты.
что это?
Suslik
> я тебе уже сказал, почему он такой же и чем он определяется.
ладно, с тебя ж правды не добьёшься, говоришь первый линк в гугле? Дай линк, почитаю :-)
Suslik
> конечно. у него аппаратный блок, который специально занят распаковкой атрибутов.
Это смотря у кого, напрмер, на радеонах, начиная с GCN, уже нету. У них прямо в спеке где-то написано было: "мы геройски отхерачили фетч-шейдеры".
Wraith
> Это смотря у кого, напрмер, на радеонах, начиная с GCN, уже нету
толку тогда с VBO вообще? (у меня радеон кстати :-) )
-=MASTER=-
> толку тогда с VBO вообще? (у меня радеон кстати :-) )
Чтобы можно было в разные форматы вершин, совместимые с инпут лейаутом шейдера. Если заводить через константный буфер, его структура фиксирована, т.е. фактически будет только один формат. Но у варианта с CB вроде бы микрокод VS чуть лучше получался, не помню уже.
Тема в архиве.