-
Notifications
You must be signed in to change notification settings - Fork 411
Shader Model 6
As of the June 2021 release, DirectX Tool Kit for DX12 defaults to using Shader Model 6 (except for legacy Xbox One XDK). The directx-vs-templates for DirectX 12 check for Shader Model 6 support as of May 2021.
Shader Model 6 is the latest HLSL compiler technology. It is required for DirectX Raytracing, DirectML, DirectX Mesh
& Amplification Shaders, and a number of other DirectX 12 features. The DXIL compiler (DXC
) generates Shader Model 6 programs, and the compiler is based on LLVM and is hosted on GitHub. A prebuilt version of DXC.EXE
is provided in the Windows 10 SDK (17134 or later).
DirectX 11 does not support Shader Model 6 shaders.
While most modern DirectX 12 drivers support Shader Model 6, you need to verify the level of support required by your program.
D3D12_FEATURE_DATA_SHADER_MODEL shaderModel = { D3D_SHADER_MODEL_6_0 };
if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel)))
|| (shaderModel.HighestShaderModel < D3D_SHADER_MODEL_6_0))
{
#ifdef _DEBUG
OutputDebugStringA("ERROR: Shader Model 6.0 is not supported!\n");
#endif
throw std::exception("Shader Model 6.0 is not supported!");
}
For higher shader models, you may be running on a system that doesn't recognize them, so the logic is slightly more complex in this case. This code finds the highest possible supported level, which is overkill in most cases, but is a useful reference:
D3D12_FEATURE_DATA_SHADER_MODEL shaderModel = {};
#if defined(NTDDI_WIN10_VB) && (NTDDI_VERSION >= NTDDI_WIN10_VB)
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_6;
#elif defined(NTDDI_WIN10_19H1) && (NTDDI_VERSION >= NTDDI_WIN10_19H1)
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_5;
#elif defined(NTDDI_WIN10_RS5) && (NTDDI_VERSION >= NTDDI_WIN10_RS5)
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_4;
#elif defined(NTDDI_WIN10_RS4) && (NTDDI_VERSION >= NTDDI_WIN10_RS4)
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_2;
#elif defined(NTDDI_WIN10_RS3) && (NTDDI_VERSION >= NTDDI_WIN10_RS3)
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_1;
#else
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_0;
#endif
HRESULT hr = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel));
while (hr == E_INVALIDARG && shaderModel.HighestShaderModel > D3D_SHADER_MODEL_6_0)
{
shaderModel.HighestShaderModel = static_cast<D3D_SHADER_MODEL>(static_cast<int>(shaderModel.HighestShaderModel) - 1);
hr = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel));
}
if (FAILED(hr))
{
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_5_1;
}
Note that a number of Shader Model levels were defined originally as 'experimental' so were not supported by the released
DXC
compiler or production drivers until later releases of Windows.
The code above assumes you are building with Windows 10 SDK (14393) or later. Shader Model 6 was not supported prior to Windows 10 Anniversary Update (14393).
By default shaders are built with FXC
for Shader Model 5.1 (using Root Signature 1.1). To use Shader Model 6, invoke the CompileScripts.cmd
with dxil
:
CompileShaders dxil
Be sure your application verifies that Shader Model 6 is supported before using the DirectX Tool Kit effects, SpriteBatch, or any other shader-using class or you will get runtime errors/C++ exceptions that may be harder to diagnose.
If you wish to modify the Visual Studio vcxproj
that invokes the shader build to use DXIL, modify the Exec
statement near the bottom of the file as follows:
<Target Name="ATGEnsureShaders" BeforeTargets="PrepareForBuild">
<Exec Condition="!Exists('src/Shaders/Compiled/SpriteEffect_SpriteVertexShader.inc')"
WorkingDirectory="$(ProjectDir)src/Shaders"
Command="CompileShaders dxil"
EnvironmentVariables="WindowsSdkVerBinPath=$(WDKBinRoot)" />
</Target>
The FXCCompile
task in Visual Studio is used automatically for .hlsl
files. If set to Shader Model 6 or later, MSBuild will invoke the DXC.EXE
compiler rather than FXC.EXE
.
If you plan to use Shader Model 6 in your project, it's a good idea to edit your vcxproj
file in a text editor and update the ItemDefinitionGroup
entries each platform to set a reasonable default value:
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
...
</Link>
<ClCompile>
...
</ClCompile>
<FXCompile>
<ShaderModel>6.0</ShaderModel>
<EnableDebuggingInformation>true</EnableDebuggingInformation>
<AdditionalOptions>/Fd "$(OutDir)%(Filename).pdb" %(AdditionalOptions)</AdditionalOptions>
</FXCompile>
/ItemDefinitionGroup>
Be sure to update all the configurations in your project (Release|x64
, Debug|Win32
, Release|Win32
, etc.).
The FXC.EXE
compiler defaulted to putting the shader debug information inside the shader blob which is simple, but can lead to 'bloaty' shader blobs. The recommendation is to use external PDBs instead, and the newer versions of DXC.EXE
will generate warnings if you use embedded symbols. The /Fd
statement above supports external PDBs above.
Be careful about name collisions between shader files and C/C++ source files. While
MyFile.cso
andMyFile.obj
won't collide, their correspondingMyFile.pdb
will collide which can result in very weird linker/debug symbol errors.
VS 2017 supports setting Shader Model 6.0, 6.1, 6.2, or 6.3. VS 2019 supports 6.0 - 6.4. They support Vertex Shader, Pixel Shader, Geometry Shader, Hull Shader, Domain Shader, and Compute Shader.
If you need to build with a higher shader model or a shader type that is not supported by the property pages, the workaround is to (a) set the highest level supported (such as Shader Model 6.3 for a VS 2017 project):
Then (b) use the Additional Options area to provide the correct target parameter (here we are building a Shader Model 6.5 Mesh Shader):
Microsoft Docs: Shader Model 6
Announcing Microsoft DirectX Raytracing! (requires Shader Model 6.3 or later)
Direct Machine Learning (DirectML) (requires Shader Model 6.4 or later)
Mesh Shaders and Amplification Shaders: Reinventing the Geometry Pipeline (requires Shader Model 6.5 or later)
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Xbox One
- Xbox Series X|S
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- MinGW 12.2, 13.2
- CMake 3.20