Повторные изменения состояния в Opengl - PullRequest
4 голосов
/ 21 сентября 2011
   Its a fact that state changes in Opengl leads to performance degradation. 

// Скажем, если я вызываю glEnable (GL_DEPTH_TEST) / glBlendFunc несколько раз в каждом кадре.

РЕДАКТИРОВАТЬ:> Здесь я просто хочу сказать, "некоторые изменения состояния, такие как это, изменения состояния вызывают проблемы производительности"

Кто-нибудь может объяснить, пожалуйста, причину этого в деталях?

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

Ответы [ 3 ]

17 голосов
/ 21 сентября 2011

Действительно, изменения состояния могут быть причиной снижения производительности.Однако важный вопрос, который нужно задать: «Какое государство».Некоторые изменения состояния настолько дешевы, что просто не имеет смысла отслеживать их, чтобы свести к минимуму их использование.

В современных реализациях OpenGL glEnable / glDisable практически не имеют снижения производительности (конечнонекоторые включенные / отключенные состояния имеют большое влияние на производительность рендеринга в целом.)

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

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

Еще одно дорогое изменение состояния - это переключение шейдеров.Переключение шейдера негативно влияет на графический процессор двумя способами: во-первых, он заставляет процессоры полностью останавливаться, сбрасывая конвейер их выполнения.Заправка трубопровода до тех пор, пока все работает "как по маслу", занимает несколько сотен циклов.Другая проблема заключается в том, что разные шейдеры имеют разные схемы исполнения и доступа к данным.Шаблоны выполнения определяются единицами предсказания кодового пути, чтобы оценить, какие операции должны быть выполнены наиболее вероятно.Это также означает, что нужно знать, какие данные предварительно выбрать.Переключение шейдера уничтожает эту важную информацию.

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

1 голос
/ 21 сентября 2011

Я считаю, что glEnable(GL_DEPTH_TEST) не приведет к значительному снижению производительности.

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

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

0 голосов
/ 21 сентября 2011

Вы должны включить некоторое состояние opengl, только если вы сначала отключили его. Поэтому нет необходимости вызывать glEnable(GL_DEPTH_TEST) или glBlendFunc каждый кадр, если вам не нужны такие изменения

...