HLSL, FXC, and D3DCompilehlsl, visualc, windowssdk
Originally posted to Chuck Walbourn's Blog on MSDN,
With the retirement of D3DX (See “Where is the DirectX SDK?”, “Where is the DirectX SDK (2013 Edition)?”, and “Where is the DirectX SDK (2015 Edition)?”), there is some confusion about how applications access the High-Level Shader Language (HLSL) compiler. As mentioned in an earlier post (See “What’s up with D3DCompiler_xx.DLL?”), the HLSL compilation functions, shader reflection, and some support functions for the compiler were pulled out of D3DX as of the DirectX SDK (August 2009) release. While many developers continue to use the D3DX functions to compile HLSL and Effects, they are just pass-through functions to the D3DCompile API which can be used directly instead. The latest version of the D3DCompile API includes some new functions as well such as D3DCompileFromFile and D3DCompile2.
Windows 8.1 / Windows 10: The latest version of the D3DCompiler (#47) is now included with the Windows 8.1 / Windows 10 OS and is available for runtime use by Windows Store apps / Universal Windows Platform (UWP) apps. There is a new HLSL linker option as well that provides some of this flexibility to compose shaders at runtime without recompiling from the HLSL source.
Visual Studio and HLSL
With Visual Studio 2012 or later, HLSL and the FXC.EXE tool is now integrated into build environment and the Windows 8.x SDK / Windows 10 SDK. If you add
.fx extension files to your project, there are properties for controlling how the HLSL compiler is invoked as part of your build including target profile, entry point name, etc. The resulting compiled shader uses the default extension of
.cso (Compiled Shader Object). The texture editor supports HLSL colorization, and the Visual Studio Graphics Diagnostics feature provides support for debugging HLSL as well.
There is one quirk of having HLSL integrated into MSBuild that requires some restructuring of existing HLSL source files. The MSBuild system assumes that each source files is built exactly once. If you need to build the same HLSL source multiple times, you’ll need individual
.fx files for each instance you want to build added to your project. Judicious use of the
#include directive should make it fairly easy to share the same source where needed, but this is a bit of a move away from the
.fx file model where all variations of shaders were kept in a single file. You of course can still make use of some custom build script and integrate a custom build step for more sophisticated generation of shaders, but this “one .hlsl file per shader combination” model is going to be seen in a lot of samples.
This automatic integration only works for C++ projects, not C# projects.
VS 2013: Visual Studio 2013 comes with Windows 8.1 SDK which includes the
D3DCompiler_47.DLL. It works essentially the same as it did with VS 2012.
VS 2015: Visual Studio 2015 comes with the Windows 8.1 SDK (Spring 2015) and optionally the Windows 10 SDK which includes an updated
Build-time vs. Runtime Compilation
As we have recommended for many years, developers should compile their HLSL shaders at build-time rather than rely on runtime compilation. There is little benefit to doing runtime compilation for most scenarios, as vendor-specific micro-optimizations are done by the driver at runtime when converting the HLSL binary shader blobs to vendor-specific instructions as part of the shader object creation step. Developers don’t generally want the HLSL compiler results to change ‘in the field’ over time, so it makes more sense to do compilation at build-time. That is the primary usage scenario expected with the Windows 8.0 SDK and Visual Studio 11, and is the only supported scenario for Windows Store apps (a.k.a Metro style apps) in Windows 8.0. FXC and the MSBuild rules above are well suited to this usage.
For development purposes, it is often very convenient to use runtime compilation. Such applications typically keep a ‘shader cache’ file that is generated during execution, and a ‘final’ version of the shader cache is then shipped with the title. This scenario is supported by the D3DCompile API hosted in the
D3DComplier_*.DLL. This is fully supported for Win32 desktop applications, and can even be used for Windows Store apps during development although not in deployment with Windows 8.0. In this case, the
D3DCompiler_*.DLL from the Windows 8.0 SDK should be included side-by-side with the application itself (i.e. application local deployment). The
d3dcomplier.h header and
d3dcompiler.lib are part of the Windows 8.0 SDK include and lib paths, and the
D3DCompiler_*.DLL itself is located in
"%WindowsSdkDir%\redist\d3d". If your application makes use of the D3DCompile API, you will want to add a Custom Build Step for the project to make sure the right DLL is copied as part of your build.
Platform: Win32 (All Configurations)
copy "$(WindowsSdkDir)redist\d3d\x86\D3DCompile*.DLL" "$(TargetDir)"
Platform: x64 (All Configurations)
copy "$(WindowsSdkDir)redist\d3d\x64\D3DCompile*.DLL" "$(TargetDir)"
Platform: ARM (All Configurations)
copy "$(WindowsSdkDir)redist\d3d\arm\D3DCompile*.DLL" "$(TargetDir)"
Note this assumes you are using the Windows 8.1 SDK or Windows 10 SDK.
Windows 8.1 / Windows 10: For Windows Store apps and Universal Windows Platform (UWP) apps, there’s no need to copy the
D3DCompiler_*.DLL since there is a copy in the OS available for this use. The
D3DCompiler_*.DLL itself won’t pass WACK, so you shouldn’t use application local deployment.
The legacy DirectX SDK versions of D3DCompile (#33 - #43) were deployed using the DirectSetup technology and installed to the
%WINDIR%\SysWow64) folders using the redistribution package (which requires administrator rights at installation time). With the Windows 8.x SDK / Windows 10 SDK, the D3DCompile DLL is never installed to the
%WINDIR% folders. Instead, you should copy it into your applications folder and deploy it ‘application local’ with your Win32 desktop application.
Windows 8.1 / Windows 10: D3DCompile #47 is included with the Windows 8.1 / Windows 10 OS so there is no need to redistribute it for Windows Store apps / Universal Windows Platform (UWP) apps. There is also a copy in the Windows 8.1 SDK (
C:\Program Files (x86)\Windows Kits\8.1\Redist\D3D) / Windows 10 SDK (
C:\Program Files (x86)\Windows Kits\10\Redist\D3D) you can redistribute application local for Win32 classic desktop applications the same way as you could D3DCompiler #46 from the Windows 8.0 SDK (
C:\Program Files (x86)\Windows Kits\8.0\Redist\D3D).
The Effects 11 (aka FX11) shared source library requires the “Effect” Shader Type and the “Shader Model 5” profile. It also requires the
D3DCompiler_*.DLL at runtime for the shader reflection APIs, which makes it unsuitable for Windows Store apps.
The “fx” profiles (
fx_5_0) are deprecated and may be removed from a future update of the HLSL compiler.
The shader binaries built by the current FXC.EXE and D3DCompile API using the Shader Model 2.0 and Shader Model 3.0 profiles will work on all Direct3D 9.0c compatible platforms including Windows XP. The actual
D3DCompiler_*.DLL in the Windows 8.x SDK / Windows 10 SDK itself only supports Windows Vista, Windows 7, Windows 8.x, and Windows 10. Windows XP development requires some additional work as detailed here.
For Shader Model 5 shaders, some HLSL language features require the DirectX 11.1 runtime. This uses the existing mechanism that indicates a shader requires the hardware support double-precision shaders for DirectX 11.0. This includes use of Feature Level 11.1 features (UAVs at every stage, 64 UAV slots), DirectX 11.1 runtime features (minimum-precision data-types), and new DirectX 11.1 optional hardware features (extended double-precision instructions, SAD4). A shader blob that indicates one of these requirements will fail to bind at runtime if the system doesn’t support them. This information is included in the HLSL disassembly output, and all require some explicit feature usage in the HLSL source.
Here’s a handy table of equivalents for replacing legacy D3DX HLSL compiler related functions (see Living without D3DX for a complete listing).
||No direct equivalent. Can use resource APIs and then
- D3DCompiler_47 - Windows 10 (inbox), Windows 10 SDK; Windows 8.1 (inbox), Windows 8.1 SDK, Visual Studio 2013/2015
- D3DCompiler_46 - Windows 8.0 SDK, Visual Studio 2012
- D3DCompiler_43 - DirectX SDK (June 2010)
- D3DCompiler_42 - DirectX SDK (February 2010)
- D3DCompiler_41 - DirectX SDK (March 2009)
- D3DCompiler_40 - DirectX SDK (November 2008)
- D3DCompiler_39 - DirectX SDK (August 2008)
- D3DCompiler_38 - DirectX SDK (June 2008)
- D3DCompiler_37 - DirectX SDK (March 2008)
- D3DCompiler_36 - DirectX SDK (November 2007)
- D3DCompiler_35 - DirectX SDK (August 2007)
- D3DCompiler_34 - DirectX SDK (June 2007)
- D3DCompiler_33 - DirectX SDK (Aprli 2007)
High Level Shader Language (HLSL) Update—Introducing Version 5.0 (Gamefest 2008)
Symbolic Differentiation in GPU Shaders
Related: Getting Started with Direct3D 11, What’s up with D3DCompiler_xx.DLL
DXIL: In addition to the
FXC.EXE HLSL compiler, there is a new
DXC.EXE (DXIL) compiler available for Shader Model 6 / DirectX 12. See the GitHub project for details.