Nacho
Nacho

Reputation: 99

DX12 Descriptor Heaps management

So after watching the dx12 binding videos and reading through some docs, I'm not 100% sure if I understood correctly how to manage my heaps.

Let me explain what I wan't to achieve in my application: During the initialisation, I'll be filling two heaps, one holding Samplers and the other one holding SRV, CBV and UAV. Those heaps will contain all the resources the application will be using during its life time.

Now starts the interesting part. To build the Root Signatures, I'll be using for the most part Root Descriptor Tables.

As we know, a table will hold ranges, a range being a base shader slot, number of descriptors and other settings. Let me show you and example:

Root Parameters
0 - root_table 
1 - root_table

0 root_table
CBV b1
CBV b6
SRV t0
SRV t2

1 root_table
Sampler s1
Sampler s4

As shown in the example, there can be ranges that are non sequential (for example b0,b1,b2 and b3) but, during command list recording, we can only do:

ID3D12DescriptorHeaps* heaps[2] = {mCbvSrvUavHeap,mSamplerHeap};
mCmdList->SetDescriptorHeaps(2,heaps);

mCmdList->SetGraphicsRootDescriptorTable(0, mCbvSrvUavHeapGpuHanleStart);
mCmdList->SetGraphicsRootDescriptorTable(1, mSamplerHandleHanleStart);

That means that we will need to have the descriptors properly ordered in mCbvSrvUavHeap and mSamplerHeap.

For example:

mCbvSrvUavHeap 
CBV
CBV
SRV
SRV

Here is where the problem is for me. As I initially said, I'll be creating two big heaps with all the resource for the application, but, I cannot set those heaps to the command list as they will have other descriptors that won't be used!

How can I handle this? Do I need to make a new Heap containing only the descriptors I will be using?

Hope I explained it well!

Upvotes: 1

Views: 3027

Answers (1)

galop1n
galop1n

Reputation: 8824

You are understanding it wrong. A descriptor heap is not something immutable but an always changing object. When you bind a descriptor table, you are in fact binding it from any offset. Swapping descriptor heaps is a costly operation you want to avoid at all cost.

The idea is to prepare the descriptors in non GPU visible heaps ( as many as you like, they are merely a CPU allocated object ) and copy on demand into the GPU visible one in a ring buffer fashion way with CopyDescriptor or CopyDescriptorSimple.

Let say your shader use a table with 2 CBVs and 2 SRVs, they have to be continuous in the heap, so you will allocate from your heap an array of 4, you get a heap offset, copy the needed descriptors and bind it with SetGraphicsRootDescriptorTable.

One thing you will have to be careful is the life duration of the descriptor in you heap, as you cannot overwrite them until the GPU is done processing the commands using them. And last, if many shader share some common tables, from similar root signature, you can save on processing by factorizing the updates.

Upvotes: 3

Related Questions