В чем преимущество использования косвенного рендеринга в OpenGL?

Я читал, что API, такие как glDrawElementsIndirect, glDrawArraysIndirect помогают нам в косвенном рендеринге. Непрямой рендеринг отличается от прямого в том смысле, что параметры визуализации, такие как "количество вершинных атрибутов", "количество экземпляров для рисования", "начало атрибута вершины из объекта буфера" и т.д., Предоставляются в буферном объекте самим графическим процессором, а не предоставляемый ЦП в обратном вызове.

Я понял это. Это также объясняет, что преимущество заключается в том, что он получает визуализацию быстрее, потому что нет взаимодействия с ЦП. Но подождите, не правда ли, что процессор действительно сделал вызов визуализации? Он по-прежнему указал режим рендеринга (GL_TRIANGLES т.д.). Он также может загружать атрибуты вершин.

Таким образом, все первичное усиление косвенного рендеринга объясняется тем, что просто не нужно передавать эти крошечные переменные: "count", "primitive count", "first vertex attribute", "instance count"? Это не имеет большого значения для меня. (Это тоже не меняется)

Ответ 1

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

Скажем, вы используете преобразование обратной связи с геометрическим шейдером. Это означает, что независимо от того, что вы кормили, вы не знаете, что происходит на другом конце, а не до того, как партия закончилась, и вы все равно запросили подсчеты.
Косвенный рендеринг обращается к этому, вам не нужно знать и на самом деле вы не хотите знать. Информация поступает в буферный объект, и GPU может получить к нему доступ без вашего вмешательства.

Это аналогично условному рендерингу. На самом деле вы могли бы пропустить все условное рендеринг, не так ли? Вместо отправки команд в очередь команд, которые, возможно, не будут выполнены (как неэффективно!), Вы можете запустить свой запрос на окклюзию и посмотреть, проходит ли она или нет, а затем решить, отправлять ли те объекты, которые вы хотите нарисовать.
Кроме этого, вы должны дождаться завершения запроса (и, следовательно, предыдущей партии), синхронизации и переноса PCIe, прежде чем принимать это решение. В течение этого времени GPU, вероятно, останавливается, а затем вы еще не настроили правильные буферы/текстуры и представленные команды. В действительности, поэтому гораздо эффективнее спекулятивно отправлять команды и позволять драйверу/графическому процессору решать, отбрасывать ли их или рисовать.

Это также идея ARB_query_buffer_object, которая позволяет читать результат запроса в объект-буфер.

РЕДАКТИРОВАТЬ:
Кроме того, косвенный рендеринг позволяет значительно повысить эффективность отправки пакетов команд рендеринга (особенно в сочетании с персистентными сопоставлениями), что может привести к тому, что большинство или все синхронизация сервера/клиента и процессора/графического процессора обычно присутствует и может появляться из другого ядра процессора и сохраняет per-drawcall фиксированные накладные расходы. См. Страницы 62 в разговоре Касса Эверетта.

Ответ 2

При прямом рендеринге ЦП занят подготовкой и потоковой передачей данных индекса из собственной памяти по шине с ограниченной пропускной способностью на GPU. Он должен проверить состояние GPU и синхронизировать с ним. Каждый из этих шагов занимает много времени.

Использование косвенного рендеринга всего процессора делает отправку одной короткой команды, которая запускает большую операцию рисования. Это экономит пропускную способность шины. И поскольку GPU будет работать в течение более длительного промежутка времени, там меньше прерываний, которые заставляют CPU останавливать все, что он делает прямо сейчас (контекстный переключатель), а это означает, что сложные числовые задачи, такие как физическое моделирование, будут исполнять более эффективные.