PDA

View Full Version : Constant Buffer packing issues


XVincentX
03-17-2009, 02:41 PM
I've got this constant buffer.


// Buffer Definitions:
//
// cbuffer cMultiFrame
// {
//
// row_major float4x4 WorldMatrix; // Offset: 0 Size: 64 [unused]
// bool Lamp; // Offset: 64 Size: 4 [unused]
// float SampleWeights[7]; // Offset: 80 Size: 100
// float2 SampleOffsets[7]; // Offset: 192 Size: 104
//
// }
//



As you can see, while real sizeof(cMultiFrame) in Visual Studio = 160, when i call Draw function, it say me a warning:


D3D10: WARNING: ID3D10Device::Draw: The size of the Constant Buffer at slot 0 of the Pixel Shader unit is too small (160 bytes provided, 304 bytes, at least, expected).

At first i can't understand why 7 floats = 100 bytes while it should be only 28!

All this due to packing rules and floating problems.
The way is to use packoffset to force packing rules, i tried in this way following the documentation

At first i increased SAMPLE_COUNT to 8 to have float * 8 = 2 float4 and 8 * float2 = 4 float4.
And wrote this code.


cbuffer cMultiFrame
{
row_major float4x4 WorldMatrix : packoffset(c0);
float SampleWeights[SAMPLE_COUNT] : packoffset(c4);
float2 SampleOffsets[SAMPLE_COUNT] : packoffset(c6);
bool Lamp : packoffset(c10.x);
};


But it say me i'm overriding other values.
Can you suggest me right way to organize this constant buffer?

XVincentX
03-17-2009, 05:12 PM
Close please, i resolved.

Goz
03-18-2009, 03:45 AM
Its always nice to share how you resolved in case someone else comes across the problem :)

XVincentX
03-18-2009, 05:08 AM
I resolved making another constant buffer and forcing all arrays to float4...but it's a very horrible solution and i would like to better understand how packing is done by HLSL compiler and how to avoid this problems.

Anyway, in my opinion D3D10 can also waste 1 mega for constant buffer, my question is: how can i recreate same dummy values in my struct to have the right alignement offset?? I tried using floats, but D3D10 gave me an error in CB creation becouse size was not a 16-multiple.

It looks like HLSL compiler can pack, without offsets, only float4 arrays.