I have a rather peculiar question remaining after solving most of my own question on StackOverflow. When creating the constant buffers used by my shaders, I've learned that the order of variables between the cbuffer
and the struct
representing it have to be an accurate match. I am still unsure as to why this is such an issue, and that's why I'm here.
When creating a cbuffer
to hold object data, I create the cbuffer
and struct
like so:
cbuffer ObjectBuffer : register(b0) {
float4x4 World;
float4x4 WorldViewProjection;
float4x4 WorldInverseTranspose;
}
public struct ObjectBuffer {
public Matrix World;
public Matrix WorldViewProjection;
public Matrix WorldInverseTranspose;
}
This way works just fine, but if I reorder the cbuffer
variables, or the struct
variables and do not reflect the changes in the other, issues arise and I can't even create the buffer.
cbuffer ObjectBuffer : register(b0) {
float4x4 WorldInverseTranspose;
float4x4 WorldViewProjection;
float4x4 World;
}
public struct ObjectBuffer {
public Matrix World;
public Matrix WorldViewProjection;
public Matrix WorldInverseTranspose;
}
In this case, the types are exactly the same and given the fact that HLSL
expects constant buffers to be in 16 byte chunks; why does the ordering matter so much?
Aren't float4x4
types the same as Matrix
types where it's essentially an array of arrays?
[ 0, 0, 0, 0 ] = 16 bytes
[ 0, 0, 0, 0 ] = 16 bytes
[ 0, 0, 0, 0 ] = 16 bytes
[ 0, 0, 0, 0 ] = 16 bytes
[ TOTAL ] = 64 bytes
Since a float
is 4 bytes on its own, this would mean a float4
is 16 bytes, and thus a float4x4
is 64 bytes. So why does the order matter if the size remained the same?
Update
So I've re-visited the issue and turns out I was wrong about the issue given above. This does allow the objects to be compiled correctly but presents grotesque effects in the shaders since the variables are in the wrong order which is expected.
However, this issue came up because I misread which buffer was causing the issue initially. It was all related to my material buffer in which I have a bool
and a float
. When I swapped the two on either side without reflecting the changes in the other it failed to create. I presume this is due to the difference in expected types. The cbuffer
is in bool-float
order while the struct
is the opposite. This I expect to cause an issue, but it would still be nice to know what's happening under the hood to cause it to break. Is it because bool
is a single byte but perhaps allocated into a chunk of 4 bytes?