UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MetalProfiler.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "MetalRHIPrivate.h"
7#include "GPUProfiler.h"
8#include "RHIBreadcrumbs.h"
9
11
12// Stats
28
41
45
47
52
58#if STATS
59extern int64 volatile GMetalTexturePageOnTime;
60extern int64 volatile GMetalGPUWorkTime;
61extern int64 volatile GMetalGPUIdleTime;
62extern int64 volatile GMetalPresentTime;
63#endif
64
67
69class FMetalSyncPoint;
70
75{
78
79 bool operator<(const FMetalCommandBufferTiming& RHS) const
80 {
81 // Sort by start time and then by length if the commandbuffer started at the same time
82 if (this->StartTime < RHS.StartTime)
83 {
84 return true;
85 }
86 else if ((this->StartTime == RHS.StartTime) && (this->EndTime > RHS.EndTime))
87 {
88 return true;
89 }
90 return false;
91 }
92};
93
94#if RHI_NEW_GPU_PROFILER == 0
95
97{
98public:
99 void Submit()
100 {
101 FScopeLock Lock(&Mutex);
102 Counter++;
103 }
104
106 void FrameEnd();
107 void RecordFrame();
108
110 {
111 return Timings;
112 }
113
114 static void ResetFrameBufferTimings();
116
117 static void RecordPresent(MTL::CommandBuffer* CommandBuffer);
118 // END WARNING
119
120private:
121 bool bFrameEnded;
122 int32_t Counter = 0;
124 FCriticalSection Mutex;
125
126 static FMetalCommandBufferTimer* Timer;
127};
128
130class FMetalEventNode : public FGPUProfilerEventNode
131{
132public:
133
134 FMetalEventNode(FMetalRHICommandContext& InContext, const TCHAR* InName, FGPUProfilerEventNode* InParent, bool bIsRoot, bool bInFullProfiling)
135 : FGPUProfilerEventNode(InName, InParent)
136 , StartTime(0)
137 , EndTime(0)
138 , Context(InContext)
139 , bRoot(bIsRoot)
140 , bFullProfiling(bInFullProfiling)
141 {
142 }
143
144 virtual ~FMetalEventNode();
145
150 virtual float GetTiming() override;
151 virtual void StartTiming() override;
152 virtual void StopTiming() override;
153
155
156 bool IsRoot() const { return bRoot; }
158
161private:
163 bool bRoot;
164 bool bFullProfiling;
165};
166
168class FMetalEventNodeFrame : public FGPUProfilerEventNodeFrame
169{
170public:
176
178 {
179 delete RootNode;
180 RootNode = nullptr;
181 }
182
184 virtual void StartFrame() override;
185
187 virtual void EndFrame() override;
188
190 virtual float GetRootTimingResults() override;
191
192 virtual void LogDisjointQuery() override;
193
196};
197
198class FMetalContext;
199
200// This class has multiple inheritance but really FGPUTiming is a static class
201class FMetalGPUTiming : public FGPUTiming
202{
203public:
204
209 {
210 StaticInitialize((void*)&Context, PlatformStaticInitialize);
211 }
212
214 {
215 FGPUTiming::SetCalibrationTimestamp({ GPU, CPU });
216 }
217
218private:
219
223 static void PlatformStaticInitialize(void* UserData);
224};
225
227{
228 FString Name;
229 FString Parent;
231
234
237
240
241 virtual ~IMetalStatsScope();
242
243 virtual void Start(MTL::CommandBuffer*& CommandBuffer) = 0;
244 virtual void End(MTL::CommandBuffer*& CommandBuffer) = 0;
245
246 FString GetJSONRepresentation(uint32 PID);
247};
248
250{
251 FMetalCPUStats(FString const& Name);
252 virtual ~FMetalCPUStats();
253
254 void Start(void);
255 void End(void);
256
257 virtual void Start(MTL::CommandBuffer*& CommandBuffer) final override;
258 virtual void End(MTL::CommandBuffer*& CommandBuffer) final override;
259};
260
262{
263 FMetalDisplayStats(uint32 DisplayID, double OutputSeconds, double Duration);
264 virtual ~FMetalDisplayStats();
265
266 virtual void Start(MTL::CommandBuffer*& CommandBuffer) final override;
267 virtual void End(MTL::CommandBuffer*& CommandBuffer) final override;
268};
269
275
277{
278 FMetalCommandBufferStats(MTL::CommandBuffer* CommandBuffer, uint64 GPUThreadIndex);
280
281 virtual void Start(MTL::CommandBuffer*& CommandBuffer) final override;
282 virtual void End(MTL::CommandBuffer*& CommandBuffer) final override;
283
284 MTL::CommandBuffer* CmdBuffer;
285};
286
292struct FMetalGPUProfiler : public FGPUProfiler
293{
296
302
304
305 virtual FGPUProfilerEventNode* CreateEventNode(const TCHAR* InName, FGPUProfilerEventNode* InParent) override;
306
307 void Cleanup();
308
309 virtual void PushEvent(const TCHAR* Name, FColor Color) override;
310 virtual void PopEvent() override;
311
312 void BeginFrame();
313 void EndFrame();
314
317};
318
320{
321 static FMetalProfiler* Self;
322public:
325
327 static FMetalProfiler* GetProfiler();
328 static void DestroyProfiler();
329
330 void BeginCapture(int InNumFramesToCapture = -1);
331 void EndCapture();
332 bool TracingEnabled() const;
333
334 void BeginFrame();
335 void EndFrame();
336
337 void AddDisplayVBlank(uint32 DisplayID, double OutputSeconds, double OutputDuration);
338
343
344 FMetalCPUStats* AddCPUStat(FString const& Name);
345 FMetalCommandBufferStats* AllocateCommandBuffer(MTL::CommandBuffer* CommandBuffer, uint64 GPUThreadIndex);
346 void AddCommandBuffer(FMetalCommandBufferStats* CommandBuffer);
347 virtual void PushEvent(const TCHAR* Name, FColor Color) final override;
348 virtual void PopEvent() final override;
349
350 void SaveTrace();
351
352private:
353 FCriticalSection Mutex;
354
356 TArray<FMetalDisplayStats*> DisplayStats;
358
359 int32 NumFramesToCapture;
360 int32 CaptureFrameNumber;
361
362 bool bRequestStartCapture;
363 bool bRequestStopCapture;
364 bool bEnabled;
365};
366
368{
370 : Stats(nullptr)
371 {
373 if (Profiler)
374 {
375 Stats = Profiler->AddCPUStat(Name);
376 if (Stats)
377 {
378 Stats->Start();
379 }
380 }
381 }
382
384 {
385 if (Stats)
386 {
387 Stats->End();
388 }
389 }
390
392};
393
394#endif
395
396#if RHI_NEW_GPU_PROFILER && WITH_RHI_BREADCRUMBS
397
399{
400 Begin,
401 End,
402 Encode,
403};
404
407{
409 FMetalCommandBuffer* CmdBuffer;
411 FRHIBreadcrumbNode* Node;
412};
413
414// Represents the data required for FRHIBreadcrumbNode
415// Samples can be collected across multiple counter samples and this allows us to merge the results
417{
418 FMetalBreadcrumbEvent(bool bRenderPass) : bWithinRenderPass(bRenderPass)
419 {}
420
421 bool bWithinRenderPass;
422 uint64_t* TimestampTOP = nullptr;
423 uint64_t* TimestampBOP = nullptr;
425};
426
427// Tracks the FRHIBreadcrumbNode's across encoders
429{
430public:
431 inline static FMetalBreadcrumbProfiler* GetInstance()
432 {
433 if(!Instance)
434 {
436 }
437 return Instance;
438 }
439
441 {
442 }
443
445 {
446 FScopeLock Lock(&Mutex);
448 Event.bWithinRenderPass |= bWithinRenderPass;
449
450 return Event;
451 }
452
453 inline void AddSample(FMetalCounterSamplePtr Sample)
454 {
455 FScopeLock Lock(&Mutex);
456
457 uint64_t StartTime, EndTime;
458 Sample->ResolveStageCounters(StartTime, EndTime);
459
461 {
462 CreatedBreadcrumbs[ActiveBreadcrumb].Samples.Add(Sample);
463 }
464 }
465
466 inline void OnBreadcrumbBegin(FRHIBreadcrumbNode* Node)
467 {
468 FScopeLock Lock(&Mutex);
469 ActiveBreadcrumbs.Add(Node);
470 }
471
472 inline void OnBreadcrumbEnd(FRHIBreadcrumbNode* Node)
473 {
474 FScopeLock Lock(&Mutex);
475
477
478 uint64_t* Start = Event.TimestampTOP;
479 uint64_t* End = Event.TimestampBOP;
480
481 // TODO: Carl - We have a rare bug where BeginbreadCrumb is called in a parallel pass, but end is not, we cannot cleanly handle this atm
482 if(Start && End)
483 {
484 if(Event.bWithinRenderPass || Event.Samples.Num() == 0)
485 {
486 *Start = 0;
487 *End = 0;
488 }
489 else
490 {
491 for(FMetalCounterSamplePtr Sample : Event.Samples)
492 {
493 uint64_t StartTime, EndTime;
494 Sample->ResolveStageCounters(StartTime, EndTime);
495
496 *Start = *Start > 0 ? FMath::Min(StartTime, *Start) : StartTime;
497 *End = *End > 0 ? FMath::Max(EndTime, *End) : EndTime;
498 }
499 }
500 }
501
502 ActiveBreadcrumbs.Remove(Node);
503 CreatedBreadcrumbs.Remove(Node);
504 }
505
506 // Resolves all the breakcrumbs added to the command buffer
508
509private:
512
515};
516
517#endif
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
#define DECLARE_CYCLE_STAT_EXTERN(CounterName, StatId, GroupId, API)
Definition Stats.h:679
#define DECLARE_DWORD_COUNTER_STAT_EXTERN(CounterName, StatId, GroupId, API)
Definition Stats.h:682
#define DECLARE_DWORD_ACCUMULATOR_STAT_EXTERN(CounterName, StatId, GroupId, API)
Definition Stats.h:684
#define DECLARE_MEMORY_STAT_EXTERN(CounterName, StatId, GroupId, API)
Definition Stats.h:687
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE::FPlatformRecursiveMutex FCriticalSection
Definition CriticalSection.h:53
#define DECLARE_DELEGATE_OneParam(DelegateName, Param1Type)
Definition DelegateCombinations.h:48
return true
Definition ExternalRpcRegistry.cpp:601
int64 volatile GMetalGPUWorkTime
Definition MetalProfiler.cpp:61
int64 volatile GMetalPresentTime
Definition MetalProfiler.cpp:63
int64 volatile GMetalTexturePageOnTime
Definition MetalProfiler.cpp:60
int64 volatile GMetalGPUIdleTime
Definition MetalProfiler.cpp:62
EMTLFenceType
Definition MetalProfiler.h:271
@ EMTLFenceTypeWait
Definition MetalProfiler.h:272
@ EMTLFenceTypeUpdate
Definition MetalProfiler.h:273
FRWLock Lock
Definition UnversionedPropertySerialization.cpp:921
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MetalProfiler.h:97
static FMetalCommandBufferTimer & GetFrameBufferTimer()
Definition MetalProfiler.cpp:179
void AddTiming(FMetalCommandBufferTiming Timing)
Definition MetalProfiler.cpp:76
static void ResetFrameBufferTimings()
Definition MetalProfiler.cpp:169
void FrameEnd()
Definition MetalProfiler.cpp:88
const TArray< FMetalCommandBufferTiming > & GetTimings()
Definition MetalProfiler.h:109
void RecordFrame()
Definition MetalProfiler.cpp:99
static void RecordPresent(MTL::CommandBuffer *CommandBuffer)
Definition MetalProfiler.cpp:157
void Submit()
Definition MetalProfiler.h:99
Definition MetalCommandBuffer.h:17
Definition MetalProfiler.h:169
virtual void LogDisjointQuery() override
Definition MetalProfiler.cpp:255
virtual float GetRootTimingResults() override
Definition MetalProfiler.cpp:250
FMetalEventNodeFrame(FMetalRHICommandContext &InContext, bool bInFullProfiling)
Definition MetalProfiler.h:171
bool bFullProfiling
Definition MetalProfiler.h:195
virtual ~FMetalEventNodeFrame()
Definition MetalProfiler.h:177
virtual void EndFrame() override
Definition MetalProfiler.cpp:244
virtual void StartFrame() override
Definition MetalProfiler.cpp:238
FMetalEventNode * RootNode
Definition MetalProfiler.h:194
Definition MetalProfiler.h:131
bool IsRoot() const
Definition MetalProfiler.h:156
FMetalEventNode(FMetalRHICommandContext &InContext, const TCHAR *InName, FGPUProfilerEventNode *InParent, bool bIsRoot, bool bInFullProfiling)
Definition MetalProfiler.h:134
FMetalSyncPoint * SyncPoint
Definition MetalProfiler.h:154
uint64 EndTime
Definition MetalProfiler.h:160
virtual void StopTiming() override
Definition MetalProfiler.cpp:227
virtual ~FMetalEventNode()
Definition MetalProfiler.cpp:208
uint64 StartTime
Definition MetalProfiler.h:159
uint64 GetCycles()
Definition MetalProfiler.h:157
virtual void StartTiming() override
Definition MetalProfiler.cpp:219
virtual float GetTiming() override
Definition MetalProfiler.cpp:213
Definition MetalProfiler.h:202
FMetalGPUTiming(FMetalRHICommandContext &Context)
Definition MetalProfiler.h:208
void SetCalibrationTimestamp(uint64 GPU, uint64 CPU)
Definition MetalProfiler.h:213
Definition MetalProfiler.h:320
void AddCommandBuffer(FMetalCommandBufferStats *CommandBuffer)
Definition MetalProfiler.cpp:693
virtual void PopEvent() final override
Definition MetalProfiler.cpp:711
void AddDisplayVBlank(uint32 DisplayID, double OutputSeconds, double OutputDuration)
Definition MetalProfiler.cpp:522
static FMetalProfiler * CreateProfiler(FMetalRHICommandContext &InContext)
Definition MetalProfiler.cpp:556
FMetalCPUStats * AddCPUStat(FString const &Name)
Definition MetalProfiler.cpp:673
void BeginFrame()
Definition MetalProfiler.cpp:602
static void DestroyProfiler()
Definition MetalProfiler.cpp:576
void SaveTrace()
Definition MetalProfiler.cpp:716
void EndCapture()
Definition MetalProfiler.cpp:592
FMetalCommandBufferStats * AllocateCommandBuffer(MTL::CommandBuffer *CommandBuffer, uint64 GPUThreadIndex)
Definition MetalProfiler.cpp:688
bool TracingEnabled() const
Definition MetalProfiler.cpp:597
void EncodeDispatch(FMetalCommandBufferStats *CmdBufStats, char const *DrawCall)
Definition MetalProfiler.cpp:663
virtual void PushEvent(const TCHAR *Name, FColor Color) final override
Definition MetalProfiler.cpp:706
void EncodeBlit(FMetalCommandBufferStats *CmdBufStats, char const *DrawCall)
Definition MetalProfiler.cpp:643
void EncodeDraw(FMetalCommandBufferStats *CmdBufStats, char const *DrawCall, uint32 RHIPrimitives, uint32 RHIVertices, uint32 RHIInstances)
Definition MetalProfiler.cpp:633
static FMetalProfiler * GetProfiler()
Definition MetalProfiler.cpp:571
~FMetalProfiler()
Definition MetalProfiler.cpp:547
void BeginCapture(int InNumFramesToCapture=-1)
Definition MetalProfiler.cpp:582
void EndFrame()
Definition MetalProfiler.cpp:616
Definition MetalRHIContext.h:48
Definition MetalSubmission.h:64
Definition ScopeLock.h:141
Definition Array.h:670
Definition IndirectArray.h:20
Definition UnrealString.h.inl:34
Definition SharedPointer.h:692
Type
Definition PawnAction_Move.h:11
void Sample(float *Dst, float X, float Y, float Z)
Definition FieldSystemNoiseAlgo.cpp:59
UE::FRecursiveMutex Mutex
Definition MeshPaintVirtualTexture.cpp:164
@ Start
Definition GeoEnum.h:100
Definition Color.h:486
Definition MetalProfiler.h:250
virtual ~FMetalCPUStats()
Definition MetalProfiler.cpp:497
void Start(void)
Definition MetalProfiler.cpp:502
void End(void)
Definition MetalProfiler.cpp:508
Definition MetalProfiler.h:277
MTL::CommandBuffer * CmdBuffer
Definition MetalProfiler.h:284
virtual void Start(MTL::CommandBuffer *&CommandBuffer) final override
Definition MetalProfiler.cpp:412
virtual ~FMetalCommandBufferStats()
Definition MetalProfiler.cpp:408
Definition MetalProfiler.h:75
CFTimeInterval StartTime
Definition MetalProfiler.h:76
bool operator<(const FMetalCommandBufferTiming &RHS) const
Definition MetalProfiler.h:79
CFTimeInterval EndTime
Definition MetalProfiler.h:77
Definition MetalProfiler.h:262
virtual ~FMetalDisplayStats()
Definition MetalProfiler.cpp:473
virtual void Start(MTL::CommandBuffer *&CommandBuffer) final override
Definition MetalProfiler.cpp:477
Definition MetalProfiler.h:293
virtual void PushEvent(const TCHAR *Name, FColor Color) override
Definition MetalProfiler.cpp:275
virtual void PopEvent() override
Definition MetalProfiler.cpp:283
void Cleanup()
Definition MetalProfiler.cpp:270
FMetalGPUProfiler(FMetalRHICommandContext &InContext)
Definition MetalProfiler.h:297
void BeginFrame()
Definition MetalProfiler.cpp:294
FMetalGPUTiming TimingSupport
Definition MetalProfiler.h:315
FMetalRHICommandContext & Context
Definition MetalProfiler.h:316
virtual ~FMetalGPUProfiler()
Definition MetalProfiler.h:303
virtual FGPUProfilerEventNode * CreateEventNode(const TCHAR *InName, FGPUProfilerEventNode *InParent) override
Definition MetalProfiler.cpp:260
void EndFrame()
Definition MetalProfiler.cpp:311
TIndirectArray< FMetalEventNodeFrame > GPUHitchEventNodeFrames
Definition MetalProfiler.h:295
Definition MetalProfiler.h:368
FMetalCPUStats * Stats
Definition MetalProfiler.h:391
FScopedMetalCPUStats(FString const &Name)
Definition MetalProfiler.h:369
~FScopedMetalCPUStats()
Definition MetalProfiler.h:383
Definition MetalProfiler.h:227
uint64 GPUStartTime
Definition MetalProfiler.h:235
virtual void Start(MTL::CommandBuffer *&CommandBuffer)=0
uint64 CPUStartTime
Definition MetalProfiler.h:232
TArray< IMetalStatsScope * > Children
Definition MetalProfiler.h:230
virtual ~IMetalStatsScope()
Definition MetalProfiler.cpp:349
virtual void End(MTL::CommandBuffer *&CommandBuffer)=0
FString GetJSONRepresentation(uint32 PID)
Definition MetalProfiler.cpp:357
FString Parent
Definition MetalProfiler.h:229
uint64 CPUThreadIndex
Definition MetalProfiler.h:238
uint64 GPUEndTime
Definition MetalProfiler.h:236
FString Name
Definition MetalProfiler.h:228
uint64 GPUThreadIndex
Definition MetalProfiler.h:239
uint64 CPUEndTime
Definition MetalProfiler.h:233