Forked from Cody-Duncan/gist:d85740563ceea99f6619
Last active
October 19, 2021 10:19
-
-
Save douduck08/562648de35c8cf1059c8e616eeb8bb8b to your computer and use it in GitHub Desktop.
DirectX11 Generate Input Layout from Vertex Shader using D3DReflect.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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, ¶mDesc ); | |
// 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