2015-01-11 1 views
0

Я читал, что лучший способ оптимизации порядка рендеринга непрозрачных объектов в OpenGL 2 (особенно ES) заключается в том, чтобы уделить приоритетное внимание избеганию изменений контекста (привязка разных буферов, шейдерных программ и т. Д.) К сортировке по глубине.Вызывает glBindBuffer, glUseProgram и т. Д. С теми же значениями, что и раньше, неэффективными?

Если вы делаете что-то вроде вызова glBindBuffer с уже привязанным буфером или glUseProgram с шейдерной программой, которая уже является текущей программой и т. Д., Будут ли они по-прежнему вызывать неэффективный конвейерный поток или библиотеки, достаточно умные для распознавания их как НООП? Это упростит мой код, если я могу просто привязать все в тот момент, когда это необходимо, не заставляя следить за тем, что уже связано, и проверять его.

ответ

2

Возможно. На это вообще нельзя ответить. Это полностью зависит от реализации.

Должны ли водители проверять избыточные изменения состояния, это несколько философская дискуссия, и вы не найдете консенсуса по этому вопросу. Поэтому вы должны ожидать, что разные поставщики будут обрабатывать его по-разному, и я даже не обязательно буду считать, что он обрабатывается последовательно для всех состояний в одном и том же драйвере.

Если вы ориентируетесь на определенные платформы, вы должны его измерить. К счастью, это довольно легко проверить. Если вы хотите охватить широкий спектр платформ/поставщиков, я бы минимизировал избыточные изменения состояния. По крайней мере, если у вас есть возможность сделать это относительно дешево. Если вы добавите много накладных расходов для этого, вы можете принести больше вреда, чем пользы.

Основная причина, по которой есть смешанные мнения по этому поводу, заключается в том, что проверка избыточных изменений состояния не является полностью бесплатной. Если драйвер делает это, накладные расходы распространяются на всех. Так что хорошо написанные приложения (которые не делают ненужных изменений состояния) платят за оптимизацию, которая приносит пользу плохо написанным приложениям. То, что вы могли бы спорить, очень несправедливо.

В действительности эти проверки часто выполняются, особенно если изменение состояния довольно дорого. Конечно, не стоит добавлять проверку, если изменение состояния очень дешево. Проверки часто будут определяться оптимизацией производительности для важных тестов приложений/игр. К сожалению, многие приложения/игры используют OpenGL очень неэффективно, и драйвер должен обеспечить наилучший результат для важных тестов. Фильтрация избыточных изменений состояния является общей оптимизацией в этих случаях.

0

Каждый наш вызов glBindBuffer или glUseProgram и т. Д. Создают объект команды в очереди. Эта очередь будет выполнена на gpu через некоторое время. И здесь есть 2 узких места. 1) Чтобы создать командный объект в очереди, наш код должен перейти в режим ядра к драйверу. В общем, эта операция имеет некоторое отставание. 2) GPU будет выполнять нашу команду один за другим, а для проверки того, что буфер уже связан, GPU должен читать и декодировать команду.

Чтобы избежать второго драйвера, необходимо отслеживать текущее состояние, и я думаю, что драйверы opengl не делают этого.