# DirectX 12 Constant Buffer Binding

I can't really seem to figure out how to bind two constant buffers to my shaders. I have them described like so. One in slot b0 and the other in slot b1.

cbuffer WVPData : register(b0)
{
matrix model;
matrix view;
matrix projection;
};

cbuffer DirLightData : register(b1)
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Direction;
};


Then for the root signature it's described like so.

CD3DX12_DESCRIPTOR_RANGE range[2];
CD3DX12_ROOT_PARAMETER parameter[1];

range[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
range[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);

D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // Only the input assembler stage needs access to the constant buffer.

CD3DX12_ROOT_SIGNATURE_DESC descRootSignature;
descRootSignature.Init(_countof(parameter), parameter, 0, nullptr, rootSignatureFlags);

ComPtr<ID3DBlob> pSignature;
ComPtr<ID3DBlob> pError;
DX::ThrowIfFailed(d3dDevice->CreateRootSignature(0, pSignature->GetBufferPointer(), pSignature->GetBufferSize(), IID_PPV_ARGS(&mRootSignature)));


I believe that's correct. I think the problem I have is when I create the constant buffer and the cbv below. Specifically right under the "Describe and create the constant buffer view." comment. I don't really understand what's going on.

// Create a descriptor heap for the constant buffers.
{
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
heapDesc.NumDescriptors = 2;
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
// This flag indicates that this descriptor heap can be bound to the pipeline and that descriptors contained in it can be referenced by a root table.
DX::ThrowIfFailed(d3dDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&mCbvHeap)));

mCbvHeap->SetName(L"Constant Buffer View Descriptor Heap");
}

// Create the constant buffer.
DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(CAlignedWVPDataSize),
nullptr,
IID_PPV_ARGS(&mWVPConstantBuffer)));

DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(CAlignedDirLightDataSize),
nullptr,
IID_PPV_ARGS(&mDirLightConstantBuffer)));

// Describe and create a constant buffer view.
D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc[2];// = {};
cbvDesc[0].SizeInBytes = CAlignedWVPDataSize;
cbvDesc[1].SizeInBytes = CAlignedDirLightDataSize;

CD3DX12_CPU_DESCRIPTOR_HANDLE cbvHandle0(mCbvHeap->GetCPUDescriptorHandleForHeapStart(), 0, 0);
d3dDevice->CreateConstantBufferView(cbvDesc, cbvHandle0);

CD3DX12_CPU_DESCRIPTOR_HANDLE cbvHandle1(mCbvHeap->GetCPUDescriptorHandleForHeapStart(), d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV), 1);
d3dDevice->CreateConstantBufferView(cbvDesc, cbvHandle1);

// Initialize and map the constant buffers. We don't unmap this until the
// app closes. Keeping things mapped for the lifetime of the resource is okay.
DX::ThrowIfFailed(mWVPConstantBuffer->Map(0, nullptr, reinterpret_cast<void**>(&mMappedWVPBuffer)));
memcpy(mMappedWVPBuffer, &mWVPData, sizeof(mWVPData));

DX::ThrowIfFailed(mDirLightConstantBuffer->Map(0, nullptr, reinterpret_cast<void**>(&mMappedDirLightBuffer)));
memcpy(mMappedDirLightBuffer, &mDirLightData, sizeof(mDirLightData));


Note: Slot b0 works perfect. I can change world view projection data just fine. But b1 does not work at all. What am I doing wrong?

d3dDevice->CreateConstantBufferView(cbvDesc, cbvHandle1);

The first parameter should be &cbvDesc[1]. As it is now, you're setting up two copies of cbvDesc[0].
Also, it looks like you've reversed the second and third arguments to the cbvHandle1 constructor: the second argument should be the offset (1) and the third should be the increment size. Not that it really matters, since those two values just get multiplied together anyway.