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


11

Я читал об OpenGL 4.5 Direct State Access (DSA) на opengl.org и не уверен, правильно ли я понимаю.

Кажется, подразумевается, что старый способ менее эффективен:

glBind(something)
glSetA(..)
glSetB(..)
glSetC(..)

чем новый способ:

glSetA(something, ..)
glSetB(something, ..)
glSetC(something, ..)

Судя по всему, теперь каждый glSetдолжен включать в себя glBind(something)его, и если OpenGL по-прежнему является конечным автоматом, он не может использовать преимущества потоковых изменений, примененных к одному something.

Пожалуйста, объясните причины и преимущества нового DSA.

Ответы:


21

Судя по всему, теперь каждый glSet должен включать в себя glBind (что-то)

Не совсем. Это наоборот, как описано в нескольких параграфах ниже.

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

если OpenGL все еще является конечным автоматом, он не может использовать преимущества потоковых изменений, примененных к одному объекту.

Графические процессоры не являются конечными автоматами. Интерфейс конечного автомата GL - это эмуляция, которая оборачивает DSA-подобные драйверы, а не наоборот.

Удаление одного уровня упаковки - уровня, который требует чрезмерного количества вызовов на сервер GL, - это, безусловно, выигрыш, даже если он небольшой.

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

Расширение DSA продолжает формулировать свою работу в терминах изменений состояния, потому что это, в конце концов, расширение существующего документа на основе состояния, а не совершенно новый API, поэтому оно должно быть готово подключиться к существующей спецификации GL язык и терминология документа. Даже если этот существующий язык довольно ужасно подходит для его работы в качестве современного графического аппаратного API.

Пожалуйста, объясните причины и преимущества нового DSA.

Самым большим аргументом является то, что старый способ был болью. Это очень затрудняло составление библиотек, которые могли бы изменять или полагаться на состояние GL. Это затрудняло эффективную упаковку GL API в объектно-ориентированном или функциональном стиле из-за его глубоких процедурных корней управления состоянием, которые затрудняли упаковку API в различные языки, не связанные с C, а также затрудняли создание эффективных оболочек графических устройств. тот абстрактный OpenGL от Direct3D.

Во-вторых, это процедурные издержки API конечного автомата, как описано ранее.

В-третьих, функции DSA изменили семантику, где это было необходимо, по сравнению со старыми API, что позволило повысить эффективность. Например, вещи, которые ранее были изменяемыми, стали неизменяемыми, что удаляет большую часть кода бухгалтерского учета с сервера GL. Вызовы приложения могут отправляться на аппаратное обеспечение или проверяться раньше (или несколькими параллельными модами), когда серверу GL не приходится иметь дело с изменяемыми объектами.

-

Дополнительное обоснование и объяснение даны в спецификации расширения EXT_direct_state_access .

-

Аппаратные изменения, которые имеют отношение к дизайну API, довольно многочисленны.

Помните, что OpenGL датируется 1991 годом. Целевым оборудованием были не видеокарты потребительского уровня (таких не было), а большие рабочие станции САПР и тому подобное. Аппаратные средства той эпохи имели очень разные огибающие производительности, чем сегодня; многопоточность была реже, шины памяти и процессоры имели меньший разрыв в скорости, а графический процессор делал немного больше, чем рендеринг треугольников с фиксированными функциями.

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

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

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

Современное оборудование работает еще дальше от классической модели OpenGL. DSA - это одно небольшое изменение, которое было необходимо около 10+ лет назад (изначально оно было обещано как часть OpenGL 3.0), подобно тому, как это делал D3D10. Многие из вышеперечисленных аппаратных изменений требуют гораздо большего, чем просто DSA, чтобы поддерживать актуальность OpenGL, поэтому доступны еще более крупные расширения, которые кардинально меняют модель OpenGL . Тогда есть целый новый GLnext API плюс D3D12, Mantle, Metal и т. Д., Ни один из которых не поддерживает устаревшую абстракцию конечного автомата.


Спасибо за ответ. Таким образом, кажется, что раньше какой-то конечный автомат (не DSA) был победой, но в какой-то момент что-то изменилось, и теперь DSA является выгодным. Можете ли вы пролить свет на то, что изменилось?
Кромстер

@ KromStern: сделал все возможное. Если вам нужно больше деталей, кто-то более знающий, чем я, должен будет предоставить его.
Шон Мидлдич

@KromStern Я видел (из моего ограниченного исследования истории), что openGL переходит на все меньше и меньше вызовов отрисовки со стороны ЦП на кадр; отображать списки (чего бы они ни стоили), glDrawArrays (рисовать за один вызов), VBO (загружать в GPU один раз), VAO (привязывать буферы к атрибутам один раз), объект единого буфера (устанавливать униформу за один раз). Я уверен, что есть еще кое-что, чего мне не хватает.
фрик с трещоткой

@ratchetfreak: как ни странно, сейчас мы движемся в другую сторону. Современные API-интерфейсы / расширения направлены на увеличение количества вызовов отрисовки на кадр, главным образом за счет удаления всего того состояния, которое должно быть установлено / отправлено за вызов отрисовки, и выполнения вызовов отрисовки чуть больше, чем «вставка команды отрисовки в очередь команд» для большого набор статического состояния и неограниченных ресурсов. Оооо, без привязки, я забыл даже упомянуть эту часть в своем ответе.
Шон Мидлдич

@SeanMiddleditch Я должен был установить вызовы на кадр.
фрик с трещоткой

1

Обзор оправдывает это:

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

Я думаю, что термин «более эффективный» относится как к меньшим затратам на ведение бухгалтерского учета для авторов библиотек, так и к повышению производительности. С текущим API, чтобы «хорошо себя вести», вам нужно запросить состояние, спрятать его, изменить состояние, чтобы сделать то, что вам нужно, а затем восстановить исходное состояние.

подобно

oldState = glGet()
glBind()
glDoThings...
glSet(oldState)  // restore, in case anyone needs it just as they left it

Предположительно, старое оборудование может быть сделано более производительным с явным изменяющим состояние API; в противном случае это довольно странный ритуал. Это расширение подразумевает (и просто посмотрите на список авторов!), Что избегание этого извлечения, установки, восстановления танца теперь больше выигрыша в производительности на текущем оборудовании, даже с дополнительным параметром при каждом вызове.


«нужно запросить / спрятать / изменить / восстановить» - как лучше с DSA?
Кромстер

..добавил псевдокод, чтобы показать. С DSA ничего из этого не нужно. Предположительно текущее оборудование на самом деле не нуждается в состоянии «связывания», может просто получить доступ ко всему этому по мере необходимости.
Дэвид ван Бринк

Цепочка get/bind/do/setиспользуется редко, потому что «Получить» очень медленно. Обычно приложения должны поддерживать реплику переменных в любом случае, поэтому она сводится к простому bind/do. Хотя я вижу смысл.
Кромстер

2
@krom получить из состояния драйвера может быть быстрым, некоторые из состояния gettable не имеют никакого отношения к графическому процессору, поэтому его можно просто получить из оперативной памяти, что быстро.
фрик с трещоткой
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.