Sign in to follow this  

Indexing into descriptor heaps with descriptor tables

Recommended Posts



I'm trying to wrap my head around making sense of descriptor tables and heaps to design a flexible root signature/resource mapping system. I'm a little lost in the weeds and would appreciate someone pointing me in the right direction. Here goes:


  1. So lets say I have two descriptor tables (CBV and SRV) in my root parameters - how do I allocate a descriptor heap properly so that there's enough storage for N and M ranges in the CBV and SRV respectively?
  2. Related to #1 - how is the index for the the descriptor tables into the heap specified?
  3. Related to #1, if I am able to allocate a large enough descriptor heap, is the full increment size just N or M times the handle increment size?
  4. Lastly, if I'm trying to draw a large amount geometry in batches that have unique resources, what's the most optimal descriptor table and heap configuration I should consider?



Share this post

Link to post
Share on other sites

As changing the descriptor heap is a costly operation on some hardware, especially inside a command list, one accepted behavior is to have a giant heap and deal with that. You can keep a part of it for static tables and the remaining is a giant ring buffer that get filled while you generate render commands.


Binding a descriptor table is nothing more than binding an offset into the heap.

auto handle = dHeap->GetGPUDescriptorHandleForHeapStart();
handle.ptr += tableOffset * device->GetDescriptorHandleIncrementSize(dHeapType);
// then binding
clist->SetComputeRootDescriptorTable( rootParam, handle );
// or 
clist->SetGraphicsRootDescriptorTable( rootParam, handle );

You can put things wherever you want, however you need, the only constraint is that writing descriptor is a CPU immediate operation, while the GPU will read them later on his own timeline. It means that you need to use fences to be sure that you are not gonna overwrite a descriptor before the GPU is done with it.


For the last question, It is hard to provide a magical root signature, it may depends on the hardware, but a rule of thumb, root constant, root srv/uav, then descriptor table in that order for performance because the later has an extra indirection.

Share this post

Link to post
Share on other sites
1 - as above, create a massive heap and write your own allocator(s) for allocating tables within it.
2 - when you set a table root parameter, you specify a heap offset of where your table data is.
3 - yes.
4 - I tailor my signatures to my shaders. Tables should be defined per frequency. e.g. if some resources are used by all batches, and others change per batch, then use two tables.

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