I tried to write new vertex shader (exactly vertex shader is NULL and input is going to geometry shader but this shouldn't be a difference) with different input layout like other shaders in my application. But I'm getting invalid arg during input layout creation and don't know why. So here is my C++/shader code:
Vertex definition in C++:
typedef struct vertex
{
vertex() {}
vertex( const XMFLOAT3& p,
const XMFLOAT4& c,
const XMFLOAT3& n,
const XMFLOAT3& tu,
const XMFLOAT2& t)
: Position(p), Normal(n), TangentU(tu), TexC(t) {}
vertex( float px, float py, float pz,
float n1, float n2, float n3,
float tu1, float tu2, float tu3,
float t1, float t2)
: Position(px,py,pz), Normal(n1, n2, n3), TangentU(tu1, tu2, tu3), TexC(t1, t2) {}
vertex (float px, float py, float pz)
: Position(px,py,pz), Normal(0.0f, 0.0f, 0.0f), TangentU(0.0f, 0.0f, 0.0f), TexC(0.0f, 0.0f) {}
bool operator==(const vertex& v)
{
return (memcmp(&(this->Position),&(v.Position),sizeof(Position)) == 0);
}
vertex& operator=(const vertex& v)
{
memcpy(this, &v, sizeof(*this));
return *this;
}
bool operator!=(const vertex& v)
{
if ((Position.x != v.Position.x) ||
(Position.y != v.Position.y) ||
(Position.z != v.Position.z))
return true;
return false;
}
void Init(void)
{
ZeroMemory(this,sizeof(*this));
}
XMFLOAT3 Position;
//data for lighting
XMFLOAT3 Normal;
XMFLOAT3 TangentU;
//data for texturing
XMFLOAT2 TexC;
} TVertex;
VertexIn definition in HLSL:
struct GMVectorVertexIn_Basic
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float3 TangentL : TANGENT;
};
Input layout description:
const BYTE GM_VECTORS_ATTRIBUTE_COUNT = 3;
const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::GMVectorBasicDesc[GM_VECTORS_ATTRIBUTE_COUNT] =
{
{ "Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
And input layout creation:
Effects::BasicFX->GMVectorBasicTech->GetPassByIndex(0)->GetDesc(&passDesc);
HR(device->CreateInputLayout(InputLayoutDesc::GMVectorBasicDesc, GM_VECTORS_ATTRIBUTE_COUNT, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &GMVectorBasicLayout));
FX File:
struct GMVectorVertexIn_Basic
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float3 TangentL : TANGENT;
};
struct GMVectorVertexOUT_Basic
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float4 Color : COLOR;
};
[maxvertexcount(4)]
void GS_GMVectorBasic(point GMVectorVertexIn_Basic gin[1], inout LineStream<GMVectorVertexOUT_Basic> lineStream)
{
GMVectorVertexOUT_Basic p1_out, p2_out;
float3 pointPosition;
p1_out.PosH = mul(float4(gin[0].PosL, 1.0f), gWorldViewProj);
p1_out.PosW = mul(float4(gin[0].PosL, 1.0f), gWorld).xyz;
if (gDrawNormalVectors)
{
p1_out.Color = gNormalVectorColor;
pointPosition = gin[0].PosL + gin[0].NormalL;
p2_out.PosH = mul(float4(pointPosition, 1.0f), gWorldViewProj);
p2_out.PosW = mul(float4(pointPosition, 1.0f), gWorld).xyz;
p2_out.Color = gNormalVectorColor;
lineStream.Append(p1_out);
lineStream.Append(p2_out);
}
if (gDrawTangentVectors)
{
p1_out.Color = gTangentVectorColor;
pointPosition = gin[0].PosL + gin[0].TangentL;
p2_out.PosH = mul(float4(pointPosition, 1.0f), gWorldViewProj);
p2_out.PosW = mul(float4(pointPosition, 1.0f), gWorld).xyz;
p2_out.Color = gTangentVectorColor;
lineStream.Append(p1_out);
lineStream.Append(p2_out);
}
}
float4 PS_GMVectorBasic(GMVectorVertexOUT_Basic pin, uniform bool gUseFog) : SV_Target
{
float4 retColor = pin.Color;
//fogging
if (gUseFog)
{
float distToEye = length(gEyePosW - pin.PosW);
float fogLerp = saturate((distToEye - gFogStart)/gFogEnd);
//Blend the fog color and lit color
retColor = lerp(retColor, gFogColor, fogLerp);
}
return retColor;
}
And Technique definition:
technique11 GMVectorBasicTech
{
pass P0
{
SetVertexShader(NULL);
SetGeometryShader(CompileShader(gs_5_0, GS_GMVectorBasic()));
SetPixelShader(CompileShader(ps_5_0, PS_GMVectorBasic(false)));
}
}
I checked arguments count, leyout description and CreateInputLayout calling and I can't see where is a problem. Most probably I'm too tired to see a trivial bug...
Error displayed in dialog:
Unexpected error encountered.
Error code: E_INVALIDARG (0x80070057)
D3D11 ERROR: ID3D11Device::CreateInputLayout: Encoded Signature size doesn't match specified size. [ STATE_CREATION ERROR #161: CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE]
First-chance exception at 0x76BCC42D in EngineDX.exe: Microsoft C++ exception: _com_error at memory location 0x002BF488.
First-chance exception at 0x76BCC42D in EngineDX.exe: Microsoft C++ exception: _com_error at memory location 0x002BF484.
Basic Classes\InputLayout\InputLayout.cpp(76): device->CreateInputLayout(InputLayoutDesc::GMVectorBasicDesc, GM_VECTORS_ATTRIBUTE_COUNT, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &GMVectorBasicLayout) hr=E_INVALIDARG (0x80070057)
Thanks for help.
EDIT 3.11.2014: I solved the problem by creating vertex shader, which only resend vertex data to geometry shader. Whith this, input layout was successfully created without other changes.