Jump to content

  • Log In with Google      Sign In   
  • Create Account


Issues With Input Layout


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 09:13 AM

Currently, i have two techniques setup for my skinned mesh, one using straight Diffuse texturing, and one using Normal Mapping. I want to be able to toggle between these techniques during runtime. My model contains the following attributes in the vertex buffer

float3 Position
float2 TexCoord
float3 Normal
float4 Tangent
float4 Weights
float4 Bones

Then i have my vertex shader input setup as such

struct GeometryVSIn {
    float3 position   : Position;
float2 texCoord   : TexCoord;
    float3 normal   : Normal;
#ifdef NORMALMAP
float4 tangent   : Tangent;
#endif
#ifdef SKINNED
float4 weights   : Weights;
float4 bones   : Bones;
#endif
};

now if i run the normal mapped technique, all works fine, and looks correct. However, if i run it without normal mapping ( I Don't define the preprocessor definition NORMALMAP), i get an error message as follows from Direct3D in the output window

D3D11: ERROR: ID3D11DeviceContext::DrawIndexed: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. Semantic 'Weights' is defined for mismatched hardware registers between the output stage and input stage. [ EXECUTION ERROR #343: DEVICE_SHADER_LINKAGE_REGISTERINDEX ]
D3D11: ERROR: ID3D11DeviceContext::DrawIndexed: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. Semantic 'Bones' is defined for mismatched hardware registers between the output stage and input stage. [ EXECUTION ERROR #343: DEVICE_SHADER_LINKAGE_REGISTERINDEX ]

Now when i view it in PIX, i see that the Tangent values are being passed thru to the vertex shader even though they are not supposed to be. I am under the impression that i can define my vertex buffer to have as many elements in it as i want, and inside the vertex shader using Semantics, i can tell the shader which ones to use, and which ones not to use (map to certain registers, etc...), although this doesn't seem to be the case that i am experiencing.

Would appreciate any help
Code makes the man

Sponsor:

#2 eppo   Crossbones+   -  Reputation: 2313

Like
0Likes
Like

Posted 15 November 2012 - 09:59 AM

I assume you are using the same input layout for both cases?

Input signatures between the input assembler and the vertex shader stage aren't compatible when you're skipping the Tangent semantic in the VS input struct.

http://msdn.microsoft.com/en-us/library/windows/desktop/bb509650(v=vs.85).aspx

#3 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 10:10 AM

So, based on that, i shouldn't even worry about creating a vertex shader per model, instead i should just use reflection at shader creation, and retrieve the input layout from that, and set that based on the shader that is currently bound...
Code makes the man

#4 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 10:23 AM

and when i skip the tangent piece, why are the input assembler and the vertex shader stage incompatible... it is a subset of the input assembler, and the order is the same though... sorry i am not seeing it, it's one of those days.
Code makes the man

#5 iedoc   Members   -  Reputation: 671

Like
0Likes
Like

Posted 15 November 2012 - 10:42 AM

The input layout tells the input assembler what your giving it. When you don't define NORMALMAP, you will also have to not define it in your input assembler. you will also have to adjust each element's offset after the NORMALMAP element in the input layout, otherwise what will happen is your input assembler will still think you are giving it tangent data, but since you did not define NORMALMAP, it will actually be reading the next member in your structure, which looks like weights. by the time it gets to the bones data, it will have run out of data for that vertex, and either give you an error right there, or start reading into the next vertex, which then every vertex after will be off, and eventually you will run into an error anyway after there is no more vertex data.

if NORMALMAP is defined, everything will work just fine, but if NORMALMAP is not defined, but the input layout has not changed, the input assembler will still expect it.

struct Vertex	// Vertex Structure
{
	XMFLOAT3 pos;
	XMFLOAT2 texCoord;
#ifdef NORMALMAP
	XMFLOAT3 normal;
#endif
	XMFLOAT3 tangent;
};

// input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
	{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },  
	{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },  
	{ "NORMAL",	 0, DXGI_FORMAT_R32G32B32_FLOAT,	0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0},
	{ "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT,	0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0}
};

even if you changed the code so that you took out NORMAL from the input layout when NORMALMAP is not defined, there would still be a problem because TANGENT offset is still 32. if NORMALMAP is not defined, you will need to remove NORMAL from the input layout and change TANGENT offset to 20.

Edited by iedoc, 15 November 2012 - 11:06 AM.

Braynzar Soft - DirectX Lessons & Game Programming Resources!

#6 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 11:00 AM

So using the semantics Position, TexCoord, Normal, Tangent, etc... does not tell the shader which chunk to pull. It just pulls the vertex buffer in completely, and reads that data as is ? not sure i understand the point of the semantics then aside from readability on the developers side...
Code makes the man

#7 iedoc   Members   -  Reputation: 671

Like
0Likes
Like

Posted 15 November 2012 - 11:05 AM

sorry, your right, that was a mistake. you don't have to match the vertex shaders input exactly with the input layout.

you just have to match the input layout with your vertex structure so that the input assembler knows what its getting. more specifically you have to match the input layout with the structure of vertices in the buffer you will give to the input assembler, since this buffers vertices might differ from the vertex structure you use in your applications code

Edited by iedoc, 15 November 2012 - 11:09 AM.

Braynzar Soft - DirectX Lessons & Game Programming Resources!

#8 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 11:09 AM

so if that is the case, then i should be able to use one input layout, that describes my vertex buffer, all elements in it. and then inside of my vertex shader, i should be able to extract the elements i need, as long as i keep them in the same order as the input layout.

example
vertexbuffer has the following elements
-Position (float3)
-TexCoord1(float2)
-TexCoord2(float2)
-Normal(float3)

inputlayout created to match that vertexbuffer

inside of my vertex shader i shoudl be able to pull
-Position
-TexCoord1
-Normal

and skip over the second set, as not all of my vertex shaders need the second set of tex coords. or do i need an input layout for every permutation, which doesn't seem right at all
Code makes the man

#9 iedoc   Members   -  Reputation: 671

Like
0Likes
Like

Posted 15 November 2012 - 11:12 AM

yes, you can do that. i made a mistake though, and you don't have to match the vertex shaders inputs with the input layout. you can just take whichever elements you want out of the vertex data, skipping the ones you don't need, as long as the data the vertex shader wants is in the vertex structure and input layout (although you will want to avoid sending extra data you don't use as much as possible for performance reasons)

Edited by iedoc, 15 November 2012 - 11:16 AM.

Braynzar Soft - DirectX Lessons & Game Programming Resources!

#10 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 11:30 AM

So in my original issue at the beginning, I have tangent data in my vertex buffer, however on the low end technique I don't need it, so I reprocess it out. My input layout has tangent in it correctly. So why doesn't it skip over that portion of the vertex buffer and go to weights next?
Code makes the man

#11 eppo   Crossbones+   -  Reputation: 2313

Like
0Likes
Like

Posted 15 November 2012 - 01:05 PM

An input layout describes (part of) the structure of a typeless stream of vertex data. The elements in the input layout need to match up with (at least) all the elements in a VS_INPUT structure. The VS elements can be a smaller subset of the input layout beginning at the first element, but can never contain elements unknown to the input layout.

If you want to use a single vertexbuffer and 'Position, TexCoord, Normal, Weights, Bones' as vertex shader inputs you'll have to create an input layout that refers to those elements, but contains byte offsets (D3D11_INPUT_ELEMENT_DESC.AlignedByteOffset) that skip over the unused data in the vertex stream (Tangent).

#12 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 01:20 PM

so again i ask, what is the point of the Semantic Name then? i thought that was a position point that signified where each element resided ( register wise ). I currently have the aligned byte offset set for each element in my array, so that element Weights is set to be 48, which is 12 float's from the beginning, which is correct given

Position is 3 floats, offset 0
TexCoord is 2 floats, offset 12
Normal is 3 floats, offset 20
Tangent is 4 floats, offset 32
Weights is 4 floats, offset 48
Bones is 4 floats, offset 64

so according to what you said, the aligned byte offset should tell the vertex shader that my Weights start at byte 48, which is what i want. but this is not whats happening
Code makes the man

#13 NiteLordz   Members   -  Reputation: 369

Like
0Likes
Like

Posted 15 November 2012 - 01:26 PM

from pix, the input layout is such

Input Layout 0x06ECAF40
Slot SemanticName SemanticIndex Format InputSlot AlignedByteOffset InputSlotClass InstanceDataStepRate
0 Position 0 DXGI_FORMAT_R32G32B32_FLOAT 0 0 D3D11_INPUT_PER_VERTEX_DATA 0
1 TexCoord 0 DXGI_FORMAT_R32G32_FLOAT 0 12 D3D11_INPUT_PER_VERTEX_DATA 0
2 Normal 0 DXGI_FORMAT_R32G32B32_FLOAT 0 20 D3D11_INPUT_PER_VERTEX_DATA 0
3 Tangent 0 DXGI_FORMAT_R32G32B32A32_FLOAT 0 32 D3D11_INPUT_PER_VERTEX_DATA 0
4 Weights 0 DXGI_FORMAT_R32G32B32A32_FLOAT 0 48 D3D11_INPUT_PER_VERTEX_DATA 0
5 Bones 0 DXGI_FORMAT_R32G32B32A32_FLOAT 0 64 D3D11_INPUT_PER_VERTEX_DATA 0

and the shader input signature and output signature are

// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------ ------
// Position 0 xyz 0 NONE float xyz
// TexCoord 0 xy 1 NONE float xy
// Normal 0 xyz 2 NONE float xyz
// Weights 0 xyzw 3 NONE float xyzw
// Bones 0 xyzw 4 NONE float xyzw
//
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------ ------
// SV_Position 0 xyzw 0 POS float xyzw
// TexCoord 0 xy 1 NONE float xy
// Normal 0 xyz 2 NONE float xyz
// PositionView 0 xyz 3 NONE float
// EyeVector 0 xyz 4 NONE float
Code makes the man

#14 eppo   Crossbones+   -  Reputation: 2313

Like
1Likes
Like

Posted 15 November 2012 - 01:44 PM

The bytes offsets you've supplied specify the offsets in the vertex buffer. They have nothing to do with vertex shader input registers (these are all 4 * 4 bytes floats). For example, the format DXGI_FORMAT_R8_UNORM is stored as an 8 bits integer, but expands to a 32 bits float when written into a VS register. So, as there is no direct relation between byte sizes, the IA uses semantics to couple values.

If the vertex shader expects the fourth element to have a semantic 'Weights', then the input layout should have an identical fourth element. So in this case you need to throw the Tangent semantic out of the input layout and create a separate layout for the normal mapped case.

Edited by eppo, 16 November 2012 - 02:59 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS