Constant buffer members access the same memory

0

I'm using a constant buffer to pass data to my shaders at every frame, and I'm running into an issue where the values of some of the members of the buffer point to the same memory.

When I use the Visual Studio 2012 debugging tools, it looks like the data is being set in the buffer more or less correctly:

0   [0x00000000-0x00000003] |                 +0
1   [0x00000004-0x00000007] |                 +1
2   [0x00000008-0x0000000b] |                 +1
3   [0x0000000c-0x0000000f] |                 +1
4   [0x00000010-0x00000013] |        +0.78539819
5   [0x00000014-0x00000017] |         +1.1760513
6   [0x00000018-0x0000001b] |                 +0
7   [0x0000001c-0x0000001f] |                 +1

The problem is that when I debug the shader, the sunAngle and phaseFunction both have the same value - specifically 0.78539819, which should be the value of sunAngle only. It does change to 1.1760513 if I swap the order of the two floats, but both will still be the same. I thought I'd packed everything together correctly, but am I missing how to define exactly what constants are in each part of the buffer?

Here's the C++ structure I'm using:

struct SunData {
    DirectX::XMFLOAT4 sunPosition;
    float sunAngle;
    float phaseFunctionResult;
};

And the shader buffer looks like this:

// updated as the sun moves through the sky
cbuffer sunDependent : register( b1 )
{
    float4 sunPosition;
    float sunAngle;              // theta
    float phaseFunctionResult;   // F( theta, g )
}

Here's the code I'm using to initialize the buffer:

XMVECTOR pos =  XMVectorSet( 0, 1, 1, 1 );
XMStoreFloat3( &_sunPosition, pos );

XMStoreFloat4( &_sun.sunPosition, pos );
_sun.sunAngle = XMVectorGetX(
    XMVector3AngleBetweenVectors( pos, XMVectorSet( 0, 1, 0, 0 ) )
);

_sun.phaseFunctionResult = _planet.phaseFunction( _sun.sunAngle );

// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = sizeof( SunData ) + 8;
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;

// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = &_sun;
data.SysMemPitch = 0;
data.SysMemSlicePitch = 0;

// Create the buffer.
ID3D11Buffer *constantBuffer = nullptr;
HRESULT hr = _d3dDevice->CreateBuffer(
    &cbDesc,
    &data,
    &constantBuffer
);

assert( SUCCEEDED( hr ) );

// Set the buffer.
_d3dDeviceContext->VSSetConstantBuffers( 1, 1, &constantBuffer );
_d3dDeviceContext->PSSetConstantBuffers( 1, 1, &constantBuffer );
Release( constantBuffer );

And here's the pixel shader that's using the values:

float4 main( in ATMOS_PS_INPUT input ) : SV_TARGET
{
    float R = sunAngle * sunPosition.x * sunIntensity.x
        * attenuationCoefficient.x
        * phaseFunctionResult;

    return float4( R, 1, 1, 1 );
}
c++
directx
buffer
hlsl
directx-11
asked on Stack Overflow Feb 16, 2013 by derekerdmann • edited Feb 16, 2013 by derekerdmann

1 Answer

0

It looks like a padding issue like in this question: Question

All constant buffers should be sized to be dividble by sizeof(four-component vector) (doc)

answered on Stack Overflow Feb 18, 2013 by Gnietschow • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0