Sign in to follow this  
stu_pidd_cow

[D3D11] Constant buffers aren't working properly.

Recommended Posts

stu_pidd_cow    3136
I'm trying to get a good understanding of shaders and such, and I'm having trouble getting constant buffers working. This is the struct I'm sending:

[code]
struct CBPerMesh
{
D3DXVECTOR3 ObjectPosition;
D3DXVECTOR3 CameraPosition;
D3DXVECTOR2 CameraZoom;
};
[/code]

This is the vertex shader (I don't think the pixel shader has anything to do with my problem):

[code]struct VS_INPUT
{
float3 position : POSITION;
float2 texcoord : TEXCOORD;
};

struct VS_OUTPUT
{
float4 position : SV_POSITION;
float2 texcoord : TEXCOORD;
};

cbuffer PerMesh
{
float3 ObjectPosition;
float3 CameraPosition;
float2 CameraZoom;
};

VS_OUTPUT vsMain( VS_INPUT v )
{
VS_OUTPUT o = (VS_OUTPUT)0;

o.position.x = ( v.position.x + CameraPosition.x ) / CameraZoom.x;
o.position.y = ( v.position.y + CameraPosition.y ) / CameraZoom.y;
o.position.z = 0.0f;
o.position.w = 1.0f;
o.texcoord = v.texcoord;

return o;
}
[/code]

This is how I create the constant buffer:

[code]
// setup creation information
D3D11_BUFFER_DESC cbDesc;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.ByteWidth = sizeof( ConstantBuffer );
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;
cbDesc.Usage = D3D11_USAGE_DYNAMIC;

// create the buffer
ID3D11Buffer* CBuffer = NULL;
D3DDevice->CreateBuffer( &cbDesc, NULL, &CBuffer );
[/code]

And this is to update the constant buffer:

[code]
// ConstantBuffer is a CBPerMesh
// CBuffer is the ID3D11Buffer*

D3D11_MAPPED_SUBRESOURCE MSData;
if( SUCCEEDED( D3DContext->Map( CBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MSData ) ) )
{
// copy data over to constant buffer
memcpy_s( MSData.pData, MSData.RowPitch, ConstantBuffer, sizeof( ConstantBuffer ) );

D3DContext->Unmap( CBuffer, 0 );
}

else
return false;

D3DContext->VSSetConstantBuffers( 0, 1, &CBuffer );

return true;
[/code]

Everything compiles and runs fine, but it seems that only part of the constant buffer is being updated. When I debug it it PIX, it appears that everything has been updated, but the only changes that I visually see is with CameraPosition.y (from CBPerMesh)

Sorry about all the code, but I'm having trouble narrowing down the problem.

Much appreciated.

Share this post


Link to post
Share on other sites
MJP    19788
Constant buffers have alignment rules than are different than the default alignment rules for 32-bit or 64-bit C++. Those rules are outlined here: [url="http://msdn.microsoft.com/en-us/library/bb509632%28v=vs.85%29.aspx"]http://msdn.microsoft.com/en-us/library/bb509632%28v=vs.85%29.aspx[/url]

In your case, the second and third members of your CBPerMesh struct will be aligned incorrectly in your C++ struct. To make it properly line up with your constant buffer, you can declare your struct like this:
[code]
// For aligning to float4 boundaries
#define Float4Align __declspec(align(16))

struct CBPerMesh
{
Float4Align D3DXVECTOR3 ObjectPosition;
Float4Align D3DXVECTOR3 CameraPosition;
Float4Align D3DXVECTOR2 CameraZoom;
};
[/code]

Share this post


Link to post
Share on other sites
pcmaster    982
I just wonder if [font="Courier New"]__declspec(align(16))[/font] works with both heap and stack allocated objects. Does it? 'Cuz I remember using something like

[code]struct __declspec(align(16)) CACHEALIGNED16 {
void* operator new(size_t size) { return _aligned_malloc(size, 16); }
void operator delete (void* mem) { _aligned_free(mem); }
};[/code]
and all my aligned classes/structs inherited from this object.Or is it enough to have a single (the first) member in a class aligned and it always gets aligned? This is a pure C++ question.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this