Explicit bind slots (descriptor set bloat)

Started by
3 comments, last by MJP 6 years, 8 months ago

I wanted to get a gauge on how everyone is handling resource descriptors and bind slots in the new API. Under directx11 I would allow the compiler to generate its own bind slots, and look it up at runtime. I wanted to see if people using directx12/Villanova have switched to explicit slots for easier descriptor set management, or are still using the prior version, and burning through descriptors

Advertisement

I use explicit slots for DX11 and DX12 now. I used the D3D11 EffectFrameWork before to control it but found it easier to do explicit binding for DX12.

For materials I have 2 tables. One for programmer controlled entries (like noise, reflection, refraction etc..) and one for material assets. That way I only have to update the last table when changing materials.

Henning

The rootsig creates a mapping from root-descriptors/descriptor-table layouts, and the shader's bind slots (register assignment). You can have randomly scattered register assignments in your shader, but then have predicable/contiguous descriptor table layouts.

I do shader register assignment via code generation from a simple data definition. So that's automatic from the shader author's point of view, but slots are being manually specified from D3D's point of view. When defining the input resources for a shader, a shader author must group them into "resource lists", which become the descriptor table groupings later on.

As part of the shader compiler, I loop through all my possible shader programs (where a program is a set of PS/VS/*S), get its set of input resources, and keep a list of the unique sets. Each of these is used to generate a rootsig and instructions for building the tables used by that rootsig.

At first we let the compiler auto-assign the slots to resources, which matched how we did it in D3D11. We would then reflect the shader offline to get the set of textures/buffers that needed to be bound, and at runtime we would generate a matching descriptor table right before drawing. Now we use bindless via global unbounded descriptor tables, and those tables are all manually assigned a register space that matches the root signature.

This topic is closed to new replies.

Advertisement