UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
D3D12RHICommon.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 D3D12RHICommon.h: Common D3D12 RHI definitions
5 =============================================================================*/
6
7#pragma once
8
9#include "HAL/Platform.h"
10#include "RHIPipeline.h"
11
12#include "D3D12ThirdParty.h"
13#include "D3D12RHI.h"
14#include "D3D12RHIDefinitions.h"
15
17#include "MultiGPU.h"
18#include "Stats/Stats.h"
19
20class FD3D12Adapter;
21class FD3D12Device;
22
25
26template <typename ObjectType0, typename ObjectType1>
28
30
31static_assert(MAX_ROOT_CBVS <= MAX_CBS, "MAX_ROOT_CBVS must be <= MAX_CBS.");
32static_assert((8 * sizeof(CBVSlotMask)) >= MAX_CBS, "CBVSlotMask isn't large enough to cover all CBs. Please increase the size.");
33static_assert((8 * sizeof(CBVSlotMask)) >= MAX_ROOT_CBVS, "CBVSlotMask isn't large enough to cover all CBs. Please increase the size.");
34static const CBVSlotMask GRootCBVSlotMask = (1 << MAX_ROOT_CBVS) - 1; // Mask for all slots that are used by root descriptors.
35static const CBVSlotMask GDescriptorTableCBVSlotMask = static_cast<CBVSlotMask>((1<<MAX_CBS) - 1) & ~(GRootCBVSlotMask); // Mask for all slots that are used by a root descriptor table.
36
37#if MAX_SRVS > 32
38 typedef uint64 SRVSlotMask;
39#else
41#endif
42static_assert((8 * sizeof(SRVSlotMask)) >= MAX_SRVS, "SRVSlotMask isn't large enough to cover all SRVs. Please increase the size.");
43
45static_assert((8 * sizeof(SamplerSlotMask)) >= MAX_SAMPLERS, "SamplerSlotMask isn't large enough to cover all Samplers. Please increase the size.");
46
48static_assert((8 * sizeof(UAVSlotMask)) >= MAX_UAVS, "UAVSlotMask isn't large enough to cover all UAVs. Please increase the size.");
49
52
54{
55protected:
57
58public:
60
62 {
63 // If this fires an object was likely created with a default constructor i.e in an STL container
64 // and is therefore an orphan
65 check(ParentAdapter != nullptr);
66 return ParentAdapter;
67 }
68
69 // To be used with delayed setup
71 {
72 check(ParentAdapter == nullptr);
74 }
75};
76
78{
79protected:
81
82public:
84
86 {
87 // If this fires an object was likely created with a default constructor i.e in an STL container
88 // and is therefore an orphan
89 check(Parent != nullptr);
90 return Parent;
91 }
92
94 {
95 return Parent;
96 }
97};
98
100{
101public:
103#if WITH_MGPU
104 : GPUMask(InGPUMask)
106#endif
107 {
108 // Note that node mask can't be null.
109 }
110
111#if WITH_MGPU
112 FORCEINLINE FRHIGPUMask GetGPUMask() const { return GPUMask; }
114#else
117#endif
118
119protected:
120#if WITH_MGPU
121 const FRHIGPUMask GPUMask;
122 // Which GPUs have direct access to this object
124#endif
125};
126
128{
129public:
131 : FD3D12GPUObject(GPUMask, GPUMask)
133 , GPUIndex(GPUMask.ToIndex())
134#endif
135 {}
136
137#if WITH_MGPU
139 {
140 return GPUIndex;
141 }
142#else
143 SGPU_CONSTEXPR uint32 GetGPUIndex() const { return 0; }
144#endif
145
146private:
147#if WITH_MGPU
148 uint32 GPUIndex;
149#endif
150};
151
153{
154public:
156 : FD3D12GPUObject(NodeMask, VisibiltyMask)
157 {
158 check(NodeMask.Intersects(VisibiltyMask));// A GPU objects must be visible on the device it belongs to
159 }
160};
161
162template <typename ObjectType>
164{
165public:
166 using LinkedObjectType = ObjectType;
168
170 {
171 if (IsHeadLink())
172 {
173 // When DoNotDeferDelete is set on these objects releasing it could cause the next iterator
174 // object to be invalid. Therefore we need to accumulate first and then release.
176
177 // Accumulate and release the references we added in CreateLinkedObjects.
178 for (auto It = ++FLinkedObjectIterator(this); It; ++It)
179 {
181 }
183 {
184 ObjectToRelease->Release();
185 }
186 ObjectsToBeReleased.Empty();
187 }
188 }
189
191 {
192 return GetFirstLinkedObject() == this;
193 }
194
195 // The creation lambda function is passed FD3D12Device, and a pointer to the first linked object, or nullptr if the object being constructed
196 // is itself the first object. The first object pointer is needed for cases where resources need to be shared for all linked objects,
197 // such as bindless resource descriptor handles, which need to be the same across GPUs for use in platform independent logic which generates
198 // descriptor tables.
199 template <typename ReturnType, typename CreationCoreFunction, typename CreationParameterFunction>
201 {
202 ReturnType* ObjectOut = nullptr;
203
204#if WITH_MGPU
205 for (uint32 GPUIndex : GPUMask)
206 {
208 CA_ASSUME(NewObject != nullptr);
209 if (ObjectOut == nullptr)
210 {
211 // Don't AddRef the first object or we'll create a reference loop.
213 }
214 else
215 {
216 NewObject->AddRef();
217 }
218 ObjectOut->LinkedObjects.Objects[GPUIndex] = NewObject;
219 }
220
221 if (ObjectOut != nullptr)
222 {
223 ObjectOut->LinkedObjects.GPUMask = GPUMask;
224
225 // Copy the LinkedObjects array to all of the other linked objects.
226 for (auto GPUIterator = ++FRHIGPUMask::FIterator(GPUMask); GPUIterator; ++GPUIterator)
227 {
228 ObjectOut->GetLinkedObject(*GPUIterator)->LinkedObjects = ObjectOut->LinkedObjects;
229 }
230 }
231#else
232 check(GPUMask == FRHIGPUMask::GPU0());
234#endif
235
236 return ObjectOut;
237 }
238
239 ObjectType* GetLinkedObject(uint32 GPUIndex) const
240 {
241#if WITH_MGPU
242 return LinkedObjects.Objects[GPUIndex];
243#else
244 checkSlow(GPUIndex == 0);
245 return GetFirstLinkedObject();
246#endif
247 }
248
249 ObjectType* GetFirstLinkedObject() const
250 {
251#if WITH_MGPU
252 return LinkedObjects.Objects[LinkedObjects.GPUMask.GetFirstIndex()];
253#else
254 return static_cast<ObjectType*>(const_cast<FD3D12LinkedAdapterObject*>(this));
255#endif
256 }
257
259 {
260#if WITH_MGPU
261 return LinkedObjects.GPUMask;
262#else
263 return FRHIGPUMask::GPU0();
264#endif
265 }
266
268 {
269 public:
271 : GPUIterator(0)
272 , Object(nullptr)
273 {
274 if (InObject != nullptr)
275 {
276 GPUIterator = FRHIGPUMask::FIterator(InObject->GetLinkedObjectsGPUMask());
277 Object = InObject->GetLinkedObject(*GPUIterator);
278 }
279 }
280
282 {
283 Object = ++GPUIterator ? Object->GetLinkedObject(*GPUIterator) : nullptr;
284 return *this;
285 }
286
287 explicit operator bool() const { return Object != nullptr; }
288 bool operator !() const { return Object == nullptr; }
289
290 bool operator ==(FLinkedObjectIterator& Other) const { return Object == Other.Object; }
291 bool operator !=(FLinkedObjectIterator& Other) const { return Object != Other.Object; }
292
293 ObjectType& operator *() const { return *Object; }
294 ObjectType* operator ->() const { return Object; }
295 ObjectType* Get() const { return Object; }
296
297 private:
298 FRHIGPUMask::FIterator GPUIterator;
299 ObjectType* Object;
300 };
301
304
305protected:
307
308private:
309#if WITH_MGPU
310 struct FLinkedObjects
311 {
313 : Objects(InPlace, nullptr)
314 {}
315
316 FRHIGPUMask GPUMask;
318 };
320#endif // WITH_MGPU
321};
322
328template <typename ObjectType0, typename ObjectType1>
330{
331public:
333 : GPUIterator(0)
334 {
335 const FRHIGPUMask GPUMask = InObject0->GetLinkedObjectsGPUMask();
336 check(GPUMask == InObject1->GetLinkedObjectsGPUMask());
337
338 GPUIterator = FRHIGPUMask::FIterator(GPUMask);
339 Object0 = static_cast<ObjectType0*>(InObject0->GetLinkedObject(*GPUIterator));
340 Object1 = static_cast<ObjectType1*>(InObject1->GetLinkedObject(*GPUIterator));
341 }
342
344 {
345 if (++GPUIterator)
346 {
347 Object0 = static_cast<ObjectType0*>(Object0->GetLinkedObject(*GPUIterator));
348 Object1 = static_cast<ObjectType1*>(Object1->GetLinkedObject(*GPUIterator));
349 }
350 else
351 {
352 Object0 = nullptr;
353 Object1 = nullptr;
354 }
355 return *this;
356 }
357
358 explicit operator bool() const { return static_cast<bool>(GPUIterator); }
359 bool operator !() const { return !GPUIterator; }
360
361 ObjectType0* GetFirst() const { return Object0; }
362 ObjectType1* GetSecond() const { return Object1; }
363 uint32 GetGPUIndex() const { return *GPUIterator; }
364
365private:
366 FRHIGPUMask::FIterator GPUIterator;
367 ObjectType0* Object0;
368 ObjectType1* Object1;
369};
370
371// Template helper class for converting RHI resource types to D3D12RHI resource types
372template<class T>
374{
375};
376
377// Lock free pointer list that auto-destructs items remaining in the list.
378template <typename TObjectType>
379struct TD3D12ObjectPool : public TLockFreePointerListUnordered<TObjectType, PLATFORM_CACHE_LINE_SIZE>
380{
385
393};
394
395// Set of validation to enable in all builds (including shipping)
396
397#ifndef ENABLE_COPY_BUFFER_REGION_CHECK
398 #define ENABLE_COPY_BUFFER_REGION_CHECK 1
399#endif // ENABLE_COPY_BUFFER_REGION_CHECK
400
401#ifndef ENABLE_COPY_TEXTURE_REGION_CHECK
402 #define ENABLE_COPY_TEXTURE_REGION_CHECK 1
403#endif // ENABLE_COPY_TEXTURE_REGION_CHECK
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define CA_ASSUME(Expr)
Definition CoreMiscDefines.h:126
@ InPlace
Definition CoreMiscDefines.h:162
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
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_ROOT_CBVS
Definition D3D12RHIDefinitions.h:57
#define MAX_UAVS
Definition D3D12RHI.h:19
#define MAX_SAMPLERS
Definition D3D12RHI.h:18
#define MAX_CBS
Definition D3D12RHI.h:20
#define MAX_SRVS
Definition D3D12RHI.h:17
FORCEINLINE uint32 ToIndex(FHairStrandsTiles::ETileType Type)
Definition HairStrandsData.h:93
#define DECLARE_LOG_CATEGORY_EXTERN(CategoryName, DefaultVerbosity, CompileTimeVerbosity)
Definition LogMacros.h:361
#define SGPU_CONSTEXPR
Definition MultiGPU.h:28
const bool
Definition NetworkReplayStreaming.h:178
if(Failed) console_printf("Failed.\n")
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition D3D12RHICommon.h:54
FD3D12Adapter * ParentAdapter
Definition D3D12RHICommon.h:56
FD3D12AdapterChild(FD3D12Adapter *InParent=nullptr)
Definition D3D12RHICommon.h:59
FORCEINLINE FD3D12Adapter * GetParentAdapter() const
Definition D3D12RHICommon.h:61
void SetParentAdapter(FD3D12Adapter *InParent)
Definition D3D12RHICommon.h:70
Definition D3D12Adapter.h:136
Definition D3D12CommandContext.h:513
Definition D3D12CommandContext.h:1193
Definition D3D12RHICommon.h:78
FORCEINLINE FD3D12Device * GetParentDevice() const
Definition D3D12RHICommon.h:85
FD3D12DeviceChild(FD3D12Device *InParent=nullptr)
Definition D3D12RHICommon.h:83
FD3D12Device * GetParentDevice_Unsafe() const
Definition D3D12RHICommon.h:93
FD3D12Device * Parent
Definition D3D12RHICommon.h:80
Definition D3D12Device.h:176
Definition D3D12RHICommon.h:100
SGPU_CONSTEXPR FRHIGPUMask GetGPUMask() const
Definition D3D12RHICommon.h:115
FD3D12GPUObject(FRHIGPUMask InGPUMask, FRHIGPUMask InVisibiltyMask)
Definition D3D12RHICommon.h:102
SGPU_CONSTEXPR FRHIGPUMask GetVisibilityMask() const
Definition D3D12RHICommon.h:116
FLinkedObjectIterator(FD3D12LinkedAdapterObject *InObject)
Definition D3D12RHICommon.h:270
bool operator!=(FLinkedObjectIterator &Other) const
Definition D3D12RHICommon.h:291
bool operator==(FLinkedObjectIterator &Other) const
Definition D3D12RHICommon.h:290
ObjectType * Get() const
Definition D3D12RHICommon.h:295
bool operator!() const
Definition D3D12RHICommon.h:288
ObjectType & operator*() const
Definition D3D12RHICommon.h:293
ObjectType * operator->() const
Definition D3D12RHICommon.h:294
FLinkedObjectIterator & operator++()
Definition D3D12RHICommon.h:281
Definition D3D12RHICommon.h:164
ObjectType * GetLinkedObject(uint32 GPUIndex) const
Definition D3D12RHICommon.h:239
static ReturnType * CreateLinkedObjects(FRHIGPUMask GPUMask, const CreationParameterFunction &pfnGetCreationParameter, const CreationCoreFunction &pfnCreationCore)
Definition D3D12RHICommon.h:200
FORCEINLINE bool IsHeadLink() const
Definition D3D12RHICommon.h:190
ObjectType LinkedObjectType
Definition D3D12RHICommon.h:166
ObjectType * GetFirstLinkedObject() const
Definition D3D12RHICommon.h:249
FLinkedObjectIterator begin()
Definition D3D12RHICommon.h:302
FLinkedObjectIterator end()
Definition D3D12RHICommon.h:303
~FD3D12LinkedAdapterObject()
Definition D3D12RHICommon.h:169
FRHIGPUMask GetLinkedObjectsGPUMask() const
Definition D3D12RHICommon.h:258
FD3D12LinkedAdapterObject()
Definition D3D12RHICommon.h:306
Definition D3D12RHICommon.h:153
FD3D12MultiNodeGPUObject(FRHIGPUMask NodeMask, FRHIGPUMask VisibiltyMask)
Definition D3D12RHICommon.h:155
Definition D3D12RHICommon.h:128
SGPU_CONSTEXPR uint32 GetGPUIndex() const
Definition D3D12RHICommon.h:143
FD3D12SingleNodeGPUObject(FRHIGPUMask GPUMask)
Definition D3D12RHICommon.h:130
Definition Array.h:670
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
Definition D3D12RHICommon.h:330
ObjectType1 * GetSecond() const
Definition D3D12RHICommon.h:362
TD3D12DualLinkedObjectIterator(FD3D12LinkedAdapterObject< typename ObjectType0::LinkedObjectType > *InObject0, FD3D12LinkedAdapterObject< typename ObjectType1::LinkedObjectType > *InObject1)
Definition D3D12RHICommon.h:332
ObjectType0 * GetFirst() const
Definition D3D12RHICommon.h:361
TD3D12DualLinkedObjectIterator & operator++()
Definition D3D12RHICommon.h:343
uint32 GetGPUIndex() const
Definition D3D12RHICommon.h:363
bool operator!() const
Definition D3D12RHICommon.h:359
Definition LockFreeList.h:904
Definition StaticArray.h:26
Definition MultiGPU.h:217
Definition MultiGPU.h:33
static GPUMASK_CONSTEXPR FRHIGPUMask GPU0()
Definition MultiGPU.h:186
SGPU_CONSTEXPR bool Intersects(FRHIGPUMask Rhs) const
Definition MultiGPU.h:131
Definition D3D12RHICommon.h:380
void CleanupResources()
Definition D3D12RHICommon.h:386
~TD3D12ObjectPool()
Definition D3D12RHICommon.h:381
Definition D3D12RHICommon.h:374