Настройка производительности OpenGL для пропускной способности геометрии

Это, вероятно, было задано снова и снова, но я не мог найти ничего полезного, так что он снова возвращается...

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

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

Мой первый подход состоял в том, чтобы просто извлечь все из памяти, используя один большой STREAM_DRAW VBO, который оказался слишком медленным. Моя первоначальная мысль заключалась в том, что я, возможно, перегружал автобус (толкал ~ 150 MiB за кадр), поэтому я реализовал схему кэширования, в которой хранится геометрия, недавно используемая для рендеринга объекта в статических VBOs на графической карте, причем каждый VBO хранит пару 100 KiB на пару данных о ценности MiB (хранение большего количества на VBO дает больше рутинного кэша, поэтому здесь есть компромисс). Ниже приведен пример того, как выглядят данные, где все окрашенные в красный цвет выводятся из кэшированных VBOs.

Пример отображаемых данных http://gimaker.users.sourceforge.net/0010.png

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

  • Без кеширования: 1,95 Гц
  • Кэширование с использованием вершинных массивов: 2.0 Гц ( > 75% сетки кэшируется)
  • Кэширование с использованием STATIC_DRAW VBOs: 2,4 Гц

Итак, мои вопросы: как мне ускорить это? То есть:.

  • Какой рекомендуемый формат вершин для получения достойной производительности? Я использую перемеженное хранилище с позициями и нормалями как GL_FLOAT и GL_UNSIGNED_BYTE для цветов, с одним байтом заполнения, чтобы получить 4-байтовое выравнивание (28 байт/общее количество вершин).
  • Может ли помочь использование одного и того же буфера для нормалей для всех моих ящиков (все поля выравниваются по оси, поэтому я могу выделить обычный буфер размером с самой большой кэш-записью и использовать его для всех).
  • Как узнать, какая часть трубопровода является узким местом? У меня нет впечатляющей видеокарты (Intel GM965 с драйверами для Linux с открытым исходным кодом), поэтому я могу достичь своего предела. Сколько можно ожидать от типичного оборудования (интегрированная графика на 2-3 года, современная интегрированная графика, современная дискретная графика)?
  • Любые другие советы о том, как вы справитесь с этим, ловушки и т.д.

Мне не интересны ответы, предлагающие LOD (я уже тестировал это), советы для конкретных поставщиков или использование функций OpenGL от чего-либо позже 1.5.

Ответы

Ответ 1

Вам, вероятно, не понравится этот ответ....

Я нашел вашу проблему: Intel GM965 с драйверами с открытым исходным кодом Linux

Пока моя текущая работа не затрагивает ваш объем данных, мы отобрали несколько миллионов вершин в VBO, а графические аппаратные средства/драйверы Intel оказались бесполезными. Получите себе карту NVidia (и переходите к использованию двоичного драйвера, она просто работает), и все будет готово. Даже не должно быть текущим поколением, хотя верхний конец Quadro (если работа оплачивается) или топ-серии GTX 400 (если вы платите или просто пытаетесь сэкономить несколько долларов на работе) должны делать только штрафы с последними водители. Вы также можете попытаться найти машину с этим оборудованием для проверки, если обновление вашей машины не является вариантом.

Ответ 2

Я бы сначала использовал профилировщик производительности (например, gDEBugger), поэтому вы можете выяснить, ограничены ли вы вершины, фрагменты или шины, и т.д. Невозможно угадать, какие оптимизации выполнять в таком конкретном случае (драйверы с открытым исходным кодом Intel +).

Вы также попробовали режим VA? Используете ли вы glDrawElements? glDrawArrays? Является ли вершинный кеш данных дружественным (pre и post transform)?

Ответ 3

Я не знаю о вашей "сетке", но кажется, что все они кубики. Если это возможно, сделайте единый куб объединения в список отображения и выполните масштабированную версию этого списка отображения. Это часто дает 10-кратное ускорение, поскольку шина не накачивается данными вершин или из-за потери видеопамяти.

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