Currently going through microsofts examples, it is noticable, that only one cbv_srv_uav heap is used per commandlist (+ maybe on additional sampler heap).
Is it possible to use multiple heaps per CommandList?
So i setup heap and ranges
this->mRSVHeap = new urd::DescriptorHeap(
*this->mDevice,
urd::DescriptorHeapType::CBV_SRV_UAV,
1, // shader visible
2); // space for 2 descriptors (2 textures)
this->mConstHeap = new urd::DescriptorHeap(
*this->mDevice,
urd::DescriptorHeapType::CBV_SRV_UAV,
1, // shader visible
1); // space for 1 descriptor
urd::DescriptorRange ranges[3];
ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0); // first and second descriptor in rsv heap (t0, t1)
ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); // first descriptor in cbv heap (b0)
ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 2); // same texture used as first range (again first descriptor in rsv, accessable by t2)
after that i define the descriptor tables
rootParam[0].InitDescTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
rootParam[1].InitDescTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_ALL);
rootParam[2].InitDescTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_PIXEL);
So i create shaderResourceViews for texture 1 and 2 at cpu offset 0 and 1 in rsv heap and a constantbufferview for the constant buffer at cpu offset 0 in the cbv heap
like this:
D3D12_CPU_DESCRIPTOR_HANDLE handle = this->ConstHeap->GetCPUDescriptorHandleForHeapStart();
handle.ptr += index * SIZE_OF_ONE_DESCRIPTOR_CBV_SRV_UAV_TYPE;
CreateConstantBufferView(&desc, handle)
now its time to tell the commandlist to reference those heaps
ID3D12DescriptorHeap* ppHeaps[] = { this->mRSVHeap.Get(), this->mConstHeap.Get() };
this->mCommandList->GetRef()->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps);
after this, closing the commandlist always throws.
ThrowIfFailed(this->mCommandList->Close());
Here is how i tell the commandlist which heap for which table:
this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(0, this->mRSVHeap->GetGPUHeapAddressAtOffset(0));
this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(1, this->mConstHeap->GetGPUHeapAddressAtOffset(0));
this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(2, this->mRSVHeap->GetGPUHeapAddressAtOffset(0));
It works fine if i describe all the objects into one single descriptor heap (like in the examples) and just use different offsets of that heap.
Debug Output:
D3D12 ERROR: ID3D12CommandList::SetDescriptorHeaps: pDescriptorHeaps[1] sets a descriptor heap type that appears earlier in the pDescriptorHeaps array. Only one of any given descriptor heap type can be set at a time. [ EXECUTION ERROR #554: SET_DESCRIPTOR_HEAP_INVALID] D3D12 ERROR: CCommandList::SetGraphicsRootDescriptorTable: No CBV_SRV_UAV descriptor heap is currently set on the command list so setting a root descriptor table of CBV_SRV_UAV handles is invalid. [ EXECUTION ERROR #708: SET_DESCRIPTOR_TABLE_INVALID] D3D12 ERROR: CCommandList::SetGraphicsRootDescriptorTable: No CBV_SRV_UAV descriptor heap is currently set on the command list so setting a root descriptor table of CBV_SRV_UAV handles is invalid. [ EXECUTION ERROR #708: SET_DESCRIPTOR_TABLE_INVALID] D3D12 ERROR: CCommandList::SetGraphicsRootDescriptorTable: No CBV_SRV_UAV descriptor heap is currently set on the command list so setting a root descriptor table of CBV_SRV_UAV handles is invalid. [ EXECUTION ERROR #708: SET_DESCRIPTOR_TABLE_INVALID]
The restriction is that only one heap of each type (CBV/SRV/UAV and Samplers) may be set at any one time. Thus only two descriptor heaps can ever be set at one time.
However, it's important to note that the descriptor heaps set may vary during a command list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With