Шейдерные ограничения
Я настраивал свой рендеринг для моего ноутбука, у которого есть Radeon HD 3850. У этого чипа есть приличная мощность обработки, но ограниченная пропускная способность памяти, поэтому я пытаюсь переместить больше шейдерной работы в меньше проходов.
Раньше я использовал простую многопроходную модель:
- Свяжите и очистите буфер смешивания FP16 (с буфером глубины)
-
- Только для глубины
- Для каждого света выполните вспомогательный световой проход
- Свяжите backbuffer, используйте буфер смешивания как текстуру
-
- Передача тонального сигнала
В попытке улучшить производительность этого метода я написал новый путь рендеринга, который подсчитывает количество и тип огней для динамической сборки пользовательских шейдеров GLSL. Эти шейдеры принимают все параметры света как униформы и делают все освещение за один проход. Я ожидал столкнуться с каким-то пределом, поэтому сначала проверил его с одним светом. Затем три. Затем двадцать один, без ошибок или артефактов, и с отличной производительностью. Это приводит меня к моим актуальным вопросам:
Можно ли восстановить максимальное количество униформ?
Является ли этот метод жизнеспособным на более раннем оборудовании или более унифицированы?
Если я надаю слишком далеко, в какой момент я получу ошибку? Компиляция шейдера? Связывание программ? Использование программы?
Ответы
Ответ 1
Форма шейдеров обычно реализуется аппаратными средствами как регистры (или иногда путем исправления значений непосредственно в шейдерном микрокоде, например, шейдерах nVidia). Поэтому предел сильно зависит от реализации.
Вы можете получить максимальные значения, запросив GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB
и GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB
для шейдеров вершин и фрагментов соответственно.
Ответ 2
См. 4.3.5 Единый языка затенения OpenGL® характеристики:
Существует ограничение, зависящее от реализации, на объем хранения для униформы, который может использоваться для
каждый тип шейдера, и если это превышено, это приведет к ошибке времени компиляции или времени соединения. единообразный
переменные, объявленные, но не используемые, не учитывают этот предел.
Он будет терпеть неудачу при ссылке или времени компиляции, но не используя программу.
Ответ 3
Как получить максимальное число, поддерживаемое вашей реализацией OpenGL, см. ответ moonshadow.
Для представления о том, где предел действительно для произвольных GPU, я бы рекомендовал посмотреть, какую версию DX поддерживает GPU.
Аппаратное обеспечение уровня DX9:
-
vs2_0
поддерживает 256 vec4. ps2_0
поддерживает 32 vec4.
-
vs3_0
- 256 vec4, ps3_0
- 224 vec4.
Аппаратное обеспечение уровня DX10:
vs4_0/ps4_0
- это минус 4096 констант на постоянный буфер - и вы можете иметь 16 из них.
Короче говоря, маловероятно, что у вас закончится все, что основано на DX10.
Ответ 4
Я думаю, что максимальное количество униформ определяется количеством видеопамяти,
так как это просто переменная. Нормальные переменные на процессоре слишком ограничены вашей ОЗУ?