C ++ & DirectX - настройка шейдера - PullRequest
1 голос
/ 04 августа 2010

Кто-нибудь знает быстрый способ вызвать обработку шейдеров через DirectX?

Сейчас я устанавливаю шейдеры с помощью вызовов D3DXCreateEffectFromFile, которые создают шейдеры во время выполнения (по одному на каждый шейдер) из *.fx файлов.

Рендеринг части для каждого объекта ( каждый патч в моем случае - см. Далее ) тогда означает что-то вроде:

// --------------------
// Preprocessing
effect->Begin();
effect->BeginPass(0);
effect->SetMatrix (or Vector or whatever - internal shader parameters) (...)
effect->CommitChanges();

// --------------------
// Geometry rendering

// Pass the geometry to render
// ...

// --------------------
// Postprocessing

// End 'effect' passes
effect->EndPass();
effect->End();

Это нормально, но профилировщик показывает странные вещи - preprocessing (см. Код) занимает около 60% времени (я рендеринг местностиобъект из 256 патчей, где каждый патч содержит около 10 тыс. вершин) .

Фактический рендеринг геометрии занимает ~ 35%, а постобработка - 5% от общего времени рендеринга.

Это кажется довольно страннымЯ и я думаю, что D3DXEffect интерфейс не может быть лучшим решением для такого рода вещей.

У меня есть 2 вопроса:

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

2.Поможет ли компиляция шейдеров как-то улучшить производительность установки параметров?

Может быть, кто-то знает, как решить эту проблему / какой-то реализованный интерфейс шейдера, или мог бы дать несколько советов о том, как эта проблема решается в современномигровые движки.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 05 августа 2010

Фактический рендеринг геометрии занимает ~ 35%, а постобработка - 5% от общего времени рендеринга

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

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

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

и с чего мне начать?

D3DXAssembleShader, IDirect3DDevice9 :: CreateVertexShader, IDirect3DDevice9 :: CreatePixelShader в DirectX 9, D3D10CompileShader в DirectX 10. Также можно загрузить в DirectX 10. Также можно загрузить DirectX 10. SDKчитать документацию / учебники по шейдерам.

Поможет ли компиляция шейдеров как-то улучшить производительность установки параметров?

Шейдеры автоматически компилируются при их загрузке.Вы можете попробовать компилировать с разными настройками оптимизации, но не ожидайте чудес.

2 голосов
/ 04 августа 2010
  1. Я использовал эффекты ранее в DirectX, и система в целом работает нормально.Он предоставляет некоторые приятные функции, которые могут быть проблематичны для реализации себя на более низком уровне, поэтому я бы остановился на этом на данный момент.

    Как предполагает bshields, информация о вашем времени может быть неточной.Похоже, что на самом деле рисование занимает больше всего времени.

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

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

    Я не помню, куда идут вызовы SetParameter, но вы можете проверить документы, чтобы убедиться, чтоSetMatrix находится в правильном месте.Установка параметров после запуска не поможет, конечно, не скорость.Убедитесь, что все настроено правильно.Кроме того, устанавливайте параметры настолько редко, насколько это возможно, есть небольшие накладные расходы.Покадровые наборы дадут вам заметное замедление, если у вас их слишком много.

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

2 голосов
/ 04 августа 2010

Вы используете профилировщик DirectX или просто синхронизируете код своего клиента?Профилирование вызовов API DirectX с использованием таймеров в клиентском коде, как правило, не столь эффективно, поскольку необязательно синхронно обрабатывать обновления состояния / вызовы отрисовки по мере их выполнения.За кулисами происходит много оптимизации.Вот статья об этом для DX9, но я уверен, что это не изменилось для более поздних версий:

http://msdn.microsoft.com/en-us/library/bb172234(VS.85).aspx

...