glBufferSubData очень медленно на многих устройствах Android - PullRequest
0 голосов
/ 28 марта 2019

Я запросил около 2M gl буфера для общего доступа и обновил данные для вершины и индекса с помощью glBufferSubData, он отлично работает на моих устройствах iOS. в то время как, когда я тестирую его на своих устройствах Android, он очень очень медленно.

Я нашел несколько заметок на официальном сайте: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferSubData.xhtml

Что на самом деле означает "что рендеринг должен истечь из конвейера, прежде чем хранилище данных может быть обновлено"?

1 Ответ

1 голос
/ 30 марта 2019

Разница в производительности, которую вы видите, скорее всего, не просто разница между iOS / Android, но будет зависеть как от использования вами API, так и от реализации glBufferSubData в драйвере.Не видя больше кода или не зная, какие показатели производительности вы собираете, трудно комментировать дальше.

что означает «что рендеринг должен истечь из конвейера, прежде чем хранилище данных может быть обновлено», действительно означает?

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

Рассмотрим следующий пример.В хорошем случае у нас может быть что-то вроде этого:

  • glBufferSubData в буфер 1 с ABCDE
  • Вызов с использованием буфера 1
  • glBufferSubData в буфер 2 с FGHIJ
  • Отрисовка вызова с использованием буфера 2
  • Буферы подкачки <----- Точка синхронизации, драйвер должен дождаться окончания рендеринга, прежде чем менять буферы </li>

Однакоесли вы перезаписываете тот же буфер, вы получите его вместо этого.

  • glBufferSubData в буфер 1 с ABCDE
  • Вызов с использованием буфера 1
  • glBufferSubData в буфер1, перезаписывается с помощью FGHIJ <----- Точка синхронизации, поскольку драйвер должен убедиться, что буфер завершил использование при первом вызове отрисовки перед изменением данных </li>
  • Вызов с использованием обновленного буфера 1
  • Поменять местами буферы <----- Точка синхронизации, драйвер должен дождаться окончания рендеринга, прежде чем менять местами буферы </li>

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

...