4
votes

I am trying to add things to my working code, but it is returning an error [Invalid Arg] when calling CreateInputLayout().

It works before I add the texture stuff, but fails when I add it.
The shader file compiled with no errors.
I think the way I made the layout is bad. Is this correct?

C++ Vertex structure:

struct VertexData{
    XMFLOAT3 Pos;
    XMFLOAT4 Color;
    XMFLOAT2 TexCoord;
};

C++ Layout:

    D3D11_INPUT_ELEMENT_DESC inputLayout[]={
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    }; uint lSize=sizeof(inputLayout)/sizeof(inputLayout[0]);

Shader code:

    // Stuff from DX Tutorial 7
Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );

cbuffer ViewData : register(b0){
    matrix World;
    matrix View;
    matrix Projection;
}

struct VS_INPUT{
    float4 pos : SV_POSITION;
    float4 color : COLOR0;
    float2 tex : TEXCOORD0;
};
struct PS_INPUT{
    float4 pos : SV_POSITION;
    float4 color : COLOR0;
    float2 tex : TEXCOORD0;
};

PS_INPUT VS(VS_INPUT input){
    PS_INPUT output=(PS_INPUT)0;

    output.pos=mul(input.pos, World);
    output.pos=mul(output.pos, View);
    output.pos=mul(output.pos, Projection);

    output.color = input.color;

    output.tex = input.tex;

    return output;
}

float4 PS(PS_INPUT input) : SV_Target {
    return input.color;
}

Edit:

After a bunch of twiddling with the shader code, I found that if I change the semantics of the...
1st position to: float4 pos : POSITION;
2nd position to: float4 pos : SV_POSITION;
...the input layout successfully creates.

I tried both without the SV_ [system value] prefix, but that also failed. I dont know why I cant have them be the same.

The Semantics seem a bit magical. Not sure if I should answer my own Q with this, or wait for someone smarter to answer better.

2

2 Answers

4
votes

Your structs do not match:

struct VertexData
{
    XMFLOAT3 Pos;  // float3 here
    XMFLOAT4 Color;
    XMFLOAT2 TexCoord;
};

struct VS_INPUT{
    float4 pos : SV_POSITION; // float4 here
    float4 color : COLOR0;
    float2 tex : TEXCOORD0;
};

For position in 3D space I prefer to use float3. So, as your input layout:

"POSITION", 0, R32G32B32_FLOAT

About semantics magic: Names in HLSL must match input layout names. For example:

Layout:

{ "POSITION", 0, .. }

Vertex Shader:

float4 pos : POSITION0;

The only exception is that pixel shader must always have float4 pos : SV_POSITION semantics for the input position of pixel (It is a one of the System Value semantics).

And as a bonus, some commonly used stuff I'd like to recommend:

  • int size = ARRYSIZE(inputayoutDesc);
  • use D3D11_APPEND_ALIGNED_ELEMENT instead of 12, 28, numbers as alignment offset.
0
votes

Input semantics shouldn't be SV_POSITION if they are in your input vertices, they should be POSITION I think.

Also you declare this -

struct VS_INPUT{
    float4 pos : SV_POSITION;

Shouldn't this be float3 pos : POSITION;

Your input layout only has 3 floats for that item. Not sure if it's the problem but it doesn't look quite right.