I have not yet used more complicated CBs like this here but, from what I understand, my C++ alignment and packing has to match what HLSL expects. So I'm trying to figure out the rules so I can predictably lay out the C++ struct
to match what HLSL
expects.
I was doing some tests in a Vertex Shader v5
to see packing produced in the output and used this structure in the vs.hlsl
:
cbuffer conbuf {
float m0;
float m1;
float4 m2;
bool m3[1];
bool m4[4];
float4 m5;
float m6;
float4 m7;
matrix m8;
float m9;
float m10;
float4 m11[2];
float m12[8];
float m13;
};
which produced the following output (in the Header File Name
VC++ Project HLSL Settings):
cbuffer conbuf {
float m0; // Offset: 0 Size: 4
float m1; // Offset: 4 Size: 4
float4 m2; // Offset: 16 Size: 16
bool m3; // Offset: 32 Size: 4
bool m4[4]; // Offset: 48 Size: 52
float4 m5; // Offset: 112 Size: 16
float m6; // Offset: 128 Size: 4
float4 m7; // Offset: 144 Size: 16
float4x4 m8; // Offset: 160 Size: 64
float m9; // Offset: 224 Size: 4
float m10; // Offset: 228 Size: 4
float4 m11[2]; // Offset: 240 Size: 32
float m12[8]; // Offset: 272 Size: 116
float m13; // Offset: 388 Size: 4
};
I pretty much figured out how offsets work (based on sizes) but I cannot understand the array sizes.
Some array sizes in here seem random. I can't figure out how the bool m4[4]
array has size: 52. Same for float m12[8]
which is size: 116. How does the HLSL compiler manage to produce these sizes?
Any help? I've already looked on MSDN packing page but they don't say much about arrays.
.hlsl
file is first. The one output in theHeader File Name
property of VC++ is the second. TheVS
does nothing:return pos * m1 * m10 * m4[2];
so I use a couple of values for thecbuffer
not to be optimized away. – Flagwavingbool m4[4];
will force gettingfloat4 m5;
padded to appear at the next suitable 32 or 64 bit plain address. Forget about your offset assumptions, derive these from concrete sizeof queries! Here may be some hints how to determine the 'real' offsets: #18252315 – Lammersm4
. I understand whym5
is where it is. As it's padded to the next 16-byte alignment afterm4
. Som5
is atm4.offset + m4.size + padding to(16)
.m4
's size is what puzzles me. – Flagwaving