笔者最近在编写d3d11 demo时,发现 CreateInputLayout 调用一直返回错误,查看具体错误代码后,便开始查错。如下是笔者当时的代码
HRESULT hr; ID3DX11EffectTechnique *tech = m_pFx->GetTechniqueByName("testBasic"); UINT numLayoutSize = ARRAYSIZE(inputDesc); D3DX11_PASS_DESC passDesc; tech->GetPassByIndex(0)->GetDesc(&passDesc); hr = m_pD3dDevice->CreateInputLayout(inputDesc, numLayoutSize, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &m_pInputLayout);
对应的输入层描述数组如下
const D3D11_INPUT_ELEMENT_DESC inputDesc[] = { {"POSITION4", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, };
对应的Vertex shader文件输入结构如下
struct VertexIn { float4 pos : POSITION4; float4 world : NORMAL; float4 stress : COLOR; uint InstanceId : SV_InstanceID; };
仔细检查各种输入层描述数组后,也发现什么具体问题(当时的shader语义都是参见的MSDN的语义说明符)。但是CreateInputLayout函数就只返回 E_INVALIDARG ,无奈之下,搜索各种技术网站,
最后在overstock上找到了类似的问题,但却没能提供过多的帮助。最终,在对比MSDN参考示例时,发现它用的是这样的语义说明符 "POSITION" 而不是 "POSITION4"(虽然这两种语义说明符都在MSDN的Vertex Shader Input Semantic 中)
D3D11_INPUT_ELEMENT_DESC layout[] = { { L"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { L"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { L"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 }, };
对比后,发现语义"POSITION"总是出现在网上的d3d11教程中,于是笔者修改这一语义,结果就能够成功调用 CreateInputLayout。
修改后的代码及vertex shader 输入参数如下
const D3D11_INPUT_ELEMENT_DESC inputDesc[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, }; HRESULT hr; ID3DX11EffectTechnique *tech = m_pFx->GetTechniqueByName("testBasic"); UINT numLayoutSize = ARRAYSIZE(inputDesc); D3DX11_PASS_DESC passDesc; tech->GetPassByIndex(0)->GetDesc(&passDesc); hr = m_pD3dDevice->CreateInputLayout(inputDesc, numLayoutSize, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &m_pInputLayout);
struct VertexIn { float4 pos : POSITION; float4 world : NORMAL; float4 stress : COLOR; uint InstanceId : SV_InstanceID; };
参考文献:
https://stackoverflow.com/questions/24676128/createinputlayout-returns-e-invalidarg
2020-02-09 11:43:27
D3D11 CreateInputLayout E_INVALIDARG 无效的参数
原文:https://www.cnblogs.com/Virtual-World/p/12286622.html