UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
NaniteStreamingManager.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "IO/IoDispatcher.h"
8#include "NaniteResources.h"
9#include "UnifiedBuffer.h"
10#include "SpanAllocator.h"
11
12namespace UE
13{
14 namespace DerivedData
15 {
16 class FRequestOwner; // Can't include DDC headers from here, so we have to forward declare
18 }
19}
20
21class FRDGBuilder;
22
23namespace Nanite
24{
25
26class FFixupChunk;
27
29{
32
33 friend inline uint32 GetTypeHash(const FPageKey& Key)
34 {
35 return Key.RuntimeResourceID * 0xFC6014F9u + Key.PageIndex * 0x58399E77u;
36 }
37
38 inline bool operator==(const FPageKey& Other) const
39 {
40 return RuntimeResourceID == Other.RuntimeResourceID && PageIndex == Other.PageIndex;
41 }
42
43 inline bool operator!=(const FPageKey& Other) const
44 {
45 return !(*this == Other);
46 }
47
48 inline bool operator<(const FPageKey& Other) const
49 {
50 return RuntimeResourceID != Other.RuntimeResourceID ? RuntimeResourceID < Other.RuntimeResourceID : PageIndex < Other.PageIndex;
51 }
52};
53
55{
58
59 inline bool operator<(const FStreamingRequest& Other) const
60 {
61 return Key != Other.Key ? Key < Other.Key : Priority > Other.Priority;
62 }
63};
64
65/*
66 * Streaming manager for Nanite.
67 */
69{
70public:
72
73 virtual void InitRHI(FRHICommandListBase& RHICmdList) override;
74 virtual void ReleaseRHI() override;
75
76 void Add(FResources* Resources);
77 void Remove(FResources* Resources);
78
79 ENGINE_API void BeginAsyncUpdate(FRDGBuilder& GraphBuilder); // Should be called at least once per frame. Must be called before any Nanite rendering when new meshes are added.
80 ENGINE_API void EndAsyncUpdate(FRDGBuilder& GraphBuilder); // Must be called after BeginAsyncUpdate and before any Nanite rendering.
82 ENGINE_API bool IsSafeForRendering() const;
83
84 UE_DEPRECATED(5.7, "SubmitFrameStreamingRequests should no longer be called.")
86
91
93
95 {
96 return QualityScaleFactor;
97 }
98
100 {
101 return MaxStreamingPages;
102 }
103
105 {
106 return MaxHierarchyLevels;
107 }
108
109 inline bool HasResourceEntries() const
110 {
111 return NumResources > 0u;
112 }
113
115 {
116 return MoveTemp(ModifiedResources);
117 }
118
119 ENGINE_API void PrefetchResource(const FResources* Resource, uint32 NumFramesUntilRender);
121#if WITH_EDITOR
124#endif
125
126private:
128
129 static constexpr uint16 INVALID_RESIDENT_PAGE_INDEX = 0xFFFFu;
130
131 struct FResourcePrefetch
132 {
133 uint32 RuntimeResourceID;
134 uint32 NumFramesUntilRender;
135 };
136
137 struct FAsyncState
138 {
139 struct FGPUStreamingRequest* GPUStreamingRequestsPtr = nullptr;
140 uint32 NumGPUStreamingRequests = 0;
141 uint32 NumReadyOrSkippedPages = 0;
142 bool bUpdateActive = false;
143 bool bBuffersTransitionedToWrite = false;
144 };
145
146 struct FPendingPage
147 {
148#if WITH_EDITOR
149 FSharedBuffer SharedBuffer;
150 enum class EState
151 {
152 None,
154 DDC_Ready,
156 Memory,
157 Disk,
158 } State = EState::None;
159#endif
160 FIoBuffer RequestBuffer;
162
163 uint32 GPUPageIndex = INDEX_NONE;
164 FPageKey InstallKey;
165 uint32 RingBufferAllocationSize = 0;
166 uint32 BytesLeftToStream = 0;
167 uint32 RetryCount = 0;
168 };
169
170 struct FHeapBuffer
171 {
172 int32 TotalUpload = 0;
174 FRDGScatterUploadBuffer UploadBuffer;
176
177 void Release()
178 {
179 UploadBuffer = {};
180 DataBuffer = {};
181 }
182 };
183
184 struct FRegisteredVirtualPage
185 {
186 uint32 Priority = 0u; // Priority != 0u means referenced this frame
187 uint32 RegisteredPageIndex = INDEX_NONE;
188
189 bool operator==(const FRegisteredVirtualPage&) const = default;
190 };
191
192 struct FResidentVirtualPage
193 {
194 uint16 ResidentPageIndex = INVALID_RESIDENT_PAGE_INDEX;
195
196 bool operator==(const FResidentVirtualPage&) const = default;
197 };
198
199 struct FNewPageRequest
200 {
201 FPageKey Key;
202 uint32 VirtualPageIndex = INDEX_NONE;
203 };
204
205 struct FRegisteredPage
206 {
207 FPageKey Key;
208 uint32 VirtualPageIndex = INDEX_NONE;
209 uint8 RefCount = 0;
210 };
211
212 struct FResidentPage
213 {
214 FPageKey Key;
215 uint8 MaxHierarchyDepth = 0xFF;
216 };
217
218 struct FRootPageInfo
219 {
220 FFixupChunk* FixupChunk = nullptr;
221 uint8 MaxHierarchyDepth = 0xFF;
222
223 // Per-resource properties.
224 // This could be moved to a separate struct, but probably isn't worth the indirection as there is typically one root page per resource.
225 FResources* Resources = nullptr;
226 uint32 RuntimeResourceID = INDEX_NONE;
227 uint32 VirtualPageRangeStart = INDEX_NONE; // Points to virtual address of this root page, not the first one
228 uint32 NumRootPages = INDEX_NONE;
229 uint32 NumTotalPages = INDEX_NONE;
230
231 uint32 bInvalidResource : 1 = 0; // Crude defensive measure against invalid DDC data and IO errors.
232 // Instead of just crashing on invalid data, emit an error and stop streaming from the resource.
233
234 bool operator==(const FRootPageInfo&) const = default;
235 };
236
237 TArray<FRootPageInfo> RootPageInfos;
238 TArray<uint8> RootPageVersions;
239
240 FHeapBuffer ClusterPageData; // FPackedCluster*, GeometryData { Index, Position, TexCoord, TangentX, TangentZ }*
241 FHeapBuffer Hierarchy;
242 FHeapBuffer ImposterData;
243
244 TPimplPtr<class FOrderedScatterUpdater> ClusterScatterUpdates;
245 TPimplPtr<class FOrderedScatterUpdater> HierarchyScatterUpdates;
246
247 TPimplPtr<class FHierarchyDepthManager> HierarchyDepthManager;
248 uint32 MaxHierarchyLevels = 0;
249
250 uint32 MaxStreamingPages = 0;
251 uint32 MaxRootPages = 0;
252 uint32 NumInitialRootPages = 0;
253 uint32 PrevNumInitialRootPages = 0;
254 uint32 MaxPendingPages = 0;
255 uint32 MaxPageInstallsPerUpdate = 0;
256
257 uint32 NumResources = 0;
258 uint32 NumPendingPages = 0;
259 uint32 NextPendingPageIndex = 0;
260 float QualityScaleFactor = 1.0f;
261 bool bClusterPageDataAllocated = false;
262
263 uint32 StatNumRootPages = 0;
264 uint32 StatPeakRootPages = 0;
265 uint32 StatVisibleSetSize = 0;
266 uint32 StatPrevUpdateTime = 0;
267 uint32 StatNumAllocatedRootPages = 0;
268 uint32 StatNumHierarchyNodes = 0;
269 uint32 StatPeakHierarchyNodes = 0;
270 float StatStreamingPoolPercentage = 0.0f;
271
272 uint64 PrevUpdateTick = 0;
273 uint64 PrevUpdateFrameNumber = ~0ull;
274
275 TArray<FResources*> PendingAdds;
276
277 TMultiMap<uint32, FResources*> PersistentHashResourceMap; // TODO: MultiMap to handle potential collisions and issues with there temporarily being two meshes with the same hash because of unordered add/remove.
278
279 TMap<uint32, uint32> ModifiedResources; // Key = RuntimeResourceID, Value = NumResidentClusters
280
281 FSpanAllocator VirtualPageAllocator;
282 TArray<FRegisteredVirtualPage> RegisteredVirtualPages;
283
284 typedef TArray<uint32, TInlineAllocator<16>> FRegisteredPageDependencies;
285 TArray<FRegisteredPage> RegisteredPages;
286 TArray<FRegisteredPageDependencies> RegisteredPageDependencies;
287
288 TArray<uint32> RegisteredPageIndexToLRU;
289 TArray<uint32> LRUToRegisteredPageIndex;
290
291 TArray<FResidentPage> ResidentPages;
292 TArray<FFixupChunk*> ResidentPageFixupChunks; // Fixup information for resident streaming pages. We need to keep this around to be able to uninstall pages.
293 TArray<FResidentVirtualPage> ResidentVirtualPages;
294
295 TArray<FNewPageRequest> RequestedNewPages;
296 TArray<uint32> RequestedRegisteredPages;
297
298 TArray<FPendingPage> PendingPages;
299 TArray<uint8> PendingPageStagingMemory;
300 TPimplPtr<class FRingBufferAllocator> PendingPageStagingAllocator;
301
303 TPimplPtr<class FReadbackManager> ReadbackManager;
304
305 TPimplPtr<class FQualityScalingManager> QualityScalingManager;
306
307 FGraphEventArray AsyncTaskEvents;
308 FAsyncState AsyncState;
309
310#if WITH_EDITOR
311 UE::DerivedData::FRequestOwner* RequestOwner;
312
315#endif
316 TArray<uint32> PendingExplicitRequests;
317 TArray<FResourcePrefetch> PendingResourcePrefetches;
318
319 // Transient lifetime, but persisted to reduce allocations
320 TArray<FStreamingRequest> PrioritizedRequestsHeap;
321 TArray<uint32> GPUPageDependencies;
322 TArray<FPageKey> SelectedPages;
323
324 bool AddRequest(uint32 RuntimeResourceID, uint32 PageIndex, uint32 VirtualPageIndex, uint32 Priority);
325 bool AddRequest(uint32 RuntimeResourceID, uint32 PageIndex, uint32 Priority);
326 void AddPendingGPURequests();
327 void AddPendingExplicitRequests();
328 void AddPendingResourcePrefetchRequests();
329 void AddParentRequests();
330 void AddParentRegisteredRequestsRecursive(uint32 RegisteredPageIndex, uint32 Priority);
331 void AddParentNewRequestsRecursive(const FResources& Resources, uint32 RuntimeResourceID, uint32 PageIndex, uint32 VirtualPageRangeStart, uint32 Priority);
332
333 FRootPageInfo* GetRootPage(uint32 RuntimeResourceID);
334 FResources* GetResources(uint32 RuntimeResourceID);
335
336 void SelectHighestPriorityPagesAndUpdateLRU(uint32 MaxSelectedPages);
337
338 void RegisterStreamingPage(uint32 RegisteredPageIndex, const FPageKey& Key);
339 void UnregisterStreamingPage(const FPageKey& Key);
340
341 void MoveToEndOfLRUList(uint32 RegisteredPageIndex);
342 void CompactLRU();
343 void VerifyLRU();
344
345 void ApplyFixups(const FFixupChunk& FixupChunk, const FResources& Resources, const TSet<uint32>* NoWriteGPUPages, uint32 NumStreamingPages, uint32 PageToExclude, uint32 VirtualPageRangeStart, bool bUninstall, bool bAllowReconsider, bool bAllowReinstall);
346 void VerifyFixupState();
347
348 bool ArePageDependenciesCommitted(const FResources& Resources, FPageRangeKey PageRangeKey, uint32 PageToExclude, uint32 VirtualPageRangeStart);
349
350 void ProcessNewResources(FRDGBuilder& GraphBuilder, FRDGBuffer* ClusterPageDataBuffer);
351 FRDGBuffer* ResizePoolAllocationIfNeeded(FRDGBuilder& GraphBuilder);
352
353 uint32 DetermineReadyOrSkippedPages(uint32& TotalPageSize);
354 void InstallReadyPages(uint32 NumReadyOrSkippedPages);
355
356 void UninstallResidentPage(uint32 GPUPageIndex, uint32 NumStreamingPages, const TSet<uint32>* NoWriteGPUPages, bool bApplyFixup);
357 void UninstallAllResidentPages(uint32 NumStreamingPages);
358
359 void ResetStreamingStateCPU();
360 void UpdatePageConfiguration();
361
362
363 void AsyncUpdate();
364
365#if NANITE_SANITY_CHECK_STREAMING_REQUESTS
366 void SanityCheckStreamingRequests(const struct FGPUStreamingRequest* StreamingRequestsPtr, const uint32 NumStreamingRequests);
367#endif
368
369#if WITH_EDITOR
370 void RecordGPURequests();
371 UE::DerivedData::FCacheGetChunkRequest BuildDDCRequest(const FResources& Resources, const FPageStreamingState& PageStreamingState, const uint32 PendingPageIndex);
373#endif
374};
375
377
378} // namespace Nanite
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
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
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition BulkData.h:1194
Definition IoBuffer.h:15
Definition RenderGraphResources.h:1426
Definition RenderGraphResources.h:1321
Definition RenderGraphBuilder.h:49
Definition UnifiedBuffer.h:479
Definition RHICommandList.h:455
Definition RenderResource.h:37
Definition SharedBuffer.h:341
Definition SpanAllocator.h:15
Definition NaniteStreamingManager.h:69
ENGINE_API void EndAsyncUpdate(FRDGBuilder &GraphBuilder)
Definition NaniteStreamingManager.cpp:3058
ENGINE_API bool IsSafeForRendering() const
Definition NaniteStreamingManager.cpp:3130
ENGINE_API FRDGBufferSRV * GetClusterPageDataSRV(FRDGBuilder &GraphBuilder) const
Definition NaniteStreamingManager.cpp:970
ENGINE_API FRDGBuffer * GetStreamingRequestsBuffer(FRDGBuilder &GraphBuilder) const
Definition NaniteStreamingManager.cpp:960
uint32 GetMaxHierarchyLevels() const
Definition NaniteStreamingManager.h:104
ENGINE_API void BeginAsyncUpdate(FRDGBuilder &GraphBuilder)
Definition NaniteStreamingManager.cpp:2293
ENGINE_API uint32 GetStreamingRequestsBufferVersion() const
Definition NaniteStreamingManager.cpp:3159
float GetQualityScaleFactor() const
Definition NaniteStreamingManager.h:94
ENGINE_API void PrefetchResource(const FResources *Resource, uint32 NumFramesUntilRender)
Definition NaniteStreamingManager.cpp:3135
ENGINE_API bool IsAsyncUpdateInProgress()
Definition NaniteStreamingManager.cpp:3125
virtual void InitRHI(FRHICommandListBase &RHICmdList) override
Definition NaniteStreamingManager.cpp:539
ENGINE_API void RequestNanitePages(TArrayView< uint32 > RequestData)
Definition NaniteStreamingManager.cpp:3149
virtual void ReleaseRHI() override
Definition NaniteStreamingManager.cpp:687
ENGINE_API void SubmitFrameStreamingRequests(FRDGBuilder &GraphBuilder)
Definition NaniteStreamingManager.cpp:3121
uint32 GetMaxStreamingPages() const
Definition NaniteStreamingManager.h:99
ENGINE_API FRDGBufferSRV * GetHierarchySRV(FRDGBuilder &GraphBuilder) const
Definition NaniteStreamingManager.cpp:965
FStreamingManager()
Definition NaniteStreamingManager.cpp:532
bool HasResourceEntries() const
Definition NaniteStreamingManager.h:109
TMap< uint32, uint32 > GetAndClearModifiedResources()
Definition NaniteStreamingManager.h:114
ENGINE_API FRDGBufferSRV * GetImposterDataSRV(FRDGBuilder &GraphBuilder) const
Definition NaniteStreamingManager.cpp:975
Definition NaniteStreamingManager.cpp:2022
Definition ArrayView.h:139
Definition Array.h:670
Definition RenderResource.h:543
Definition UnrealString.h.inl:34
Definition RefCounting.h:454
Definition SkinnedMeshComponent.h:50
TGlobalResource< FStreamingManager > GStreamingManager
Definition NaniteStreamingManager.cpp:3321
@ Release
Definition PhysicsPublic.h:123
bool operator==(const FCachedAssetKey &A, const FCachedAssetKey &B)
Definition AssetDataMap.h:501
State
Definition PacketHandler.h:88
Definition AdvancedWidgetsModule.cpp:13
Definition NaniteStreamingShared.h:32
Definition NaniteStreamingManager.h:29
bool operator==(const FPageKey &Other) const
Definition NaniteStreamingManager.h:38
bool operator!=(const FPageKey &Other) const
Definition NaniteStreamingManager.h:43
uint32 PageIndex
Definition NaniteStreamingManager.h:31
friend uint32 GetTypeHash(const FPageKey &Key)
Definition NaniteStreamingManager.h:33
bool operator<(const FPageKey &Other) const
Definition NaniteStreamingManager.h:48
uint32 RuntimeResourceID
Definition NaniteStreamingManager.h:30
Definition NaniteResources.h:410
Definition NaniteStreamingManager.h:55
FPageKey Key
Definition NaniteStreamingManager.h:56
bool operator<(const FStreamingRequest &Other) const
Definition NaniteStreamingManager.h:59
uint32 Priority
Definition NaniteStreamingManager.h:57
Definition PimplPtr.h:50