UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
RenderGraphAllocator.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
8#include "CoreGlobals.h"
9#include "CoreMinimal.h"
10#include "HAL/MemoryBase.h"
11#include "HAL/UnrealMemory.h"
12#include "Math/UnrealMathSSE.h"
14#include "Misc/MemStack.h"
15#include "Templates/Function.h"
17
18#define RDG_USE_MALLOC USING_ADDRESS_SANITISER
19#define RDG_ALLOCATOR_DEBUG USING_ADDRESS_SANITISER || UE_BUILD_DEBUG
20
21class FRDGAllocator;
22
24{
25public:
26 class FObject
27 {
28 public:
29 virtual ~FObject() = default;
30 };
31
32 template <typename T>
33 class TObject final : FObject
34 {
35 friend class FRDGAllocator;
36 private:
37 template <typename... TArgs>
38 inline TObject(TArgs&&... Args)
39 : Alloc(Forward<TArgs&&>(Args)...)
40 {}
41
42 T Alloc;
43 };
44
46
51
53 inline void* Alloc(uint64 SizeInBytes, uint32 AlignInBytes)
54 {
55 void* Memory;
56
57#if RDG_ALLOCATOR_DEBUG
59#endif
60
61#if RDG_USE_MALLOC
62 Memory = FMemory::Malloc(SizeInBytes, AlignInBytes);
63 Mallocs.Emplace(Memory);
64 NumMallocBytes += SizeInBytes;
65#else
66 Memory = MemStack.Alloc(SizeInBytes, AlignInBytes);
67#endif
68
69#if RDG_ALLOCATOR_DEBUG
71#endif
72
73 return Memory;
74 }
75
77 template <typename PODType>
79 {
80 return reinterpret_cast<PODType*>(Alloc(sizeof(PODType) * Count, alignof(PODType)));
81 }
82
84 template <typename T, typename... TArgs>
85 inline T* Alloc(TArgs&&... Args)
86 {
87#if RDG_ALLOCATOR_DEBUG
89#endif
90
91#if RDG_USE_MALLOC
93 NumMallocBytes += sizeof(Object);
94#else
95 TObject<T>* Object = new(MemStack) TObject<T>(Forward<TArgs&&>(Args)...);
96#endif
98 Objects.Add(Object);
99
100#if RDG_ALLOCATOR_DEBUG
102#endif
103 return &Object->Alloc;
104 }
105
107 template <typename T, typename... TArgs>
108 inline T* AllocNoDestruct(TArgs&&... Args)
109 {
110 return new (AllocUninitialized<T>(1)) T(Forward<TArgs&&>(Args)...);
111 }
112
113 inline int32 GetByteCount() const
114 {
115#if RDG_USE_MALLOC
116 return static_cast<int32>(NumMallocBytes);
117#else
118 return MemStack.GetByteCount();
119#endif
120 }
121
122 void ReleaseAll();
123
124private:
125#if RDG_USE_MALLOC
126 TArray<void*> Mallocs;
128#else
129 FMemStackBase MemStack;
130#endif
131 TArray<FObject*> Objects;
132
133#if RDG_ALLOCATOR_DEBUG
136
137 std::atomic_int32_t NumAccesses{0};
138 static thread_local int32 NumAccessesTLS;
139#endif
140
141 friend class FRDGAllocatorScope;
142 static uint32 AllocatorTLSSlot;
143};
144
146{
147public:
150
151private:
152 void* AllocatorToRestore;
153};
154
155#define RDG_FRIEND_ALLOCATOR_FRIEND(Type) friend class FRDGAllocator::TObject<Type>
156
158{
159 [[noreturn]] RENDERCORE_API void OnInvalidRDGAllocatorNum(int32 NewNum, SIZE_T NumBytesPerElement);
160}
161
163template<uint32 Alignment = DEFAULT_ALIGNMENT>
165{
166public:
168
169 enum { NeedsElementType = true };
170 enum { RequireRangeCheck = true };
171
172 template<typename ElementType>
174 {
175 public:
176 ForElementType() = default;
177
179 {
180 checkSlow(this != &Other);
181
182 Data = Other.Data;
183 Other.Data = nullptr;
184 }
185
186 inline ElementType* GetAllocation() const
187 {
188 return Data;
189 }
190
191 void ResizeAllocation(SizeType CurrentNum, SizeType NewMax, SIZE_T NumBytesPerElement)
192 {
193 void* OldData = Data;
194 if (NewMax)
195 {
196 static_assert(sizeof(int32) <= sizeof(SIZE_T), "SIZE_T is expected to be larger than int32");
197
198 // Check for under/overflow
200 {
201 UE::RenderCore::Private::OnInvalidRDGAllocatorNum(NewMax, NumBytesPerElement);
202 }
203
204 // Allocate memory from the allocator.
205 const int32 AllocSize = (int32)(NewMax * NumBytesPerElement);
206 const int32 AllocAlignment = FMath::Max(Alignment, (uint32)alignof(ElementType));
207 Data = (ElementType*)FRDGAllocator::GetTLS().Alloc(AllocSize, FMath::Max(AllocSize >= 16 ? (int32)16 : (int32)8, AllocAlignment));
208
209 // If the container previously held elements, copy them into the new allocation.
210 if (OldData && CurrentNum)
211 {
212 const SizeType NumCopiedElements = FMath::Min(NewMax, CurrentNum);
213 FMemory::Memcpy(Data, OldData, NumCopiedElements * NumBytesPerElement);
214 }
215 }
216 }
217 inline SizeType CalculateSlackReserve(SizeType NewMax, SIZE_T NumBytesPerElement) const
218 {
219 return DefaultCalculateSlackReserve(NewMax, NumBytesPerElement, false, Alignment);
220 }
221
222 inline SizeType CalculateSlackShrink(SizeType NewMax, SizeType CurrentMax, SIZE_T NumBytesPerElement) const
223 {
224 return DefaultCalculateSlackShrink(NewMax, CurrentMax, NumBytesPerElement, false, Alignment);
225 }
226
227 inline SizeType CalculateSlackGrow(SizeType NewMax, SizeType CurrentMax, SIZE_T NumBytesPerElement) const
228 {
229 return DefaultCalculateSlackGrow(NewMax, CurrentMax, NumBytesPerElement, false, Alignment);
230 }
231
232 inline SIZE_T GetAllocatedSize(SizeType CurrentMax, SIZE_T NumBytesPerElement) const
233 {
234 return CurrentMax * NumBytesPerElement;
235 }
236
237 bool HasAllocation() const
238 {
239 return !!Data;
240 }
241
243 {
244 return 0;
245 }
246
247 private:
248 ElementType* Data = nullptr;
249 };
250
252};
253
254template <uint32 Alignment>
255struct TAllocatorTraits<TRDGArrayAllocator<Alignment>> : TAllocatorTraitsBase<TRDGArrayAllocator<Alignment>>
256{
257 enum { IsZeroConstruct = true };
258};
259
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
UE_FORCEINLINE_HINT SizeType DefaultCalculateSlackReserve(SizeType NewMax, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment=DEFAULT_ALIGNMENT)
Definition ContainerAllocationPolicies.h:223
UE_FORCEINLINE_HINT SizeType DefaultCalculateSlackShrink(SizeType NewMax, SizeType CurrentMax, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment=DEFAULT_ALIGNMENT)
Definition ContainerAllocationPolicies.h:139
UE_FORCEINLINE_HINT SizeType DefaultCalculateSlackGrow(SizeType NewMax, SizeType CurrentMax, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment=DEFAULT_ALIGNMENT)
Definition ContainerAllocationPolicies.h:169
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UNLIKELY(x)
Definition Platform.h:857
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
#define MAX_int32
Definition NumericLimits.h:25
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MemStack.h:78
void * Alloc(size_t AllocSize, size_t Alignment)
Definition MemStack.h:132
CORE_API int32 GetByteCount() const
Definition MemStack.cpp:319
Definition RenderGraphAllocator.h:146
RENDERCORE_API ~FRDGAllocatorScope()
Definition RenderGraphAllocator.cpp:105
Definition RenderGraphAllocator.h:27
virtual ~FObject()=default
Definition RenderGraphAllocator.h:34
Definition RenderGraphAllocator.h:24
int32 GetByteCount() const
Definition RenderGraphAllocator.h:113
FRDGAllocator()
Definition RenderGraphAllocator.cpp:13
void ReleaseAll()
Definition RenderGraphAllocator.cpp:72
static RENDERCORE_API FRDGAllocator & GetTLS()
Definition RenderGraphAllocator.cpp:51
void * Alloc(uint64 SizeInBytes, uint32 AlignInBytes)
Definition RenderGraphAllocator.h:53
T * AllocNoDestruct(TArgs &&... Args)
Definition RenderGraphAllocator.h:108
PODType * AllocUninitialized(uint64 Count=1)
Definition RenderGraphAllocator.h:78
T * Alloc(TArgs &&... Args)
Definition RenderGraphAllocator.h:85
FRDGAllocator & operator=(FRDGAllocator &&)
Definition RenderGraphAllocator.cpp:24
~FRDGAllocator()
Definition RenderGraphAllocator.cpp:46
Definition Array.h:670
Definition RenderGraphAllocator.h:174
SizeType CalculateSlackGrow(SizeType NewMax, SizeType CurrentMax, SIZE_T NumBytesPerElement) const
Definition RenderGraphAllocator.h:227
void ResizeAllocation(SizeType CurrentNum, SizeType NewMax, SIZE_T NumBytesPerElement)
Definition RenderGraphAllocator.h:191
SIZE_T GetAllocatedSize(SizeType CurrentMax, SIZE_T NumBytesPerElement) const
Definition RenderGraphAllocator.h:232
void MoveToEmpty(ForElementType &Other)
Definition RenderGraphAllocator.h:178
SizeType GetInitialCapacity() const
Definition RenderGraphAllocator.h:242
SizeType CalculateSlackReserve(SizeType NewMax, SIZE_T NumBytesPerElement) const
Definition RenderGraphAllocator.h:217
bool HasAllocation() const
Definition RenderGraphAllocator.h:237
ElementType * GetAllocation() const
Definition RenderGraphAllocator.h:186
SizeType CalculateSlackShrink(SizeType NewMax, SizeType CurrentMax, SIZE_T NumBytesPerElement) const
Definition RenderGraphAllocator.h:222
Definition RenderGraphAllocator.h:165
@ NeedsElementType
Definition RenderGraphAllocator.h:169
ForElementType< FScriptContainerElement > ForAnyElementType
Definition RenderGraphAllocator.h:251
int32 SizeType
Definition RenderGraphAllocator.h:167
@ RequireRangeCheck
Definition RenderGraphAllocator.h:170
Definition ContainerAllocationPolicies.h:1662
Definition ContainerAllocationPolicies.h:894
Definition ContainerAllocationPolicies.h:1383
Definition RenderGraphAllocator.h:158
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
Definition ContainerAllocationPolicies.h:247
@ IsZeroConstruct
Definition ContainerAllocationPolicies.h:248
Definition ContainerAllocationPolicies.h:256