[DX 11] Scrambled constant buffer

Started by
0 comments, last by Hodgman 12 years, 4 months ago
Somehow I've once again managed to scramble my buffers...

I recently added a bunch of new variables to one of my constant buffer types, and added them to the corresponding shaders that use them, but I'm finding that one of the variables is becoming corrupted, and many of the other variables are out of order.

Here's my constant buffer type:

struct SkyConstantBufferType
{
XMMATRIX camView;
XMFLOAT3 cameraPos;
XMFLOAT3 sunDir;
float bro;
float bmo;
float g;//eccentricity
float Esun;
};



And the code that creates it for D3D11:


bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(SkyConstantBufferType);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer(&bd, NULL, &g_pSkyConstantBuffer);



And my draw call where I'm updating/binding it:


SkyConstantBufferType skyCb;
skyCb.camView = XMMatrixTranspose(conversions::boostToD3DMatrix4x4((g_quatCam.getRotationMatrix())));

boost::numeric::ublas::vector<float> camPos(3);
camPos = g_quatCam.getLocation();
skyCb.cameraPos.x = camPos[0];
skyCb.cameraPos.y = camPos[1];
skyCb.cameraPos.z = camPos[2];
skyCb.Esun = g_esun;
skyCb.bmo = g_mie;
skyCb.bro = g_rayleigh;

skyCb.sunDir.x = g_sunDir[0];
skyCb.sunDir.y = g_sunDir[1];
skyCb.sunDir.z = g_sunDir[2];
skyCb.g = g_g;

g_pImmediateContext->UpdateSubresource(g_pSkyConstantBuffer, 0, NULL, &skyCb, 0,0);


g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pSkyVertexBuffer, &stride, &offset);

// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );

g_pImmediateContext->VSSetShader(g_pSkyVShader, NULL, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pSkyConstantBuffer);
g_pImmediateContext->PSSetShader(g_pSkyPShader, NULL,0);
g_pImmediateContext->PSSetConstantBuffers(0,1, &g_pSkyConstantBuffer);
g_pImmediateContext->Draw(4,0);



Here's the relevant code on the shader side:


cbuffer ConstantBuffer : register(b0)
{
matrix camView;
float3 cameraPos;
float3 sunDir;
float bro;
float bmo;
float g;
float Esun;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Ray : RAY;

};
//.... Intervening helper functions omitted...


PS_INPUT VS(float4 Pos : POSITION)
{
PS_INPUT outPos = (PS_INPUT)0;
outPos.Pos = Pos;
outPos.Ray = float4(mul(outPos.Pos.xyz, (float3x3)camView), 0);
outPos.Ray = normalize(outPos.Ray);
return outPos;
}


float4 PS(PS_INPUT Pos) : SV_Target
{
///..... Pixel shader stage omitted ....



What I'm finding in PIX, is that when I get to the pixel shader stage, that the following constant variables are messed up:
bmo = correct_g
bro = correct_bmo
cameraPos is correct.
Esun = garbage (negative very large number)
g = correct_Esun
sunDir = { correct_sundir[1], correct_sundir[2], correct_bro}

camView does not show in PIX, I assume this is because it's not used in the pixel shader stage.

Where "correct" on the front is equal to what the associated variable should be (i.e. my bro = what i expect bmo to equal, etc...).

Are there some kind of alignment requirements that I'm missing? I've added many more and much larger variables to some of my other constant buffers in other shaders without any issues, but I've been racking my brain and code trying to figure out what I'm doing wrong here and can't see it...
Advertisement
Are there some kind of alignment requirements that I'm missing?
I'd guess that's exactly the problem. See Packing Rules for Constant Variables.

e.g. cameraPos will actually be padded out to the size of a float4 in this case.

This topic is closed to new replies.

Advertisement