<p>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 <em>does</em> try to look at it, it could trigger a GPU crash / TDR.</p>
<p>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.</p>
<p>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 <a href="https://microsoft.github.io/DirectX-Specs/d3d/ResourceBinding.html#null-descriptors" rel="nofollow noreferrer">D3D12 functional spec</a> for more.</p>

CC BY-SA 4.0
2020-10-19T20:08:41.627Z
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`)?
Matthias
CC BY-SA 4.0
2020-10-19T20:17:21.590Z
No, I meant that in addition to null root descriptors (root SRVs etc), also another thing that causes crashes is null/unbound descriptor tables.
Nathan Reed
CC BY-SA 4.0
2020-10-19T20:30:51.783Z
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.
Matthias
CC BY-SA 4.0
2020-10-19T21:06:28.713Z
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.
Nathan Reed
CC BY-SA 4.0
2020-10-19T17:07:51.867Z
2020-10-19T17:07:51.867Z
Nathan Reed
<p><strong>Unbound descriptor tables</strong></p>
<p>If a <code>D3D12_VERSIONED_ROOT_SIGNATURE_DESC</code> defines <em>N</em> <code>D3D12_ROOT_PARAMETER</code>s (with <code>ParameterType</code> set to <code>D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE</code>) that are each visible to a single (non-compute) shader stage, does each of these require a corresponding <code>ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable</code> invocation (with an allocated shader visible descriptor range) after binding the <code>ID3D12RootSignature</code> and <code>ID3D12PipelineState</code>, even if the latter does only use a subset of the (non-compute) shader stages (e.g., no geometry shader, etc.)? Stated differently, does <code>ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable</code> need to be invoked for root parameters associated with shader stages that are <strong>not</strong> defined for the <code>ID3D12PipelineState</code> <strong>but</strong> are part of the <code>ID3D12RootSignature</code>?</p>
<p><strong>Unbound descriptors</strong></p>
<p>If a shader uses say 2 SRVs, but up to 64 SRVs could be potentially bound for the <code>ID3D12RootSignature</code>, is it necessary that the 62 unused SRVs, which are part of the same shader visible descriptor range(s), are actually associated with an <strong>existing</strong> SRV of a resource that is still <strong>alive</strong> (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?</p>

<directx12>
Unbound descriptor tables and descriptors for fat root signatures
Matthias
# Unbound descriptor tables and descriptors for fat root signatures

(Asked by: username_0 on 2020-10-17)

**Unbound descriptor tables**

If a `D3D12_VERSIONED_ROOT_SIGNATURE_DESC` defines *N* `D3D12_ROOT_PARAMETER`s (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?

**Tags:** directx12


---

## 1 answers

### Answer by username_1 on 2020-10-19. Score: 1 | Accepted answer

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](https://microsoft.github.io/DirectX-Specs/d3d/ResourceBinding.html#null-descriptors) for more.

> **Comments:**
> **username_0**: 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`)?  
> **username_1**: No, I meant that in addition to null root descriptors (root SRVs etc), also another thing that causes crashes is null/unbound descriptor tables.  
> **username_0**: 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.  
> **username_1**: 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.  

---

