Unbound descriptor tables

If a D3D12_VERSIONED_ROOT_SIGNATURE_DESC defines N D3D12_ROOT_PARAMETERs (with ParameterType set to D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) that are each visible to a single (non-compute) shader stage, does each of these require a corresponding ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable invocation (with an allocated shader visible descriptor range) after binding the ID3D12RootSignature and ID3D12PipelineState, even if the latter does only use a subset of the (non-compute) shader stages (e.g., no geometry shader, etc.)? Stated differently, does ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable need to be invoked for root parameters associated with shader stages that are not defined for the ID3D12PipelineState but are part of the ID3D12RootSignature?

Unbound descriptors

If a shader uses say 2 SRVs, but up to 64 SRVs could be potentially bound for the ID3D12RootSignature, is it necessary that the 62 unused SRVs, which are part of the same shader visible descriptor range(s), are actually associated with an existing SRV of a resource that is still alive (which is not automatically guaranteed if the shader visible descriptor heaps are used in a ring buffer fashion, as initially the descriptors are unused and later on could be reused)? Or does one for example need to use an SRV of a dummy resource that is kept alive?


Everything is allowed to be left unbound / invalid / uninitialized as long as the shader doesn't try to look at it. However, if the shader does try to look at it, it could trigger a GPU crash / TDR.

In practice, it may be a good idea to explicitly clear out descriptors that you know aren't going to be valid: either setting them to a null descriptor, or pointing to a dummy resource. Loading/sampling from a null SRV/UAV descriptor in a descriptor table is defined to just return 0 and not crash. Likewise, stores to a null UAV descriptor are dropped on the floor without crashing.

However, this guarantee doesn't apply to descriptors directly in the root signature; trying to load/sample from a null root descriptor can crash the GPU. Likewise trying to read from a null descriptor table can crash. See the D3D12 functional spec for more.

| improve this answer | |
  • $\begingroup$ Shouldn't the second to last line read: Likewise trying to read from a null root descriptor can crash., because if I understand correctly descriptors directly in the root signature refers to D3D12_ROOT_DESCRIPTOR (as opposed to D3D12_ROOT_DESCRIPTOR_TABLE)? $\endgroup$ – Matthias Oct 19 at 20:08
  • 1
    $\begingroup$ No, I meant that in addition to null root descriptors (root SRVs etc), also another thing that causes crashes is null/unbound descriptor tables. $\endgroup$ – Nathan Reed Oct 19 at 20:17
  • $\begingroup$ Wasn't that already assumed by the first paragraph: if the shader looks at a CBV/SRV/UAV the associated root descriptor or root descriptor table needs to be bound, and only in case of the latter it may point to a null descriptor with a matching format (and the other contiguous descriptors in that same table can be unbound / invalid / uninitialized if not being looked at in the shader). I was a bit confused with a null descriptor table as SetGraphicsRootDescriptorTable expects the base offset descriptor. $\endgroup$ – Matthias Oct 19 at 20:30
  • $\begingroup$ AFAIK nothing prevents you from setting a null descriptor to SetGraphicsRootDescriptorTable as well. I'm just pointing out that if a shader attempts to retrieve a descriptor out of a null descriptor table then bad things may happen, there isn't a guranteed fallback for that case in the way that there is for e.g. loading from a buffer described by a non-root null descriptor. Also note the difference between a null descriptor and one that's invalid (but non-null) by virtue of pointing to an invalid memory address / a resource that's been deleted or unmapped, etc. $\endgroup$ – Nathan Reed Oct 19 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.