Skip to content

Instantly share code, notes, and snippets.

@douduck08
Forked from Cody-Duncan/gist:d85740563ceea99f6619
Last active October 19, 2021 10:19
Show Gist options
  • Save douduck08/562648de35c8cf1059c8e616eeb8bb8b to your computer and use it in GitHub Desktop.
Save douduck08/562648de35c8cf1059c8e616eeb8bb8b to your computer and use it in GitHub Desktop.
DirectX11 Generate Input Layout from Vertex Shader using D3DReflect.
//Function Creates an input layout from the vertex shader, after compilation.
//Input layout can be reused with any vertex shaders that use the same input layout.
HRESULT CreateInputLayoutDescFromVertexShaderSignature( ID3DBlob* pShaderBlob, ID3D11Device* pD3DDevice, ID3D11InputLayout** pInputLayout, int* inputLayoutByteLength )
{
// Reflect shader info
ID3D11ShaderReflection* pVertexShaderReflection = nullptr;
HRESULT hr = S_OK;
if ( FAILED( D3DReflect( pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**) &pVertexShaderReflection ) ) )
{
return S_FALSE;
}
// get shader description
D3D11_SHADER_DESC shaderDesc;
pVertexShaderReflection->GetDesc( &shaderDesc );
// Read input layout description from shader info
unsigned int byteOffset = 0;
std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayoutDesc;
for ( unsigned int i=0; i< shaderDesc.InputParameters; ++i )
{
D3D11_SIGNATURE_PARAMETER_DESC paramDesc;
pVertexShaderReflection->GetInputParameterDesc(i, &paramDesc );
// create input element desc
D3D11_INPUT_ELEMENT_DESC elementDesc;
elementDesc.SemanticName = paramDesc.SemanticName;
elementDesc.SemanticIndex = paramDesc.SemanticIndex;
elementDesc.InputSlot = 0;
elementDesc.AlignedByteOffset = byteOffset;
elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
elementDesc.InstanceDataStepRate = 0;
// determine DXGI format
if ( paramDesc.Mask == 1 )
{
if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ) elementDesc.Format = DXGI_FORMAT_R32_UINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ) elementDesc.Format = DXGI_FORMAT_R32_SINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ) elementDesc.Format = DXGI_FORMAT_R32_FLOAT;
byteOffset += 4;
}
else if ( paramDesc.Mask <= 3 )
{
if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ) elementDesc.Format = DXGI_FORMAT_R32G32_UINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ) elementDesc.Format = DXGI_FORMAT_R32G32_SINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT;
byteOffset += 8;
}
else if ( paramDesc.Mask <= 7 )
{
if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
byteOffset += 12;
}
else if ( paramDesc.Mask <= 15 )
{
if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32 ) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32 ) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT;
else if ( paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32 ) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
byteOffset += 16;
}
//save element desc
inputLayoutDesc.push_back(elementDesc);
}
// Try to create Input Layout
hr = pD3DDevice->CreateInputLayout( &inputLayoutDesc[0], inputLayoutDesc.size(), pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), pInputLayout );
//Free allocation shader reflection memory
pVertexShaderReflection->Release();
//record byte length
*inputLayoutByteLength = byteOffset;
return hr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment