ReXGlue SDK
Loading...
Searching...
No Matches
perf.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#include <cstring>
16#include <optional>
17#include <string>
18#include <string_view>
19
20#include <rex/platform.h>
21#include <rex/result.h>
22#include <rex/types.h>
23
24namespace rex::platform {
25
27enum class CounterID : u8 {
28 kFrameTimeUs,
29 kFps,
30};
31
33enum class CounterType : u8 {
36};
37
39inline constexpr size_t kMaxCounters = 64;
40
50 const char* name, CounterType type = CounterType::kAccumulator);
51
57REX_API std::optional<CounterID> FindCounter(std::string_view name);
58
63
64REX_API void SetCounter(CounterID id, i64 value);
65
71REX_API void IncrementCounter(CounterID id, i64 delta = 1);
72
75
78
81
84
90REX_API void SetCSVLogPath(const std::string& path);
91
94
95REX_API void CloseCSV();
96
97} // namespace rex::platform
98
99#ifdef REXGLUE_ENABLE_PERF_COUNTERS
100
108#define REX_PERF_APPLY(name, call) \
109 do { \
110 static const auto rex_perf_found = ::rex::platform::FindCounter(name); \
111 if (rex_perf_found) { \
112 const ::rex::platform::CounterID rex_perf_id = *rex_perf_found; \
113 call; \
114 } \
115 } while (false)
116
127#define REX_PERF_SET(name, value) \
128 REX_PERF_APPLY(name, ::rex::platform::SetCounter(rex_perf_id, value))
129
139#define REX_PERF_INC(name) REX_PERF_APPLY(name, ::rex::platform::IncrementCounter(rex_perf_id))
140
151#define REX_PERF_ADD(name, delta) \
152 REX_PERF_APPLY(name, ::rex::platform::IncrementCounter(rex_perf_id, delta))
153
154#else
155
167#define REX_PERF_SET(name, value)
168#define REX_PERF_INC(name)
169#define REX_PERF_ADD(name, delta)
170
171#endif
172
173#ifdef REXGLUE_ENABLE_PROFILING
174
175#include <tracy/Tracy.hpp>
176
186#define REX_PROFILE_SCOPE(name) ZoneNamedN(___tracy_cpu_zone, name, TracyIsStarted)
187
198#define REX_PROFILE_SCOPE_TEXT(name, detail) \
199 ZoneNamedN(___tracy_cpu_zone_i, name, TracyIsStarted); \
200 ZoneTextV(___tracy_cpu_zone_i, detail, std::strlen(detail))
201
211#define REX_PROFILE_THREAD(name) \
212 do { \
213 if (TracyIsStarted) \
214 tracy::SetThreadName(name); \
215 } while (0)
216
217#ifdef TRACY_FIBERS
227#define REX_PROFILE_FIBER_ENTER(name) \
228 do { \
229 if (TracyIsStarted) \
230 TracyFiberEnter(name); \
231 } while (0)
232
240#define REX_PROFILE_FIBER_LEAVE() \
241 do { \
242 if (TracyIsStarted) \
243 TracyFiberLeave; \
244 } while (0)
245#else
256#define REX_PROFILE_FIBER_ENTER(name) ((void)sizeof(decltype(name)))
264#define REX_PROFILE_FIBER_LEAVE()
265#endif
266
277#define REX_PROFILE_PLOT(name, value) \
278 do { \
279 if (TracyIsStarted) \
280 TracyPlot(name, static_cast<::rex::i64>(value)); \
281 } while (0)
282
293#define REX_PROFILE_PLOT_F64(name, value) \
294 do { \
295 if (TracyIsStarted) \
296 TracyPlot(name, static_cast<::rex::f64>(value)); \
297 } while (0)
298
308#define REX_PROFILE_ALLOC(ptr, size) \
309 do { \
310 if (TracyIsStarted) \
311 TracyAlloc(ptr, size); \
312 } while (0)
313
321#define REX_PROFILE_FREE(ptr) \
322 do { \
323 if (TracyIsStarted) \
324 TracyFree(ptr); \
325 } while (0)
326
338#define REX_PROFILE_ALLOC_NAMED(ptr, size, pool) \
339 do { \
340 if (TracyIsStarted) \
341 TracyAllocN(ptr, size, pool); \
342 } while (0)
343
353#define REX_PROFILE_FREE_NAMED(ptr, pool) \
354 do { \
355 if (TracyIsStarted) \
356 TracyFreeN(ptr, pool); \
357 } while (0)
358
369#define REX_PROFILE_ALLOC_STACK(ptr, size, depth) \
370 do { \
371 if (TracyIsStarted) \
372 TracyAllocS(ptr, size, depth); \
373 } while (0)
374
384#define REX_PROFILE_FREE_STACK(ptr, depth) \
385 do { \
386 if (TracyIsStarted) \
387 TracyFreeS(ptr, depth); \
388 } while (0)
389
401#define REX_PROFILE_ALLOC_NAMED_STACK(ptr, size, depth, pool) \
402 do { \
403 if (TracyIsStarted) \
404 TracyAllocNS(ptr, size, depth, pool); \
405 } while (0)
406
417#define REX_PROFILE_FREE_NAMED_STACK(ptr, depth, pool) \
418 do { \
419 if (TracyIsStarted) \
420 TracyFreeNS(ptr, depth, pool); \
421 } while (0)
422
432#define REX_PROFILE_SCOPE_DYNAMIC(name) \
433 ZoneNamed(___tracy_cpu_zone_d, TracyIsStarted); \
434 const std::string_view ___tracy_zone_name_d = (name); \
435 ZoneNameV(___tracy_cpu_zone_d, ___tracy_zone_name_d.data(), ___tracy_zone_name_d.size())
436
444#define REX_PROFILE_FRAME() \
445 do { \
446 if (TracyIsStarted) \
447 FrameMark; \
448 } while (0)
449
461#define REX_PROFILE_IS_CONNECTED() (TracyIsStarted && TracyIsConnected)
462
463#else
464
481#define REX_PROFILE_SCOPE(name)
482#define REX_PROFILE_SCOPE_TEXT(name, detail)
483#define REX_PROFILE_THREAD(name)
484#define REX_PROFILE_FIBER_ENTER(name) ((void)sizeof(decltype(name)))
485#define REX_PROFILE_FIBER_LEAVE()
486#define REX_PROFILE_PLOT(name, value)
487#define REX_PROFILE_PLOT_F64(name, value)
488#define REX_PROFILE_ALLOC(ptr, size)
489#define REX_PROFILE_FREE(ptr)
490#define REX_PROFILE_ALLOC_NAMED(ptr, size, pool)
491#define REX_PROFILE_FREE_NAMED(ptr, pool)
492#define REX_PROFILE_ALLOC_STACK(ptr, size, depth)
493#define REX_PROFILE_FREE_STACK(ptr, depth)
494#define REX_PROFILE_ALLOC_NAMED_STACK(ptr, size, depth, pool)
495#define REX_PROFILE_FREE_NAMED_STACK(ptr, depth, pool)
496#define REX_PROFILE_SCOPE_DYNAMIC(name)
497#define REX_PROFILE_FRAME()
498#define REX_PROFILE_IS_CONNECTED() (false)
499
500#endif // REXGLUE_ENABLE_PROFILING
501
502namespace rex::platform {
503
505class Profiler {
506 public:
508 static void Startup() {
509#ifdef REXGLUE_ENABLE_PROFILING
510 if (!tracy::IsProfilerStarted())
511 tracy::StartupProfiler();
512#endif
513 }
514
520 static void OnThreadEnter(const char* name = nullptr) {
521#ifdef REXGLUE_ENABLE_PROFILING
522 if (name && tracy::IsProfilerStarted())
523 tracy::SetThreadName(name);
524#else
525 (void)name;
526#endif
527 }
528
529 static void OnThreadExit() {}
530
532 static void EndFrame() {
533#ifdef REXGLUE_ENABLE_PROFILING
534 if (tracy::IsProfilerStarted()) {
535 FrameMark;
536 }
537#endif
538#ifdef REXGLUE_ENABLE_PERF_COUNTERS
541#endif
542 }
543
544 static void Flush() {}
545
547 static void Shutdown() {
548#ifdef REXGLUE_ENABLE_PROFILING
549 if (tracy::IsProfilerStarted())
550 tracy::ShutdownProfiler();
551#endif
552#ifdef REXGLUE_ENABLE_PERF_COUNTERS
553 CloseCSV();
554#endif
555 }
556
558 static bool IsEnabled() {
559#ifdef REXGLUE_ENABLE_PROFILING
560 return tracy::IsProfilerStarted();
561#else
562 return false;
563#endif
564 }
565};
566
567} // namespace rex::platform
Definition perf.h:505
static bool IsEnabled()
Definition perf.h:558
static void Startup()
Definition perf.h:508
static void EndFrame()
Definition perf.h:532
static void Shutdown()
Definition perf.h:547
static void OnThreadEnter(const char *name=nullptr)
Definition perf.h:520
Definition platform.h:345
std::optional< CounterID > FindCounter(std::string_view name)
void InitCounters()
void ResetFrameCounters()
CounterType
Definition perf.h:33
@ kGauge
Definition perf.h:35
@ kAccumulator
Definition perf.h:34
const char * GetCounterName(CounterID id)
i64 GetCounter(CounterID id)
i64 GetSnapshotCounter(CounterID id)
Result< CounterID > RegisterCounter(const char *name, CounterType type=CounterType::kAccumulator)
void SetCSVLogPath(const std::string &path)
void WriteCSVFrame()
CounterID
Definition perf.h:27
constexpr size_t kMaxCounters
Definition perf.h:39
void IncrementCounter(CounterID id, i64 delta=1)
std::expected< T, Error > Result
Definition result.h:98
Platform flags, packing macros and export markers.
#define REX_API
Definition platform.h:177
Integer types, byte order wrappers and size literals.