xref: /aosp_15_r20/external/mesa3d/src/util/perf/cpu_trace.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2022 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef CPU_TRACE_H
7 #define CPU_TRACE_H
8 
9 #include "u_perfetto.h"
10 #include "u_gpuvis.h"
11 
12 #include "util/detect_os.h"
13 #include "util/macros.h"
14 
15 #if defined(HAVE_PERFETTO)
16 
17 /* note that util_perfetto_is_tracing_enabled always returns false util
18  * util_perfetto_init is called
19  */
20 #define _MESA_TRACE_BEGIN(name)                                              \
21    do {                                                                      \
22       if (unlikely(util_perfetto_is_tracing_enabled()))                      \
23          util_perfetto_trace_begin(name);                                    \
24    } while (0)
25 
26 #define _MESA_TRACE_FLOW_BEGIN(name, id)                                     \
27    do {                                                                      \
28       if (unlikely(util_perfetto_is_tracing_enabled()))                      \
29          util_perfetto_trace_begin_flow(name, id);                           \
30    } while (0)
31 
32 #define _MESA_TRACE_END()                                                    \
33    do {                                                                      \
34       if (unlikely(util_perfetto_is_tracing_enabled()))                      \
35          util_perfetto_trace_end();                                          \
36    } while (0)
37 
38 #define _MESA_TRACE_SET_COUNTER(name, value)                                 \
39    do {                                                                      \
40       if (unlikely(util_perfetto_is_tracing_enabled()))                      \
41          util_perfetto_counter_set(name, value);                             \
42    } while (0)
43 
44 #define _MESA_TRACE_TIMESTAMP_BEGIN(name, track_id, flow_id, timestamp)      \
45    do {                                                                      \
46       if (unlikely(util_perfetto_is_tracing_enabled()))                      \
47          util_perfetto_trace_full_begin(name, track_id, flow_id, timestamp); \
48    } while (0)
49 
50 #define _MESA_TRACE_TIMESTAMP_END(name, track_id, timestamp)                 \
51    do {                                                                      \
52       if (unlikely(util_perfetto_is_tracing_enabled()))                      \
53          util_perfetto_trace_full_end(name, track_id, timestamp);            \
54    } while (0)
55 
56 /* NOTE: for now disable atrace for C++ to workaround a ndk bug with ordering
57  * between stdatomic.h and atomic.h.  See:
58  *
59  *   https://github.com/android/ndk/issues/1178
60  */
61 #elif DETECT_OS_ANDROID && !defined(__cplusplus)
62 
63 #include <cutils/trace.h>
64 
65 #define _MESA_TRACE_BEGIN(name)                                              \
66    atrace_begin(ATRACE_TAG_GRAPHICS, name)
67 #define _MESA_TRACE_END() atrace_end(ATRACE_TAG_GRAPHICS)
68 #define _MESA_TRACE_FLOW_BEGIN(name, id)                                     \
69    atrace_begin(ATRACE_TAG_GRAPHICS, name)
70 #define _MESA_TRACE_SET_COUNTER(name, value)
71 #define _MESA_TRACE_TIMESTAMP_BEGIN(name, track_id, flow_id, timestamp)
72 #define _MESA_TRACE_TIMESTAMP_END(name, track_id, timestamp)
73 #else
74 
75 #define _MESA_TRACE_BEGIN(name)
76 #define _MESA_TRACE_END()
77 #define _MESA_TRACE_FLOW_BEGIN(name, id)
78 #define _MESA_TRACE_SET_COUNTER(name, value)
79 #define _MESA_TRACE_TIMESTAMP_BEGIN(name, track_id, flow_id, timestamp)
80 #define _MESA_TRACE_TIMESTAMP_END(name, track_id, timestamp)
81 
82 #endif /* HAVE_PERFETTO */
83 
84 #if defined(HAVE_GPUVIS)
85 
86 #define _MESA_GPUVIS_TRACE_BEGIN(name) util_gpuvis_begin(name)
87 #define _MESA_GPUVIS_TRACE_END() util_gpuvis_end()
88 
89 #else
90 
91 #define _MESA_GPUVIS_TRACE_BEGIN(name)
92 #define _MESA_GPUVIS_TRACE_END()
93 
94 #endif /* HAVE_GPUVIS */
95 
96 #if __has_attribute(cleanup) && __has_attribute(unused)
97 
98 #define _MESA_TRACE_SCOPE_VAR_CONCAT(name, suffix) name##suffix
99 #define _MESA_TRACE_SCOPE_VAR(suffix)                                        \
100    _MESA_TRACE_SCOPE_VAR_CONCAT(_mesa_trace_scope_, suffix)
101 
102 /* This must expand to a single non-scoped statement for
103  *
104  *    if (cond)
105  *       _MESA_TRACE_SCOPE(...)
106  *
107  * to work.
108  */
109 #define _MESA_TRACE_SCOPE(name)                                              \
110    int _MESA_TRACE_SCOPE_VAR(__LINE__)                                       \
111       __attribute__((cleanup(_mesa_trace_scope_end), unused)) =              \
112          _mesa_trace_scope_begin(name)
113 
114 #define _MESA_TRACE_SCOPE_FLOW(name, id)                                     \
115    int _MESA_TRACE_SCOPE_VAR(__LINE__)                                       \
116       __attribute__((cleanup(_mesa_trace_scope_end), unused)) =              \
117          _mesa_trace_scope_flow_begin(name, id)
118 
119 static inline int
_mesa_trace_scope_begin(const char * name)120 _mesa_trace_scope_begin(const char *name)
121 {
122    _MESA_TRACE_BEGIN(name);
123    _MESA_GPUVIS_TRACE_BEGIN(name);
124    return 0;
125 }
126 
127 static inline int
_mesa_trace_scope_flow_begin(const char * name,uint64_t * id)128 _mesa_trace_scope_flow_begin(const char *name, uint64_t *id)
129 {
130    if (*id == 0)
131       *id = util_perfetto_next_id();
132    _MESA_TRACE_FLOW_BEGIN(name, *id);
133    _MESA_GPUVIS_TRACE_BEGIN(name);
134    return 0;
135 }
136 
137 static inline void
_mesa_trace_scope_end(UNUSED int * scope)138 _mesa_trace_scope_end(UNUSED int *scope)
139 {
140    _MESA_GPUVIS_TRACE_END();
141    _MESA_TRACE_END();
142 }
143 
144 #else
145 
146 #define _MESA_TRACE_SCOPE(name)
147 
148 #endif /* __has_attribute(cleanup) && __has_attribute(unused) */
149 
150 #define MESA_TRACE_SCOPE(name) _MESA_TRACE_SCOPE(name)
151 #define MESA_TRACE_SCOPE_FLOW(name, id) _MESA_TRACE_SCOPE_FLOW(name, id)
152 #define MESA_TRACE_FUNC() _MESA_TRACE_SCOPE(__func__)
153 #define MESA_TRACE_FUNC_FLOW(id) _MESA_TRACE_SCOPE_FLOW(__func__, id)
154 #define MESA_TRACE_SET_COUNTER(name, value) _MESA_TRACE_SET_COUNTER(name, value)
155 #define MESA_TRACE_TIMESTAMP_BEGIN(name, track_id, flow_id, timestamp) \
156    _MESA_TRACE_TIMESTAMP_BEGIN(name, track_id, flow_id, timestamp)
157 #define MESA_TRACE_TIMESTAMP_END(name, track_id, timestamp) \
158    _MESA_TRACE_TIMESTAMP_END(name, track_id, timestamp)
159 
160 static inline void
util_cpu_trace_init()161 util_cpu_trace_init()
162 {
163    util_perfetto_init();
164    util_gpuvis_init();
165 }
166 
167 #endif /* CPU_TRACE_H */
168