Можете ли вы предварительно подогреть шейдер в фоновом потоке с собственным контекстом? - PullRequest
11 голосов
/ 10 января 2012

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

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

Предварительное нагревание действительно не упоминается нигде в документах iOS или OpenGL. Это, однако, упоминается в OpenGL ES Analyzer (один из инструментов, доступных при профилировании из xcode). В этом инструменте я получаю предупреждение «Скомпилированный шейдер вне фазы предварительного нагрева» каждый раз, когда что-то отображается с помощью шейдера, который раньше не использовался для рендеринга чего-либо. «Расширенная деталь» гласит:

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

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

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

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

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

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

1 Ответ

9 голосов
/ 24 января 2012

Честно говоря, до вчерашнего дня я был совершенно неосведомлен об этом, хотя некоторое время работал над оптимизацией своего двигателя.Итак, прежде всего, спасибо за совет:).

С тех пор я изучал тему потепления шейдеров и не нашел много вокруг.

Я нашел упоминание официальногоДокументация AMD в документе под названием «Руководство по программированию и оптимизации ATI OpenGL»:

http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=6&ved=0CEoQFjAF&url=http%3A%2F%2Fdeveloper.amd.com%2Fmedia%2Fgpu_assets%2FATI_OpenGL_Programming_and_Optimization_Guide.pdf&ei=3HIeT_-jKYbf8AOx3o3BDg&usg=AFQjCNFProzLiXf5Aqqs4jZ2jOb4x0pssg&sig2=6YV7SVA97EFglXv_SX5weg

Вот отрывок, который относится к потеплению шейдеров:

Цитата:

Хотя R500 изначально поддерживает управление потоком в блоке затенения фрагментов, ASIC R300 и R400 этого не делают.Статическое управление потоком для R300 и R400 эмулируется драйвером, который формирует неиспользуемые условия и циклы развертывания на основе заданных констант.Несмотря на то, что семейство AS500 R500 изначально поддерживает управление потоком, драйвер все равно будет пытаться компилировать статические условия потока, позволяя ему реорганизовать команды шейдера для лучшего планирования команд.Драйвер также попытается кэшировать скомпилированный шейдер для определенного статического условия потока, установленного в ожидании его повторного использования.Поэтому при написании фрагментной программы, в которой используется статическое управление потоком, рекомендуется «подогревать» кэш шейдера, визуализируя фиктивный треугольник в самом первом кадре, который использует общие статические условные перестановки, относящиеся к жизни шейдера.

Лучшее объяснение, которое я нашел вокруг, таково:

http://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part-1/

Цитата:

Кстати, это также причина, по которой вы часто будете видетьзадержка при первом использовании нового шейдера или ресурса;большая часть работы по созданию / компиляции откладывается драйвером и выполняется только тогда, когда это действительно необходимо (вы не поверите, сколько неиспользуемой ерунды создают некоторые приложения!).Графические программисты знают другую сторону истории - если вы хотите убедиться, что что-то действительно создано (в отличие от просто зарезервированной памяти), вам нужно выполнить фиктивный вызов отрисовки, который использует его для «разогрева».Ужасно и раздражающе, но это имело место с тех пор, как я впервые начал использовать 3D-оборудование в 1999 году. Это означает, что к этому моменту это в значительной степени факт жизни, так что привыкните к нему.:)

В этой презентации упоминается, как механизм cryteck выполнял его на механизме удаленного доступа, хотя в основном он связан с DirectX.

http://www.powershow.com/view/11f2b1-MzUxN/Far_Cry_and_DirectX_flash_ppt_presentation

Iнадеюсь, что эти ссылки каким-то образом помогут.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...