Created
August 1, 2014 04:30
-
-
Save Cody-Duncan/d85740563ceea99f6619 to your computer and use it in GitHub Desktop.
DirectX11 Generate Input Layout from Vertex Shader using D3DReflect.
This file contains hidden or 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
I have a question, how to know the InputSlot?In your code ,just specific it as zero,but there might be more then 1 input paramates like:
VertexOut main(float3 pos : POSITION, float4 colors : COLOR)
{
VertexOut output;
............
return output;
}
so, is there any way to know the InputSlot?