D3D 10.0 : Problem with constant buffers

Started by
3 comments, last by MJP 12 years, 11 months ago
Hello !

I'm starting to use constant buffers in my program , and I get troubles to retreive correctly a matrix from a constant buffer in the shader :

Here's the constant buffer declaration in the shader :

cbuffer everyFrame
{
float3 g_vCameraPosition;
matrix g_mViewProjection;
};


Here's the corresponding structure in the program :


#define ALIGN_CONSTANT_BUFFER _declspec(align(16))

ALIGN_CONSTANT_BUFFER struct CBeveryFrame
{
D3DXVECTOR3 g_vCameraPosition;
D3DXMATRIX g_mViewProjection;
};


At the beginning of the render loop, I instanciate this structure and send it to the GPU via UpdateSubresource().
The camera position is well updated, but not the viewProj matrix : the rendering using it (geometry instancing) seems to be not done.
I looked in the DX tutorials but I can't figure out what is wrong.

Any idea ?

Thank you in advance !
Bye
Advertisement
Putting alignment on the structure definition just specifies the alignment of that structure, not the alignment of the members inside of the structure. You're probably not interested in aligning the structure to anything, but instead aligning the matrix member to 16 bytes so that it lines up with the HLSL version. To do that you would do something like this:

#define ALIGN_REGISTER _declspec(align(16))

struct CBeveryFrame
{
D3DXVECTOR3 g_vCameraPosition;
ALIGN_REGISTER D3DXMATRIX g_mViewProjection;
};


You can also use #pragma pack to control packing of members of a struct or class.

Also, keep in mind that by default HLSL expects matrices in a constant buffer to be column-major and the D3DXMATRIX type is row-major. So you either need to transpose it in your C++ code, or transpose it in the shader, or declare the matrix in the constant buffer with the "row_major" modifier, or compile the shader with D3D10_SHADER_PACK_MATRIX_ROW_MAJOR.
Thank you it helps me very much !

(In fact this is the whole constant buffer that is not updated at all, I thought it was just the matrix but it is worth than that)
Hello
Thanks to your post I solve one of the 2 problems I had.
The second one was I simply omitted to set the constant buffer (effect->GetConstantBufferByIndex(x)->SetConstantBuffer(cb) ) :blink:

I had also difficulties to set 3 scalars (2 floats, 1 int). The solution I found was to put then in a vector3.
I wonder why, I supposed it's a problem of serialization (scalar encoding is not the same in the GPU ?)

Now all woks fine, thank you MJP

Does someone know why the scalars were not uploaded correctly?

this does work :

cbuffer everySubset
{
row_major matrix g_mWorld;
row_major matrix g_mWorldViewProjection;
float3 g_vMaterialColor;
float3 g_vEmissiveColor;
float3 g_vShininessIntensity_ShininessPower_Alpha;
};


this doesn't :

cbuffer everySubset
{
row_major matrix g_mWorld;
row_major matrix g_mWorldViewProjection;
float3 g_vMaterialColor;
float3 g_vEmissiveColor;
float g_fShininessIntensity;
float g_fAlpha;
int g_iShininessPower;
};


Bye :rolleyes:
HLSL has specific rules for packing individual variables in a constant buffer, that are listed here: http://msdn.microsoft.com/en-us/library/bb509632%28v=vs.85%29.aspx

So in your case, g_fShinninessIntensity won't be aligned to the next 16-byte boundary but will come immediately after g_vEmissiveColor.

This topic is closed to new replies.

Advertisement