So, I am working on something that requires I programmatically know what’s in a DX11 shader file. One of the cool things you can use to figure out how many constant buffers, get string names from position streams, etc – is the DirectX Shader Reflection system. It gives you the ability to query a loaded shader blob for names/types/etc. However, it’s not quite as straightforward as one might expect to use. The docs were pretty incomplete up until the DX11 version. But here’s the basics of the ID3D11ShaderReflection system:
- Load your vertex/pixel shaders. Get the actual shader blob – or extract it from the FX system if you used that.
- Bind it to a shader reflection object using D3DReflect:
pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(), pPixelShaderBuffer->GetBufferSize(), g_pPSClassLinkage, &g_pPixelShader );
ID3D11ShaderReflection* pReflector = NULL;
D3DReflect( pPixelShaderBuffer->GetBufferPointer(), pPixelShaderBuffer->GetBufferSize(), IID_ID3D11ShaderReflection, (void**) &pReflector);
- Query the reflection object for whatever constant buffer, input/output stream, or other info you want using the many methods available. It’s a GREAT way to test your shaders at load time so you don’t get cryptic runtime errors later when you try to actually draw objects.
Now, the gotcha’s:
- You must add this:
Or you’ll get a compile error with D3DReflect() – despite the fact the official Microsoft docs seem to say you should (only) include:
- You MUST have the DirectX SDK include directory listed before the windows include directory in the Visual Studio compiler include directory list or you’ll get compile errors in D3DShader.h. This is apparently because the windows headers that come with Visual Studio actually have a few DX definitions in them that conflict with the DX SDK header definitions. Check Tools/Options | Project and Solutions | VC++ Directories and make sure Windows SDK include & library paths appear AFTER DirectX include & library paths. See here for the thread.