D3D10 costant buffer size issue

Started by
6 comments, last by Demirug 15 years ago
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:
Quote: 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?
Advertisement
What does say you're overriding values, D3DCompile?
Also can you try to test:
float4x4 WorldMatrix : packoffset(c0);float4 SampleWeights[2] : packoffset(c4);float4 SampleOffsets[4] : packoffset(c6);bool Lamp : packoffset(c10.x);
Here is the complete error:

Quote:
error X4019: Multiple variables found with the same user-specified location (7,8)
error X4019: Multiple variables found with the same user-specified location (8,9)


Row 7-8-9
	float SampleWeights[SAMPLE_COUNT]	:	packoffset(c4);	float2 SampleOffsets[SAMPLE_COUNT]	:	packoffset(c6);	bool Lamp				:	packoffset(c10.x);
Can you try the code I typed above?
iirc each of your float's and float2's will take a full float4
It looks like work but it will completely destroy all my previous code for loop reasons.
This is the original

    float4 Blur(VSB_OUTPUT Inp) : SV_TARGET        {                    float4 c = 0;            for (int i = 0; i < SAMPLE_COUNT;i++)            {                c += SpotText.Sample(SamplText, Inp.Tex + SampleOffsets.xy) * SampleWeights;            }                        return c;        }



How could i rewrite it respecting new cbuffer??
You could "inline" it, eg:

float4 Blur(VSB_OUTPUT Inp) : SV_TARGET{    float4 c = 0;    for (int i = 0; i < SAMPLE_COUNT / 4; i++)    {        int i2 = i * 2;        c += SpotText.Sample( SamplText, Inp.Tex + SampleOffsets[i2].xy ) * SampleWeights.x;        c += SpotText.Sample( SamplText, Inp.Tex + SampleOffsets[i2].zw ) * SampleWeights.y;        c += SpotText.Sample( SamplText, Inp.Tex + SampleOffsets[i2 + 1].xy ) * SampleWeights.z;        c += SpotText.Sample( SamplText, Inp.Tex + SampleOffsets[i2 + 1].zw ) * SampleWeights.w;    }                return c;}


(probably has some typos and stupid logic errors, as well being not much optimized, but you get the idea)
Ok but why 100 bytes instead 28??
Padding rules based on array elements addressing rules. In a Direct3D 10 shader a constant buffer is internally handled in 16 byte slots. To allow the shader to address each float in your array the need to store with a 16 byte granularity. While this would give us 7*16 byte = 112 bytes the last 12 bytes are not counted as the compiler could store other elements there. But as there is another array followed the compiler doesn’t use them and jump to the next 16 byte slot.

This topic is closed to new replies.

Advertisement