I have issues with HLSL Buffer alignment. I have a light struct in an array of size 48 (i.e. a shader is meant to hold atmost 48 lights). (Divisiors are markers of 16 byte boundaries)
struct RendererLight {
float4 Position;
//---//
float4 Color;
//---//
float4 Direction;
//---//
float Intensity;
float In;
float Out;
float Range;
//---//
int bakedLight;
int dynamicLight;
//---//
};
cbuffer LightsBuffer : register(b1)
{
RendererLight Lights[48];
//---//
int NumLights;
//---//
};
for some reason, the sizes differ from the c++ side of the structs.
struct ShaderLight {
Vector4 Position;
Vector4 Color;
Vector4 Direction;
float Intensity;
float In;
float Out;
float Range;
int baked;
int dynamic;
int pad[2];
};
constexpr auto of5 = offsetof(ShaderLight, dynamic); //68 - correct
constexpr auto sz1 = sizeof(ShaderLight); // 80 - i think correct?
struct CLightBuffer {
ShaderLight Lights[NUM_LIGHTS_PER_BUFFER];
int NumLights;
int pad[3];
};
constexpr auto sz = sizeof(CLightBuffer::Lights); // 3840 - incorrect; hlsl assembly says wants 3832 - 8 byte less
constexpr auto sz2 = sizeof(CLightBuffer); // 3844 - incorrect;
constexpr auto of = offsetof(CLightBuffer, NumLights); // 3840 - incorrect; hlsl assembly wants 3832
Here is the assembly of the buffer:
// cbuffer LightsBuffer
// {
//
// struct
// {
//
// float4 Position; // Offset: 0
// float4 Color; // Offset: 16
// float4 Direction; // Offset: 32
// float Intensity; // Offset: 48
// float In; // Offset: 52
// float Out; // Offset: 56
// float Range; // Offset: 60
// int bakedLight; // Offset: 64
// int dynamicLight; // Offset: 68
//
// } Lights[48]; // Offset: 0 Size: 3832
// int NumLights; // Offset: 3832 Size: 4
//
// }
i don't quite understand how the HLSL array has a size of 3832. 3832 / 48 is not 80 but 79.83 - how is that possible?
As you've correctly noted on the C++ side, your ShaderLight data just contains 72 Bytes of 'used' data and has therefore 8 bytes of padding at the end. However, on the HLSL side, these 8 padding bytes are not needed for the last element in your array, as the follow-up element (the NumLight integer) can be packed inside these padding bytes.
You could fix this easily by specifying the int pad[2];
not just on the C++ side, but also in your HLSL code.