Microsoft Visual Studio 2012 can now compile shader code from *.hlsl files that you include in your C++ project.
As part of the build process, Visual Studio 2012 uses the fxc.exe HLSL code compiler to compile the .hlsl files into binary shader object files or into byte arrays that are defined in header files. How the HLSL code compiler compiles each .hlsl file in your project depends on how you specify the Ouput Files property for that file. For more info about HLSL property pages, see HLSL Property Pages.
The compile method that you use typically depends on the size of your *.hlsl file. If you include a large amount of byte code in a header, you increase the size and the initial load time of your app. You also force all byte code to reside in memory even after the shader is created, which wastes resources. But when you include byte code in a header, you can reduce code complexity and simplify shader creation.
Let's now look at various ways to compile your shader code and conventions for file extensions for shader code.
- Using shader code file extensions
- Compiling at build time to object files
- Compiling at build time to header files
- Compiling with D3DCompileFromFile
- Related Topics
To conform to Microsoft convention, use these file extensions for your shader code:
- A file with the .hlsl extension holds High Level Shading Language (HLSL) source code.
- A file with the .cso extension holds a compiled shader object.
- A file with the .h extension is a header file, but in a shader code context, this header file defines a byte array that holds shader data.
If you compile your .hlsl files into binary shader object files, your app needs to read the data from those object files (.cso is the default extension for these object files), assign the data to byte arrays, and create shader objects from those byte arrays. For example, to create a vertex shader (ID3D11VertexShader**), call the ID3D11Device::CreateVertexShader method with a byte array that contains compiled vertex shader byte code. The Direct3D tutorial sample shows how to create shader objects from byte arrays that it obtained from .cso binary shader object files. In this example code from the Direct3D tutorial sample, the Ouput Files property for the SimpleVertexShader.hlsl file specifies to compile into the SimpleVertexShader.cso object file.
auto vertexShaderBytecode = reader->ReadData("SimpleVertexShader.cso"); ComPtr<ID3D11VertexShader> vertexShader; DX::ThrowIfFailed( m_d3dDevice->CreateVertexShader( vertexShaderBytecode->Data, vertexShaderBytecode->Length, nullptr, &vertexShader )
If you compile your .hlsl files into byte arrays that are defined in header files, you need to include those header files in your code. The Media extensions sample shows how to create shader objects from byte arrays that are defined in header files and that you include in your project at compile time. In this example code from the Media extensions sample, the Ouput Files property for the PixelShader.hlsl file specifies to compile into the g_psshader byte array that is defined in the PixelShader.h header file.
# include "PixelShader.h" ComPtr<ID3D11PixelShader> m_pPixelShader; hr = pDevice->CreatePixelShader(g_psshader, sizeof(g_psshader), nullptr, &m_pPixelShader);
Note Windows Store apps support using D3DCompileFromFile for development but not for deployment.