Each field in a constant buffer must be 16-byte aligned
#define ALIGN_REGISTER _declspec(align(16)) struct LightingConstants { DirectX::XMFLOAT3 myLightDirection; ALIGN_REGISTER DirectX::XMFLOAT3 myLightColour; ALIGN_REGISTER DirectX::XMFLOAT3 myCameraPosition; ALIGN_REGISTER DirectX::XMFLOAT2 myHalfPixel; ALIGN_REGISTER DirectX::XMFLOAT4X4 myInverseViewProjection; float myPadding; };
.... should work. But maybe XM... types are already aligned, with D3DX I have to manually align the fields.
My explanation is quite bad, please check this http://msdn.microsoft.com/en-us/library/bb509632%28v=vs.85%29.aspx
Not all variables in a constant buffer will be aligned to 16-byte boundaries. Alignment issues only occur when a variable will straddle a 16-byte boundary. So for instance this constant buffer won't require any special alignment in your C++ struct:
However something like this will cause the alignment rules to kick in:cbuffer Constants { float Var0; // Offset == 0 float Var1; // Offset == 4 float Var2; // Offset == 8 float Var3; // Offset == 12 }
cbuffer Constants { float Var0; // Offset == 0 float Var1; // Offset == 4 float3 Var2; // Offset == 16, since a float 3 would occupy bytes [8-20] which would cross the boundar float Var3; // Offset == 20 }
Hello MJP. That's why I suggested to follow the link....
Could we say that vectors and matrices must be 16-bytes aligned and scalars musn't ?
Yes indeed the link spells out all of the rules in detail, I just wanted to make sure that anyone reading in this thread didn't come away with incorrect information.
Saying that vectors need to be aligned and scalars don't is also incorrect. A float2 vector won't need to be aligned if it starts on byte 4 or byte 8, since it can still fit within a 16-byte boundary. Same goes for a float3 that starts on byte 4. Matrices can also be a bit weird if you don't use a float4x4, since you have to consider the alignment for each row. For instance a float3x3 will get packed as 3 float3's, with each float3 aligned to the next 16-byte boundary.