A quick note on shader compilers
This morning I was wrestling with a particularly complicated compute shader, which was taking just shy of 10 minutes to compile using D3DCompiler_43 from the June 2010 DirectX SDK. After a few failed attempts to speed it up by rearranging the code, I figured I’d try it out with the new version of the compiler that comes with the Windows 8 SDK. I wasn’t expecting any miracles, but to my surprise it compiled my shader in about 45 seconds! I figured I would pass along the knowledge, in case anyone else is dealing with a similar problem.
Comments:
Using the Feb 2010 SDK, I’ve found that array size directly impacts shader compile time: We had an array for bones with 1K elements, and our compile times for vertex shaders were about 30-45 seconds depending on the shader; after changing that to a one element array (to test this theory), our compile times went down to 0.2, 0.3 secs.
#### [MJP](http://mynameismjp.wordpress.com/ "mpettineo@gmail.com") -
@zproxy I don’t think I can say, although I’ll tell you that it involved a few instances of an unrolled loop that executed for 49 iterations. @talden I was actually already compiling the shaders at O1, and it was still that slow! But thanks for the tip.
#### [zeuxcg](http://zeuxcg.wordpress.com "arseny.kapoulkine@gmail.com") -
R Caloca, you should change the array count to 2. If it’s 1, compiler always selects the first bone so the generated assembly is incorrect; if it’s 2, it does the proper index-based lookup, and you can upload more than 2 bones - assuming that the array is at the end of the constant buffer, of course. This does not generate any D3D Debug warnings and, as far as I’m aware, is safe wrt different HW/drivers.
#### [MJP](http://mynameismjp.wordpress.com/ "mpettineo@gmail.com") -
Yes, you basically just need to change the VC++ directories for your include and lib files and then you can use the newer D3D headers and libraries. For VS 2010 you can follow these directions: http://blogs.msdn.com/b/vcblog/archive/2012/03/25/10287354.aspx One thing that is different with the Win8 SDK version of D3D is that there is no D3DX anymore. So if you have any dependencies on D3DX you’ll need to change your code.
#### [talden](http://talden.wordpress.com "dwrightnow@gmail.com") -
I’ve found that with compute shaders in particular, if you drop down to O1 instead of the default O3 optimization level you will get the same instruction count with 2-10x faster compiles.
#### [zproxy](http://zproxy.wordpress.com/ "dadeval@gmail.com") -
What was the shader about?
#### [benualdo]( "benualdo@msn.com") -
Thanks you for your help! I finally did it the “GetProcAddress” way because I was too lazy to change the vcproj. The shader now compile ~40% faster than before. Some shaders even compile twice faster (compute shaders and pixel shaders with lots of branch and nested loopts). Trivial shaders (like ZPass opaque PS) are a bit slower to compile.
#### [djmips](http://djmips.wordpress.com "david.c.galloway@gmail.com") -
Is there any chance that the new compiler generates more efficient code?
#### []( "") -
MJP, is it legal to ship the d3dcompiler.dll with your game or does Microsoft forbid that. If it is forbidden, then how can you ship your game when it pops a missing .dll error if you don’t include it? I am compiling ahead of time using VS2012 and so don’t see any reason why the executable would require me to dynamically link with the d3dcomipler anyway. For now I’ll just include the .dll in my .exe directory, but I feel that this is a hack. Thanks in advance.
#### [Dave Ottley]( "the_goosemaster@hotmail.com") -
By the way, the above post was made by Dave Ottley.
#### [benualdo]( "benualdo@msn.com") -
Could you use the win8 sdk compiler with your win7 application? If so, can you give more details about how you manage to do that? Did you have to compile shader using fxc.exe or compiling from code also worked? thanks!
#### [MJP](http://mynameismjp.wordpress.com/ "mpettineo@gmail.com") -
Yes, it’s possible. You can build Win7 applications using the Win8 SDK, in which case you just include D3DCompiler.h and link to d3dcompiler.lib and you’ll use the new compiler. Just make sure that you copy d3dcompiler_46.dll from the Bin folder of your SDK install directory and put it next to your executable, because it won’t be present on Win7 machines. If you want to keep using the headers and libs from DirectX SDK and use the compiler from the Win8 SDK, it’s a little more tricky. You can’t just add both Include paths to your VC++ directories, otherwise VC++ won’t know which version of the file you want to include. An alternative would be to just use LoadLibrary and GetProcAddress to call the compile functions in d3dcompiler_46.dll without using the headers or linking to it. Or if you’re compiling your shaders ahead of time, using fxc.exe is a simple way to do it.
#### [benualdo]( "benualdo@msn.com") -
Greate new and thanks for your answer, I’m fed up with slow shader compilation. I did not know that win8 is not needed to build apps using the win7 SDK. If I understand what you say all I have to do is to install the Win8SDK and include/link against the Directx11 (11.1?) that comes with it instead of DirectX SDK? And I won’t have to change anything else in my app to make it run with the win8SDK (as I can’t actually run a win8 on win7 anyway)?
#### [benualdo]( "benualdo@msn.com") -
Greate news and thanks for your answer, I’m fed up with slow shader compilation. I did not know that win8 is not needed to build apps using the win8SDK. If I understand what you say all I have to do is to install the Win8SDK and include/link against the Directx11 (11.1?) that comes with it instead of DirectX SDK? And I won’t have to change anything else in my app to make it run with the win8SDK (as I can’t actually run a win8 on win7 anyway)?
#### [benualdo]( "benualdo@msn.com") -
arg sorry for double post I was too excited by faster shader compilation (and cannot switch to win8 atm) :)