Можно ли изменить размер VBO на месте? - PullRequest
11 голосов
/ 31 августа 2011

В заголовке написано все, но для ясности я добавлю несколько дополнительных слов.

В этом случае resize означает:

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

РЕДАКТИРОВАТЬ

Как объяснить некоторые дополнительные детали и обосновать мой вопрос:Я буду хранить данные (заранее) неизвестного размера в VBO, но я знаю только верхний предел, который является очень грубой оценкой (в 10 - 100 раз больше или даже больше в необычных условиях).

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

Вот почему я нене хочу копировать (особенно не на стороне процессора):Я делаю все это на GPU, чтобы получить интерактивную частоту кадров.Когда мне приходится копировать, это очень медленно или даже невозможно, потому что не хватает места.Наихудшим из всех является копирование данных через ЦП, следовательно, передача всего по шине в новую область памяти, которая имеет достаточный размер, затем glBufferData с использованием VBO с новым размером и новой области памяти в качестве источника.Это было бы убийцей производительности.

обойдено

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

Ответы [ 3 ]

7 голосов
/ 21 января 2015

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

Копирование на GPU

Расширение, упомянутое в ответе Кристиана Рау, является основным начиная с версии 3.1, что позволяет нам копировать содержимое (через glCopyBufferSubData ) из одного VBO в другое. Надеюсь, драйвер сделает это на стороне графического процессора!

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

Истинное изменение размера

Хорошая новость: с разреженными буферами на горизонте еще лучшее решение.

Учитывая это расширение, мы можем выделить виртуальный буфер с более чем достаточным пространством для наших данных, даже не заплатив за ненужное пространство. Нам нужно только «зафиксировать» те области памяти, в которых мы физически хотим хранить данные. Это означает, что мы можем «увеличить» VBO, фиксируя новые страницы в конце.

Плохая новость: в текущей версии OpenGL (4.5) это все еще расширение, а не ядро, поэтому принятие этого может быть невозможным. Не следует также указывать, что в спецификации есть некоторые детали, которые еще не разработаны. Например, отображение разреженных буферов запрещено в текущем расширении, но поддержка может быть добавлена ​​в будущих версиях.

Я бы хотел услышать о наличии этого расширения, если у вас есть какие-либо данные об этом.

7 голосов
/ 31 августа 2011

Я думаю, что без создания копии вы не сможете обойти это, потому что единственный способ изменить размер буфера - вызвать glBufferData, и у IMO нет способа сообщить драйверу о сохранении старых данных.

То, что вы, вероятно, можете сделать, чтобы, по крайней мере, не копировать его в ЦПУ и обратно, - создать какое-то вспомогательное VBO для этих целей и напрямую скопировать из VBO во вспомогательное VBO (используя ARB_copy_buffer extension), измените размер VBO и скопируйте его содержимое обратно.

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

0 голосов
/ 12 марта 2013

Если у вас есть поддержка недавнего стандарта OpenGL, альтернативой VBO может быть хранение ваших данных в текстурах (опять же, при условии, что на вашей карте достаточно памяти).Копирование данных между старой и новой текстурами будет происходить на карте и не повлиять на передачу данных.

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

...