UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
D3D12DescriptorCache.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "HAL/Platform.h"
6#include "Containers/Set.h"
9#include "D3D12RHICommon.h"
10#include "D3D12Descriptors.h"
11
21
30
31class FD3D12SyncPoint;
33
34// Like a TMap<KeyType, ValueType>
35// Faster lookup performance, but possibly has false negatives
36template<typename KeyType, typename ValueType>
38{
39public:
46
47 void Add(const KeyType& Key, const ValueType& Value)
48 {
49 uint32 Index = GetIndex(Key);
50
51 Entry& Pair = Table[Index];
52
53 Pair.Valid = true;
54 Pair.Key = Key;
55 Pair.Value = Value;
56 }
57
58 ValueType* Find(const KeyType& Key)
59 {
60 uint32 Index = GetIndex(Key);
61
62 Entry& Pair = Table[Index];
63
64 if (Pair.Valid &&
65 (Pair.Key == Key))
66 {
67 return &Pair.Value;
68 }
69 else
70 {
71 return nullptr;
72 }
73 }
74
75 void Reset()
76 {
77 for (int32 i = 0; i < Table.Num(); i++)
78 {
79 Table[i].Valid = false;
80 }
81 }
82
83private:
84 uint32 GetIndex(const KeyType& Key)
85 {
86 uint32 Hash = GetTypeHash(Key);
87
88 return Hash % static_cast<uint32>(Table.Num());
89 }
90
91 struct Entry
92 {
93 bool Valid;
94 KeyType Key;
95 ValueType Value;
96 };
97
98 TArray<Entry> Table;
99};
100
102{
105
106 inline bool operator==(const FD3D12SamplerArrayDesc& rhs) const
107 {
109 check(rhs.Count <= UE_ARRAY_COUNT(rhs.SamplerID));
110
111 if (Count != rhs.Count)
112 {
113 return false;
114 }
115 else
116 {
117 // It is safe to compare pointers, because samplers are kept alive for the lifetime of the RHI
118 return 0 == FMemory::Memcmp(SamplerID, rhs.SamplerID, sizeof(SamplerID[0]) * Count);
119 }
120 }
121};
122
125
127
129{
132 {
133 FMemory::Memcpy(&Key, &KeyIn, sizeof(Key));//Memcpy to avoid alignement issues
134 FMemory::Memcpy(CPUTable, Table, Key.Count * sizeof(D3D12_CPU_DESCRIPTOR_HANDLE));
135 }
136
138 D3D12_CPU_DESCRIPTOR_HANDLE CPUTable[MAX_SAMPLERS]{};
139
140 // This will point to the table start in the global heap
142};
144
145
146struct FD3D12UniqueSamplerTableKeyFuncs : BaseKeyFuncs<FD3D12UniqueSamplerTable, FD3D12UniqueSamplerTable, /*bInAllowDuplicateKeys = */ false>
147{
150
155 {
156 return Element;
157 }
158
163 {
164 return A.Key == B.Key;
165 }
166
169 {
170 return GetTypeHash(Key.Key);
171 }
172};
173
175
178{
179public:
182
184
185 FORCEINLINE D3D12_CPU_DESCRIPTOR_HANDLE GetCPUSlotHandle(uint32 Slot) const { return Heap->GetCPUSlotHandle(Slot); }
187
188 // Call this to reserve descriptor heap slots for use by the command list you are currently recording. This will wait if
189 // necessary until slots are free (if they are currently in use by another command list.) If the reservation can be
190 // fulfilled, the index of the first reserved slot is returned (all reserved slots are consecutive.) If not, it will
191 // throw an exception.
192 bool CanReserveSlots(uint32 NumSlots);
194
197
198 // Function which can/should be implemented by the derived classes
199 virtual bool RollOver() = 0;
200 virtual void HeapLoopedAround() { }
201 virtual void OpenCommandList () { }
202 virtual void CloseCommandList() { }
203 virtual uint32 GetTotalSize() { return Heap->GetNumDescriptors(); }
204
205protected:
206 // Keeping this ptr around is basically just for lifetime management
208
209 // This index indicate where the next set of descriptors should be placed *if* there's room
211
212 // Indicates the last free slot marked by the command list being finished
214
215 // Does the heap support loop around allocations
216 const bool bCanLoopAround;
217};
218
221{
222public:
224
225 void Init(uint32 TotalSize);
226
227 // Override FD3D12OnlineHeap functions
228 virtual bool RollOver() final override;
229
231
233
234private:
235 TSharedPtr<FD3D12SamplerSet> UniqueDescriptorTables;
236 FRWLock Mutex;
237};
238
241{
242public:
244
245 // Override FD3D12OnlineHeap functions
246 virtual bool RollOver() final override;
247 virtual void OpenCommandList() final override;
248 virtual uint32 GetTotalSize() final override
249 {
250 return CurrentBlock ? CurrentBlock->Size : 0;
251 }
252
253private:
254 // Allocate a new block from the global heap - return true if allocation succeeds
255 bool AllocateBlock();
256
257 FD3D12OnlineDescriptorBlock* CurrentBlock = nullptr;
258
259 FD3D12DescriptorCache& DescriptorCache;
260 FD3D12CommandContext& Context;
261};
262
263
268{
269public:
271
272 // Allocate the actual overflow heap
274
275 // Override FD3D12OnlineHeap functions
276 virtual bool RollOver() final override;
277 virtual void HeapLoopedAround() final override;
278 virtual void OpenCommandList () final override;
279 virtual void CloseCommandList() final override;
280
281private:
282 struct FSyncPointEntry
283 {
284 FD3D12SyncPointRef SyncPoint;
285 uint32 LastSlotInUse = 0;
286 };
287 TQueue<FSyncPointEntry> SyncPoints;
288
289 struct FPoolEntry
290 {
292 FD3D12SyncPointRef SyncPoint;
293 };
294 FPoolEntry Entry {};
295 TQueue<FPoolEntry> ReclaimPool;
296
297 FD3D12DescriptorCache& DescriptorCache;
298 FD3D12CommandContext& Context;
299
300 void RecycleSlots();
301};
302
304{
305 None = 0,
306 ForceChanged = 1 << 0,
307 Bindless = 1 << 1,
308};
310
312{
313public:
316
318
319 inline FD3D12OnlineHeap* GetCurrentViewHeap() const { return CurrentViewHeap; }
320 inline FD3D12OnlineHeap* GetCurrentSamplerHeap() const { return CurrentSamplerHeap; }
321
322 ID3D12DescriptorHeap* GetLastSetViewHeap() const { return LastSetViewHeap; }
323
324 // Checks if the specified descriptor heap has been set on the current command list.
326 {
327 return (pHeap == LastSetViewHeap) || (pHeap == LastSetSamplerHeap);
328 }
329
330 // Notify the descriptor cache every time you start recording a command list.
331 // This sets descriptor heaps on the command list and indicates the current fence value which allows
332 // us to avoid querying DX12 for that value thousands of times per frame, which can be costly.
333 void OpenCommandList();
334 void CloseCommandList();
335
336 // ------------------------------------------------------
337 // end Descriptor Slot Reservation stuff
338
341
345
349
352
354
358
362
365
367 {
368 return CurrentSamplerHeap != &LocalSamplerHeap;
369 }
370
372 {
373 return *LocalSamplerSet.Get();
374 }
375
376 // Sets the current descriptor tables on the command list and marks any descriptor tables as dirty if necessary.
377 // Returns true if one of the heaps actually changed, false otherwise.
379
380
381#if PLATFORM_SUPPORTS_BINDLESS_RENDERING
382 bool CouldUseBindless() const { return bCouldUseBindless; }
383 bool IsFullyBindless() const { return bFullyBindless; }
384#else
385 constexpr bool CouldUseBindless() const { return false; }
386 constexpr bool IsFullyBindless() const { return false; }
387#endif
388
389#if PLATFORM_SUPPORTS_BINDLESS_RENDERING
391 {
393 }
394
396 {
398 }
399
401 {
403 }
404
405 bool IsUsingBindlessHeap() const
406 {
408 }
409#endif
410
411protected:
414
415private:
416 // The previous view and sampler heaps set on the current command list.
417 ID3D12DescriptorHeap* LastSetViewHeap = nullptr;
418 ID3D12DescriptorHeap* LastSetSamplerHeap = nullptr;
419
420 FD3D12OnlineHeap* CurrentViewHeap = nullptr;
421 FD3D12OnlineHeap* CurrentSamplerHeap = nullptr;
422
423 FD3D12LocalOnlineHeap* LocalViewHeap = nullptr;
424 FD3D12LocalOnlineHeap LocalSamplerHeap;
425 FD3D12SubAllocatedOnlineHeap SubAllocatedViewHeap;
426
427 FD3D12SamplerMap SamplerMap;
428
430
431 TSharedPtr<FD3D12SamplerSet> LocalSamplerSet;
432 bool bUsingExplicitCacheHeaps = false;
433 bool bExplicitViewHeapIsBindless = false;
434 bool bLocalSamplerHeapOpen = false;
435 bool bUsingViewHeap = true;
436
437 uint32 NumLocalViewDescriptors = 0;
438
439#if PLATFORM_SUPPORTS_BINDLESS_RENDERING
440 bool bCouldUseBindless = false;
441 bool bFullyBindless = false;
442
443 bool bLastSetHeapsBindless = false;
445
448#endif
449};
@ Valid
Definition AndroidInputInterface.h:103
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FD3D12ConservativeMap< FD3D12SamplerArrayDesc, D3D12_GPU_DESCRIPTOR_HANDLE > FD3D12SamplerMap
Definition D3D12DescriptorCache.h:126
uint32 GetTypeHash(const D3D12_SAMPLER_DESC &Desc)
Definition D3D12State.cpp:213
ED3D12SetDescriptorHeapsFlags
Definition D3D12DescriptorCache.h:304
TSet< FD3D12UniqueSamplerTable, FD3D12UniqueSamplerTableKeyFuncs > FD3D12SamplerSet
Definition D3D12DescriptorCache.h:174
uint32 SamplerSlotMask
Definition D3D12RHICommon.h:44
uint16 CBVSlotMask
Definition D3D12RHICommon.h:29
uint32 SRVSlotMask
Definition D3D12RHICommon.h:40
uint16 UAVSlotMask
Definition D3D12RHICommon.h:47
#define MAX_SAMPLERS
Definition D3D12RHI.h:18
#define ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:6
void Init()
Definition LockFreeList.h:4
EShaderFrequency
Definition RHIDefinitions.h:202
ERHIDescriptorHeapType
Definition RHIDefinitions.h:1338
#define UE_ARRAY_COUNT(array)
Definition UnrealTemplate.h:212
uint32 Size
Definition VulkanMemory.cpp:4034
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition D3D12CommandContext.h:513
Definition D3D12DescriptorCache.h:38
void Reset()
Definition D3D12DescriptorCache.h:75
void Add(const KeyType &Key, const ValueType &Value)
Definition D3D12DescriptorCache.h:47
FD3D12ConservativeMap(uint32 Size)
Definition D3D12DescriptorCache.h:40
ValueType * Find(const KeyType &Key)
Definition D3D12DescriptorCache.h:58
Definition D3D12View.h:435
Definition D3D12DescriptorCache.h:312
bool SwitchToContextLocalViewHeap()
Definition D3D12DescriptorCache.cpp:768
void OpenCommandList()
Definition D3D12DescriptorCache.cpp:157
const FD3D12DefaultViews & DefaultViews
Definition D3D12DescriptorCache.h:413
FD3D12CommandContext & Context
Definition D3D12DescriptorCache.h:412
void SetConstantBufferViews(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12ConstantBufferCache &Cache, CBVSlotMask SlotsNeededMask, uint32 Count, uint32 &HeapSlot)
Definition D3D12DescriptorCache.cpp:539
constexpr bool IsFullyBindless() const
Definition D3D12DescriptorCache.h:386
FD3D12OnlineHeap * GetCurrentViewHeap() const
Definition D3D12DescriptorCache.h:319
bool IsHeapSet(ID3D12DescriptorHeap *const pHeap) const
Definition D3D12DescriptorCache.h:325
FD3D12DescriptorCache()=delete
void SetVertexBuffers(FD3D12VertexBufferCache &Cache)
Definition D3D12DescriptorCache.cpp:207
constexpr bool CouldUseBindless() const
Definition D3D12DescriptorCache.h:385
ID3D12DescriptorHeap * GetLastSetViewHeap() const
Definition D3D12DescriptorCache.h:322
D3D12_GPU_DESCRIPTOR_HANDLE BuildUAVTable(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12UnorderedAccessViewCache &Cache, const UAVSlotMask &SlotsNeededMask, uint32 Count, uint32 &HeapSlot)
Definition D3D12DescriptorCache.cpp:226
void SetRootConstantBuffers(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12ConstantBufferCache &Cache, CBVSlotMask SlotsNeededMask, FD3D12StateCache *StateCache)
Definition D3D12DescriptorCache.cpp:667
FD3D12SamplerSet & GetLocalSamplerSet()
Definition D3D12DescriptorCache.h:371
bool SetDescriptorHeaps(ED3D12SetDescriptorHeapsFlags Flags)
Definition D3D12DescriptorCache.cpp:71
bool UsingGlobalSamplerHeap() const
Definition D3D12DescriptorCache.h:366
void SwitchToGlobalSamplerHeap()
Definition D3D12DescriptorCache.cpp:815
D3D12_GPU_DESCRIPTOR_HANDLE BuildSamplerTable(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12SamplerStateCache &Cache, const SamplerSlotMask &SlotsNeededMask, uint32 Count, uint32 &HeapSlot)
Definition D3D12DescriptorCache.cpp:333
bool SwitchToContextLocalSamplerHeap()
Definition D3D12DescriptorCache.cpp:800
void SetSamplerTable(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12SamplerStateCache &Cache, uint32 SlotsNeeded, const D3D12_GPU_DESCRIPTOR_HANDLE &BindDescriptor)
Definition D3D12DescriptorCache.cpp:415
void SetUAVTable(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12UnorderedAccessViewCache &Cache, uint32 SlotsNeeded, const D3D12_GPU_DESCRIPTOR_HANDLE &BindDescriptor)
Definition D3D12DescriptorCache.cpp:269
void SetRenderTargets(FD3D12RenderTargetView **RenderTargetViewArray, uint32 Count, FD3D12DepthStencilView *DepthStencilTarget)
Definition D3D12DescriptorCache.cpp:296
~FD3D12DescriptorCache()
Definition D3D12DescriptorCache.cpp:38
bool HeapRolledOver(ERHIDescriptorHeapType InHeapType)
Definition D3D12DescriptorCache.cpp:13
void PrepareBindlessViews(EShaderFrequency ShaderStage, TConstArrayView< FD3D12ShaderResourceView * > SRVs, TConstArrayView< FD3D12UnorderedAccessView * > UAVs)
Definition D3D12DescriptorCache.cpp:512
void HeapLoopedAround(ERHIDescriptorHeapType InHeapType)
Definition D3D12DescriptorCache.cpp:19
void CloseCommandList()
Definition D3D12DescriptorCache.cpp:185
FD3D12OnlineHeap * GetCurrentSamplerHeap() const
Definition D3D12DescriptorCache.h:320
void SetSRVTable(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12ShaderResourceViewCache &Cache, uint32 SlotsNeeded, const D3D12_GPU_DESCRIPTOR_HANDLE &BindDescriptor)
Definition D3D12DescriptorCache.cpp:488
void UnsetExplicitDescriptorCache()
Definition D3D12DescriptorCache.cpp:874
void SetExplicitDescriptorCache(FD3D12ExplicitDescriptorCache &ExplicitDescriptorCache)
Definition D3D12DescriptorCache.cpp:825
D3D12_GPU_DESCRIPTOR_HANDLE BuildSRVTable(EShaderFrequency ShaderStage, const FD3D12RootSignature *RootSignature, FD3D12ShaderResourceViewCache &Cache, const SRVSlotMask &SlotsNeededMask, uint32 Count, uint32 &HeapSlot)
Definition D3D12DescriptorCache.cpp:439
Definition D3D12RHICommon.h:78
Definition D3D12Device.h:176
Definition D3D12RHIPrivate.h:160
Definition D3D12ExplicitDescriptorCache.h:109
Definition D3D12DescriptorCache.h:221
virtual bool RollOver() final override
Definition D3D12DescriptorCache.cpp:1046
void ConsolidateUniqueSamplerTables(TArrayView< FD3D12UniqueSamplerTable > UniqueTables)
Definition D3D12DescriptorCache.cpp:1060
TSharedPtr< FD3D12SamplerSet > GetUniqueDescriptorTables()
Definition D3D12DescriptorCache.cpp:1054
Definition D3D12DescriptorCache.h:268
virtual void OpenCommandList() final override
Definition D3D12DescriptorCache.cpp:1292
virtual void HeapLoopedAround() final override
Definition D3D12DescriptorCache.cpp:1276
virtual void CloseCommandList() final override
Definition D3D12DescriptorCache.cpp:1297
virtual bool RollOver() final override
Definition D3D12DescriptorCache.cpp:1222
Definition D3D12DescriptorCache.h:178
ID3D12DescriptorHeap * GetHeap()
Definition D3D12DescriptorCache.h:183
uint32 GetNextSlotIndex() const
Definition D3D12DescriptorCache.h:196
virtual ~FD3D12OnlineHeap()
FORCEINLINE D3D12_CPU_DESCRIPTOR_HANDLE GetCPUSlotHandle(uint32 Slot) const
Definition D3D12DescriptorCache.h:185
void SetNextSlot(uint32 NextSlot)
Definition D3D12DescriptorCache.cpp:1009
uint32 FirstUsedSlot
Definition D3D12DescriptorCache.h:213
const bool bCanLoopAround
Definition D3D12DescriptorCache.h:216
virtual bool RollOver()=0
uint32 ReserveSlots(uint32 NumSlotsRequested)
Definition D3D12DescriptorCache.cpp:957
virtual void OpenCommandList()
Definition D3D12DescriptorCache.h:201
virtual void CloseCommandList()
Definition D3D12DescriptorCache.h:202
virtual void HeapLoopedAround()
Definition D3D12DescriptorCache.h:200
uint32 NextSlotIndex
Definition D3D12DescriptorCache.h:210
FORCEINLINE D3D12_GPU_DESCRIPTOR_HANDLE GetGPUSlotHandle(uint32 Slot) const
Definition D3D12DescriptorCache.h:186
TRefCountPtr< FD3D12DescriptorHeap > Heap
Definition D3D12DescriptorCache.h:207
bool CanReserveSlots(uint32 NumSlots)
Definition D3D12DescriptorCache.cpp:910
virtual uint32 GetTotalSize()
Definition D3D12DescriptorCache.h:203
Definition D3D12View.h:423
Definition D3D12RootSignature.h:73
Definition D3D12View.h:351
Definition D3D12RHICommon.h:128
Definition D3D12StateCachePrivate.h:300
Definition D3D12DescriptorCache.h:241
virtual void OpenCommandList() final override
Definition D3D12DescriptorCache.cpp:1121
virtual bool RollOver() final override
Definition D3D12DescriptorCache.cpp:1111
virtual uint32 GetTotalSize() final override
Definition D3D12DescriptorCache.h:248
Definition D3D12Submission.h:76
Definition D3D12View.h:388
Definition ArrayView.h:139
Definition Array.h:670
UE_FORCEINLINE_HINT SizeType AddUninitialized()
Definition Array.h:1664
UE_REWRITE SizeType Num() const
Definition Array.h:1144
Definition Queue.h:48
Definition SharedPointer.h:692
UE_FORCEINLINE_HINT ObjectType * Get() const
Definition SharedPointer.h:1065
Definition CriticalSection.h:14
Definition VulkanCommon.h:29
U16 Index
Definition radfft.cpp:71
Definition SetUtilities.h:23
Definition D3D12StateCachePrivate.h:172
Definition D3D12View.h:54
Definition D3D12Descriptors.h:95
ID3D12DescriptorHeap * GetHeap() const
Definition D3D12Descriptors.h:107
uint32 GetNumDescriptors() const
Definition D3D12Descriptors.h:117
D3D12_CPU_DESCRIPTOR_HANDLE GetCPUSlotHandle(uint32 Slot) const
Definition D3D12Descriptors.h:124
D3D12_GPU_DESCRIPTOR_HANDLE GetGPUSlotHandle(uint32 Slot) const
Definition D3D12Descriptors.h:125
Definition D3D12StateCachePrivate.h:101
Definition D3D12Descriptors.h:188
uint32 Size
Definition D3D12Descriptors.h:197
Definition D3D12DescriptorCache.h:102
uint16 SamplerID[MAX_SAMPLERS]
Definition D3D12DescriptorCache.h:104
uint32 Count
Definition D3D12DescriptorCache.h:103
bool operator==(const FD3D12SamplerArrayDesc &rhs) const
Definition D3D12DescriptorCache.h:106
Definition D3D12StateCachePrivate.h:257
Definition D3D12StateCachePrivate.h:197
Definition D3D12DescriptorCache.h:147
static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
Definition D3D12DescriptorCache.h:168
static FORCEINLINE KeyInitType GetSetKey(ElementInitType Element)
Definition D3D12DescriptorCache.h:154
TCallTraits< FD3D12UniqueSamplerTable >::ParamType KeyInitType
Definition D3D12DescriptorCache.h:148
TCallTraits< FD3D12UniqueSamplerTable >::ParamType ElementInitType
Definition D3D12DescriptorCache.h:149
static FORCEINLINE bool Matches(KeyInitType A, KeyInitType B)
Definition D3D12DescriptorCache.h:162
Definition D3D12DescriptorCache.h:129
FD3D12UniqueSamplerTable()=default
D3D12_CPU_DESCRIPTOR_HANDLE CPUTable[MAX_SAMPLERS]
Definition D3D12DescriptorCache.h:138
FD3D12UniqueSamplerTable(FD3D12SamplerArrayDesc KeyIn, D3D12_CPU_DESCRIPTOR_HANDLE *Table)
Definition D3D12DescriptorCache.h:131
D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle
Definition D3D12DescriptorCache.h:141
FD3D12SamplerArrayDesc Key
Definition D3D12DescriptorCache.h:137
Definition D3D12StateCachePrivate.h:232
Definition D3D12StateCachePrivate.h:78
static UE_FORCEINLINE_HINT int32 Memcmp(const void *Buf1, const void *Buf2, SIZE_T Count)
Definition UnrealMemory.h:114
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
Definition MultiGPU.h:33
TCallTraitsParamTypeHelper< T, PassByValue >::ParamType ParamType
Definition UnrealTypeTraits.h:275