Можно ли разогреть шейдер в фоновом потоке с собственным контекстом?

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

У меня компиляция и линковка шейдеров работает в отдельном потоке с собственным контекстом open-gl. Но я не смог заставить предварительный разогрев шейдеров работать в отдельном потоке (чтобы не было падения производительности при первом использовании шейдера).

Предварительная разминка действительно нигде не упоминается в документации по iOS или OpenGL. Однако оно упоминается в OpenGL ES Analyzer (один из инструментов, доступных при профилировании из xcode). В этом инструменте я получаю предупреждение "Shader Compiled Outside of Prewarming Phase" каждый раз, когда что-то рендерится с помощью шейдера, который не использовался для рендеринга ранее. В "Расширенной детализации" говорится следующее:

"OpenGL ES Analyzer обнаружил компиляцию шейдера, которая не является частью начальной фазы предварительного разогрева. Компиляция шейдеров может быть трудоемкой операцией. Чтобы избежать их, предварительно разогрейте все шейдеры, используемые для рендеринга. Для этого при запуске приложения сделайте предварительный разогрев и выполните вызов отрисовки с каждой из используемых шейдерных программ, используя все настройки состояния gl, с которыми будет использоваться шейдерная программа. Такие состояния, как смешивание, цветовая маска, логические операции, мультизамена, форматы текстур и состояние примитивов точек, могут влиять на компиляцию шейдеров."

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

У меня есть код для предварительного разогрева шейдеров путем рендеринга треугольника нулевого размера перед его первым использованием.

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

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

Удалось ли кому-нибудь заставить предварительный прогрев работать на фоновом потоке?

11
задан Namaste 26 January 2012 в 22:48
поделиться