Basically, computers typically like (and sometimes require) data to be aligned on certain byte 'boundaries'. DirectX 11 requires 16 byte alignment and DirectX 12 is 256 byte. You can read about why alignment is good/required on the internet elsewhere. But the short of it is that computers will read multiple values at the same time, in sizes that are powers of 2 (Usually a minimum of 4 bytes at a time).
When things are unaligned, to read a single value, the computer may be required
to read multiple regions to fetch the data (or worst case, read single bytes at a time) [..==|==..]
(both the first and second slots would have to be read to read the value in the middle, whereas, if correctly aligned, [====|....]
could read just the first. (This also has storage implications).
This also means, that when reading a single value that is multiple bytes (say a float4, you may want to align it on its own 16 byte boundary)
You can find sizes of the data types here: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509646(v=vs.85).aspx
Remember that one byte is 8 bits. So, a float is 32 bits, which is 32 / 8 == 4 bytes.
Vectors are just multiples of the scalar (so if float is 4 bytes, float4 is 4 * 4 == 16 bytes).
So, in a constant buffer, you want your values to align to those 16/256 byte boundaries (and will be required to fill up to the next 16/256 bytes).
cbuffer {
float2 position; //offset = 0, size = 8
float2 texcoord; //offset = 8, size = 8
//16 byte boundary
float3 normal; //offset = 16, size = 12
float padding; //offset = 28, size = 4
//16 byte boundary
float4 tangent; //offset = 32, size = 16
//16 byte boundary
};
float4 xyz;
float2 zyx;
float pad;
float2 zxy;
Which means the order of bytes is 16, 12, 4, 12? \$\endgroup\$