D3DCompiler API Reference
This section provides reference documentation for the D3DCompiler API, which is used for compiling High-Level Shading Language (HLSL) code into shader bytecode for DirectX.
Overview
The Direct3D Shader Compiler (D3DCompiler) API allows you to compile HLSL code into shader bytecode. This bytecode can then be loaded by Direct3D and used by the GPU.
Key functionalities include:
- Compiling HLSL source code to shader bytecode.
- Optimizing shader code.
- Disassembling shader bytecode.
- Generating shader reflection data.
The D3DCompiler API is available starting with Direct3D 10.
Functions
The following are the primary functions exposed by the D3DCompiler API:
D3DCompile
Compiles HLSL shader code into shader bytecode.
HRESULT D3DCompile(
[in] LPCVOID pSrcData,
[in] SIZE_T SrcDataSize,
[in, optional] LPCSTR pSourceName,
[in, optional] const D3D_SHADER_MACRO *pDefines,
[in, optional] ID3DInclude *pInclude,
[in] LPCSTR pEntrypoint,
[in] LPCSTR pTarget,
[in] UINT Flags1,
[in] UINT Flags2,
[out] ID3DBlob **ppCode,
[out, optional] ID3DBlob **ppErrorMsgs
);
Parameters
- pSrcData: Pointer to the HLSL source code.
- SrcDataSize: Size of the HLSL source code in bytes.
- pSourceName: Optional name of the source file (for debugging).
- pDefines: Optional array of preprocessor macro definitions.
- pInclude: Optional interface for handling include directives.
- pEntrypoint: Name of the shader entry point function.
- pTarget: Shader target profile (e.g., "vs_5_0", "ps_4_1").
- Flags1: Compilation flags (e.g.,
D3DCOMPILE_ENABLE_STRICTNESS). - Flags2: Effect compilation flags (usually 0 for standard shaders).
- ppCode: Pointer to a variable that receives a pointer to an
ID3DBlobinterface containing the compiled shader code. - ppErrorMsgs: Pointer to a variable that receives a pointer to an
ID3DBlobinterface containing any compilation error or warning messages.
Return Value
S_OKif the compilation was successful.- An error code otherwise. Check the
ppErrorMsgsparameter for details.
D3DDisassemble
Disassembles shader bytecode into human-readable assembly code.
HRESULT D3DDisassemble(
[in] LPCVOID pSrcData,
[in] SIZE_T SrcDataSize,
[in] UINT Flags,
[in, optional] LPCSTR szComments,
[out] ID3DBlob **ppDisassembly
);
Parameters
- pSrcData: Pointer to the shader bytecode.
- SrcDataSize: Size of the shader bytecode in bytes.
- Flags: Disassembly flags.
- szComments: Optional string to be prepended to the disassembly.
- ppDisassembly: Pointer to a variable that receives a pointer to an
ID3DBlobinterface containing the disassembled code.
Return Value
S_OKif the disassembly was successful.- An error code otherwise.
Constants and Structures
The D3DCompiler API uses various constants and structures to define compilation flags, shader models, and other parameters.
Compilation Flags (D3DCOMPILE_*)
D3DCOMPILE_DEBUG: Enables debug information in the shader.D3DCOMPILE_OPTIMIZATION_LEVEL0: Disables optimizations.D3DCOMPILE_OPTIMIZATION_LEVEL3: Enables maximum optimizations.D3DCOMPILE_ENABLE_STRICTNESS: Enables stricter shader conformance.D3DCOMPILE_IEEE_STRICTNESS: Enables IEEE strictness for floating-point operations.
Shader Target Profiles
Shader targets specify the shader model and feature level to compile for:
- Vertex Shaders:
vs_X_Y(e.g.,vs_5_0,vs_4_1) - Hull Shaders:
hs_X_Y - Domain Shaders:
ds_X_Y - Geometry Shaders:
gs_X_Y - Pixel Shaders:
ps_X_Y(e.g.,ps_5_1,ps_3_0) - Compute Shaders:
cs_X_Y
Where X is the major version and Y is the minor version.
Usage Example
Here's a basic example of how to compile an HLSL shader:
#include <d3dcompiler.h>
#include <iostream>
// ... inside your application ...
const char* shaderCode = R"(
float4 PSMain() : SV_TARGET
{
return float4(1.0f, 0.0f, 0.0f, 1.0f); // Red color
}
)";
ID3DBlob* shaderBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
HRESULT hr = D3DCompile(
shaderCode,
strlen(shaderCode),
"basic_shader.hlsl",
nullptr, // No macros
nullptr, // No include handler
"PSMain", // Entry point
"ps_5_0", // Target profile
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, // Flags
0, // Effect flags
&shaderBlob,
&errorBlob
);
if (FAILED(hr)) {
if (errorBlob) {
std::cerr << "Shader compilation failed:\n" << (char*)errorBlob->GetBufferPointer() << std::endl;
errorBlob->Release();
} else {
std::cerr << "Shader compilation failed with unknown error." << std::endl;
}
if (shaderBlob) shaderBlob->Release();
return;
}
if (errorBlob) {
std::cout << "Shader compilation warnings:\n" << (char*)errorBlob->GetBufferPointer() << std::endl;
errorBlob->Release();
}
std::cout << "Shader compiled successfully!" << std::endl;
// Use shaderBlob->GetBufferPointer() and shaderBlob->GetBufferSize() to create shader object
if (shaderBlob) shaderBlob->Release();
Note: This example is illustrative. In a real application, you would manage the ID3DBlob objects carefully, releasing them when no longer needed.