Форум программистов » Программирование
DirectX SDK, new vs old
(11 posts)-
Помогите плз разобраться. Есть проект, который юзает DX SDK аж 2004 года (это как раз dx 9.0c вышел с ps 3.0), и в нем юзается функция D3DXCompileShaderFromFile, и вот мне интересно где она находится (то есть её реализация).
Насколько я знаю в новых sdk эта функция лежит в d3dx9_xx.dll (правильно?), а в том старом sdk - эта функция походу лежит в d3dx9.lib и она прикомпиливается в .ехе, то есть
реализация находится даже не в DLL а в .lib. Так как в свежей XP винде (где еще dx не ставили) никаких d3dx9.dll и тем более d3dx9_xx.dll нет.
То есть, получается что это мое приложение юзает компилятор шейдеров аж 2004 года, так?!? И тогда должно быть так, что с новым sdk откомпиленные шейдеры (новым компилятором) - возможно быстрей будут работать (на новых видеокартах)? Я думаю там не мало должно было поменяться в компиляторе за ~5 лет...
И может, кто имел практику перехода со старых DX SDK на новые - не будет ли проблем? (версии используемых у меня DX-компонентов будут те же). -
dx 9.0c і dx 9.0 - то ж різні версії. При переході з одного на інший великих проблем не має бути. Якщо перейдеш на новішу версію SDK (dx 9.0c) то і в юзера має бути та версія DirectX, щоб проект запустився.
На рахунок того чи будуть швидще компілитися шейдери і т.д. В SDK всьо написано що нового добавили, що змінилося. -
Перешел на новый SDK, никаких проблем, проект скомпилился с первого раза без единой ошибки.
И вроде как шейдеры пошустрее стали отрабатывать, но не все.. кроме одного(!), самого главного.
Теперь приложение выдает в два раза меньше fps из-за одного шейдера :(
Прийдется теперь долго разбираться почему так, а то и на старой версии sdk может прийдется остаться. -
Прийдется теперь долго разбираться почему так, а то и на старой версии sdk может прийдется остаться.
Не загружаешь все ALU и самплеры полностью.
Берешь под свою видюху тулзу и смотришь, где bottleneck:
Intel GPA: http://software.intel.com/en-us/articles/intel-gpa/
nVidia PerfHUD: http://developer.nvidia.com/object/nvperfhud_home.html
ATI/AMD ShaderAnalyzer: http://developer.amd.com/gpu/shader/Pages/default.aspx -
Да, и не делай универсальных pixel/fragment shader'ов, лучше иметь 100 штук под каждый случай жизни, чем 1 универсальный.
-
Mike Gorchak
Не загружаешь все ALU и самплеры полностью.
Берешь под свою видюху тулзу и смотришь, где bottleneckДа возможно, хотя я так изначально думал про старый компилятор, а тут новый и так напортачил..
Вот все собираюсь дотянуться до PerfHUD, наверное сегодня таки дотянусь..Да, и не делай универсальных pixel/fragment shader'ов, лучше иметь 100 штук под каждый случай жизни, чем 1 универсальный.
Та тут не все так просто, юзается Deferred shading, и бочит как раз главный шейдер который собирает MRT и делает освещение.
И там уже нечего менять/оптимизировать, и не разбить на мелкие куски; ну разве что менять архитектуру :)
Если в начале этого шейдера ставить return "что-то" - и потихоньку его сдвигать вниз (то есть, постепенно добавлять операций на выполнение) - можно наблюдать
как проседает fps на достаточно простых операциях типа умножения, деления; и это на GF GTX 285! Наверное нужно будет сравнить ассемблерный аутпут
старого компилера и нового, сдается мне что новый компилер с этим шейдером какую-то лажу генерит.
И повторюсь, что со старым sdk этот шейдер прекрасно работает. -
Та тут не все так просто, юзается Deferred shading, и бочит как раз главный шейдер который собирает MRT и делает освещение.
А у Render Target'ов формат какой ? Хотя от компилятора это врядли зависит, но может перед записью в MRTs происходит постоянное конвертирование int32 -> float16 -> float32, или что-то подобное ... PerfHUD скажет :)
-
Формат следующий: три RT: D3DFMT_A8R8G8B8 (цвет), D3DFMT_A2B10G10R10 (нормаль), D3DFMT_R32F (глубина).
Да, кстати запись в MRT происходит нормально (то есть, по времени, как и ожидаю). Еще утром провел некие исследования (сейчас нет доступа к проекту):
весь рендер (а он не так прост, юзаются еще дополнительные аккумулирующие RT, постпроцессинг, разные материалы) дает 90 фпс с новым sdk, и ~200 со старым.
Отключаю использование этого проблемного шейдера освещения (то есть, тупо коментарю код который собирает MRT и делает освещение) - с новым sdk 350 фпс, со старым 290.
То есть, выходит что не считая этого проблемного шейдера - польза от нового sdk ощутима и она есть, как только юзается проблемный шейдер - эта польза сводится на нет и приложение замедляется в ~2 раза (по сравнению со старым sdk). В общем, сегодня вечером буду "разбирать" этот шейдер по кускам пока не пойму в чем дело.ps. Проект в DX Debug (с макс. уровнем дебага) не выдает ни одного эрора в output.
-
В общем, скомпилил я свой шейдер старым fxc.exe и новым, посмотрел в ассемблер и стало мне грустно...
Мне кажется, реальный ход событий был примерно таков: в 2004 году видеокарты были довольно слабые (относительно ~современных), и чтобы они тянули более-менее третьи шейдеры - разработчики все силы вкладывали в компилятор оных, применя оптимизации где только можно и какие только можно. А по ходу течения времени - карты становились все сильней и сильней, появился SLI, вот и перестали уделять должное внимание оптимизации, мол мощная карта все схавает.
Даже при поверхностном просмотре ассемблера видно что старый компилятор сгенерил более быстрый код; развернул цикл (а новый - нет), заюзал хитрые оптимизации - if/else при котором скипается куча кода в некоторых случаях (а новый - никак не отреагировал), отдает приоритет более легковесным операциям. Конечно в некоторых случая новый компилятор справляется тоже совсем не плохо (я и другие шейдеры попроверял), но наверное я буду дальше юзать старый компилер : / -
Даже при поверхностном просмотре ассемблера видно что старый компилятор сгенерил более быстрый код; развернул цикл (а новый - нет), заюзал хитрые оптимизации - if/else при котором скипается куча кода в некоторых случаях (а новый - никак не отреагировал), отдает приоритет более легковесным операциям. Конечно в некоторых случая новый компилятор справляется тоже совсем не плохо (я и другие шейдеры попроверял), но наверное я буду дальше юзать старый компилер : /
А может и не надо юзать компилятор каждый раз, храни в бинарном виде, чтобы не зависить от SDK. Вполне возможно, что хранить надо будет код под каждый GPU от каждого производителя, если требуется универсальность и высокая производительность одновременно ...
Я, когда реализовывал fixed function pipeline в OpenGL ES 1.1 драйвере на железе, которое поддерживало только шейдеры: geometry, vertex и pixel, весь код писал руками в GPU-машинных кодах без использования компиляторов от производителя видеокарты и жёстко вшивал в основной код в виде:
....
// asr (2) g115.14<1>W g1.14<2,2,1>W -0.1W {align1};
{ 0x00010020, 0x34001E00, 0x00001400, 0x00000030 },
// add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1};
{ 0x00800031, 0x20601F21, 0x00A10040, 0x04110203 },
....Это уже конечный результат после компилирования шейдерного ассемблера в GPU'шный ассемблер. Т.е. фактически потратил неделю на написание всех программ с последующим тестированием, зато я уверен в них на все 100%. И уже забыл, когда к ним возвращался...
Главное не забывать, что шейдерный ассемблер ещё компилируется в GPU'шный, где частенько не бывает нужных команд. К примеру, часто можно ожидать, что DP4 может развернуться в ~20 GPU'шных команд, или шум, или синусы/косинусы реализованы софтварно.
-
Mike Gorchak
Ого, да у вас опыт еще тот :)А может и не надо юзать компилятор каждый раз, храни в бинарном виде
Да, я над этим тоже думал, но все руки не доходят. Думаю хранить обе версии (исходники и бины) и при загрузке смотреть, если есть бины - грузить их,
иначе - компилировать исходники (и сохранять бины).
А старый компилятор я наверное заверну в отдельную DLL (так как сам компилятор лежит в статической либе, то он прилинкуется и будет жить в моей dll) - и буду юзать её, а sdk пускай уже новый остается.Кстати, в новом компиляторе можно заюзать флаг D3DXSHADER_USE_LEGACY_D3DX9_31_DLL - как ни странно, юзание этого флага приводит к генерации
более шустрого кода (так как юзается другой, более старый компилятор). Но все равно не дотягивает до 2004г. версии :)
Получается, новый компилер без этого флага дает ~90fps;
тот же компилер с этим флагом - 170-180fps;
и старый компилер (2004г) - ~200fps.Вот еще нашел на gamedev.net тоже заечание по поводу этого флага и нового компилера.
Чувак говорит что "Once I remove D3DXSHADER_USE_LEGACY_D3DX9_31_DLL it all slows to a crawl".В общем, Mike Gorchak, благодарю за содействие ;)
Думаю проблему можно считать решенной.