I am learning d3d develpoment recently.
For the triangle example, I add code about model, view matrix setting. Here I set model, view seperate.
There are 3 methods to do this.
- root constants
- root constant buffer
- cbv in descriptor table
There are no problem except using descriptor table for me.
For descriptor table, there are 3 ways to do. I want to practice them all to learn well-undertsanding of d3d coding.
- put
2
float4x4 in one constant buffer as 1 descriptor table. - put
1
float4x4 in each constant buffer, then as2
descriptor tables with each has1
descriptor range. - put
1
float4x4 in each constant buffer, then as1
descriptor table with2
descriptor ranges.
I have tried the method 1 & 3, but when i try method 2, I get screen flicker.
Here is my code of method 2 & 3 to comprare. Please help me to find the root casue.
create root signature
#ifdef TABLE_SEPERATE
/* 2 descriptor table, 2 cbvs*/
CD3DX12_ROOT_PARAMETER slotRootParameter[2];
CD3DX12_DESCRIPTOR_RANGE dscRange[2];
dscRange[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
dscRange[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);
slotRootParameter[0].InitAsDescriptorTable(1, &dscRange[0]);
slotRootParameter[1].InitAsDescriptorTable(1, &dscRange[1]);
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init(2, slotRootParameter, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
#else
/* 1 descriptor table, 2 cbvs*/
CD3DX12_ROOT_PARAMETER slotRootParameter[1];
CD3DX12_DESCRIPTOR_RANGE dscRange[2];
dscRange[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
dscRange[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);
slotRootParameter[0].InitAsDescriptorTable(2, &dscRange[0]);
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init(1, slotRootParameter, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
#endif
ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error;
ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
ThrowIfFailed(m_d3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
create descriptor heaps & constant view
ModelCB model;
ViewCB view;
DirectX::XMStoreFloat4x4(&model.model, XMMatrixTranspose(XMMatrixScaling(0.1, 0.1, 1.0)));
DirectX::XMStoreFloat4x4(&view.view, XMMatrixTranspose(XMMatrixScaling(0.5, 0.5, 1.0))); // For debugging, so do scaling first. easy to see effect.
m_pModelBuffer = new CUploadBufferResource<ModelCB>(m_d3d12Device.Get(), 1, true);
m_pViewBuffer = new CUploadBufferResource<ViewCB>(m_d3d12Device.Get(), 1, true);
m_pViewBuffer->CopyData(0, view);
m_pModelBuffer->CopyData(0, model);
D3D12_DESCRIPTOR_HEAP_DESC cbvHeapDesc;
cbvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
cbvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
cbvHeapDesc.NumDescriptors = 2;
cbvHeapDesc.NodeMask = 0;
ThrowIfFailed(m_d3d12Device->CreateDescriptorHeap(&cbvHeapDesc, IID_PPV_ARGS(&m_cbvHeap)));
m_ModelBufferView.BufferLocation = m_pModelBuffer->Resouce()->GetGPUVirtualAddress();
m_ModelBufferView.SizeInBytes = m_pModelBuffer->GetElementByteSize();
m_ViewBufferView.BufferLocation = m_pViewBuffer->Resouce()->GetGPUVirtualAddress();
m_ViewBufferView.SizeInBytes = m_pViewBuffer->GetElementByteSize();
UINT cbv_srv_uavDescriptorSize = m_d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
auto handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_cbvHeap->GetCPUDescriptorHandleForHeapStart());
handle.Offset(0, cbv_srv_uavDescriptorSize);
m_d3d12Device->CreateConstantBufferView(&m_ModelBufferView, handle);
cbv_srv_uavDescriptorSize = m_d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_cbvHeap->GetCPUDescriptorHandleForHeapStart());
handle.Offset(1, cbv_srv_uavDescriptorSize);
m_d3d12Device->CreateConstantBufferView(&m_ViewBufferView, handle);
shader hlsl
cbuffer V : register( b1 )
{
float4x4 view;
};
cbuffer M : register(b0)
{
float4x4 model;
};
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
PSInput VSMain(float4 position : POSITION, float4 color : COLOR)
{
PSInput result;
result.position = mul(mul(position, model), view);
result.color = color;
return result;
}
float4 PSMain(PSInput input) : SV_TARGET
{
return input.color;
}
code in OnRender
1 descriptor table, 2 cbvs [Work]
ID3D12DescriptorHeap* descHeaps[] = { m_cbvHeap.Get() };
m_commandList->SetDescriptorHeaps(_countof(descHeaps), descHeaps);
m_commandList->SetPipelineState(m_pipelineState.Get());
m_commandList->SetGraphicsRootSignature(m_rootSignature.Get());
UINT cbv_srv_uavDescriptorSize = m_d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
auto handle = CD3DX12_GPU_DESCRIPTOR_HANDLE(m_cbvHeap->GetGPUDescriptorHandleForHeapStart());
handle.Offset(0, cbv_srv_uavDescriptorSize);
m_commandList->SetGraphicsRootDescriptorTable(0, handle);
2 descriptor table. 2 cbvs [NOT WORK]
ID3D12DescriptorHeap* descHeaps[] = { m_cbvHeap.Get() };
m_commandList->SetDescriptorHeaps(_countof(descHeaps), descHeaps);
m_commandList->SetPipelineState(m_pipelineState.Get());
m_commandList->SetGraphicsRootSignature(m_rootSignature.Get());
UINT cbv_srv_uavDescriptorSize = m_d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
auto handle = CD3DX12_GPU_DESCRIPTOR_HANDLE(m_cbvHeap->GetGPUDescriptorHandleForHeapStart());
handle.Offset(0, cbv_srv_uavDescriptorSize);
m_commandList->SetGraphicsRootDescriptorTable(0, handle);
handle = CD3DX12_GPU_DESCRIPTOR_HANDLE(m_cbvHeap->GetGPUDescriptorHandleForHeapStart());
handle.Offset(1, cbv_srv_uavDescriptorSize);
m_commandList->SetGraphicsRootDescriptorTable(1, handle);
```