Как выбрать между GL_STREAM_DRAW или GL_DYNAMIC_DRAW? - PullRequest
27 голосов
/ 27 ноября 2011

Я использую OpenGL ES 2.0, но я думаю, что это также относится и к не-ES: как узнать, какое «использование» выбрать при создании VBO?

Этот конкретный VBO будет использоваться для 1до 4 раз до полного обновления, и я не уверен, должен ли я выбрать GL_STREAM_DRAW или GL_DYNAMIC_DRAW.

Ответы [ 4 ]

21 голосов
/ 11 апреля 2014

Ну, в соответствии с OpenGL API вы должны использовать DYNAMIC_DRAW .

STREAM
Вам следует использовать STREAM_DRAW, когда содержимое хранилища данных будет изменено один раз и использовано самое большее несколько раз.

СТАТИЧЕСКИЕ
Используйте STATIC_DRAW, когда содержимое хранилища данных будет изменено один раз и использовано много раз.

DYNAMIC
Используйте DYNAMIC_DRAW, когда содержимое хранилища данных будет неоднократно изменяться и использоваться много раз.

Обязательно обновите VBO с помощью glBufferSubData ()

11 голосов
/ 27 ноября 2011

Флаг использования является подсказкой, а не принуждением.Или другими словами: вещи не ломаются, если вы используете «неправильный» флаг.Поэтому я предлагаю вам попробовать все 3: STATIC_DRAW, STREAM_DRAW и DYNAMIC_DRAW и выбрать тот, который дает вам наилучшую производительность - и очень вероятно, что они будут связывать.

7 голосов
/ 12 апреля 2014

Помимо ответов, которые были даны до сих пор, и хотя это не имеет прямого отношения к GLES, я бы хотел вставить этот бит из выпуска 2 расширения ARB_buffer_storage (вводится вместе с рабочим столом GL 4.4) :

2) Новые флаги не отображаются напрямую на параметр для glBufferData и одно не может быть выражено в терминах другого. Есть ли это имеет значение?

Большинство приложений ошибаются usage, и в любом случае они только подсказки. флаги - это жесткие и быстрые правила, которые необходимо соблюдать. Они служат различное назначение. Идея здесь состоит в том, чтобы позволить реализации не придется угадать приложение и выполнить меньше отслеживания, и для приложения, чтобы иметь больше контроля. Мы определяем BufferData в условия BufferStorage с наиболее либеральными разрешенными флагами (по сути, все идет), но все же передать подсказку реализация, чтобы позволить ему продолжать угадывать применение.

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

Драйвер GL рабочего стола Nvidias в профиле отладки напечатает некоторые решения, которые он принял для объектов буфера, особенно если они хранятся в оперативной памяти клиента или непосредственно в графическом процессоре. При игре с этим я получил следующее:

Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in HOST memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in VIDEO memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in HOST memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in SYSTEM HEAP memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).

Здесь я использовал PBO для потоковой передачи обновлений текстуры в графический процессор, с одним обновлением на кадр через отображение буфера. Естественным выбором здесь будет использование GL_STREAM_DRAW, но я указал GL_STATIC_DRAW. Драйвер сначала дал мне некоторый буфер с резервной копией VRAM и сделал отображение ввода / вывода для первых двух обновлений, которые я сделал. Но затем он передумал и использует буфер, поддерживаемый клиентом, - давая мне именно тот результат, который я получил бы, если бы сначала попросил GL_STREAM_DRAW. То, что мы видим здесь, является примером для second guessing, о котором цитировался текст выше.

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

1 голос
/ 24 февраля 2013

Для IOS информация о VBO здесь на сайте разработчика Apple. Согласно их документам GL_DYNAMIC_DRAW and GL_STREAM_DRAW are equivalent.

Но я думаю, что ваше решение более близко к GL_DYNAMIC_DRAW, так как GL_DYNAMIC_DRAW is for vertex buffers that are rendered many times, and whose contents change during the rendering loop.

...