Monado OpenXR Runtime
u_trace_marker.h
Go to the documentation of this file.
1 // Copyright 2020-2022, Collabora, Ltd.
2 // SPDX-License-Identifier: BSL-1.0
3 /*!
4  * @file
5  * @brief Tracing support code, see @ref tracing.
6  * @author Jakob Bornecrantz <jakob@collabora.com>
7  * @ingroup aux_util
8  */
9 
10 #pragma once
11 
12 #include "xrt/xrt_compiler.h"
13 #include "xrt/xrt_config_os.h"
14 #include "xrt/xrt_config_have.h"
15 #include "xrt/xrt_config_build.h" // IWYU pragma: keep
16 
17 #include <stdio.h>
18 
19 #if defined(__cplusplus) && (defined(__clang__) || defined(__GNUC__))
20 #pragma GCC diagnostic push
21 #if defined(__GNUC__) && !defined(__clang__)
22 #pragma GCC diagnostic ignored "-Wpedantic"
23 #elif defined(__clang__)
24 #pragma GCC diagnostic ignored "-Wc++20-designator"
25 #endif
26 #endif
27 
28 #if defined(XRT_FEATURE_TRACING) && defined(XRT_HAVE_PERCETTO)
29 #define U_TRACE_PERCETTO
30 #include <percetto.h>
31 #endif
32 
33 #if !defined(XRT_FEATURE_TRACING) || !defined(XRT_HAVE_TRACY)
34 #define U_TRACE_FUNC_COLOR(CATEGORY, COLOR) \
35  (void)COLOR; \
36  U_TRACE_FUNC(CATEGORY)
37 
38 #define U_TRACE_IDENT_COLOR(CATEGORY, IDENT, COLOR) \
39  (void)COLOR; \
40  U_TRACE_IDENT(CATEGORY, IDENT)
41 
42 #define U_TRACE_BEGIN_COLOR(CATEGORY, IDENT, COLOR) \
43  (void)COLOR; \
44  U_TRACE_BEGIN(CATEGORY, IDENT)
45 #endif
46 
47 #if defined(XRT_FEATURE_TRACING) && defined(XRT_HAVE_TRACY)
48 #ifndef TRACY_ENABLE
49 #define TRACY_ENABLE
50 #endif // TRACY_ENABLE
51 #define U_TRACE_TRACY
52 #include "tracy/TracyC.h"
53 #ifdef __cplusplus
54 #include "tracy/Tracy.hpp"
55 #endif
56 #endif
57 
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62 
63 /*!
64  * Should the extra tracks be enabled, see @ref tracing.
65  *
66  * @ingroup aux_util
67  */
69 {
70  U_TRACE_WHICH_SERVICE,
71  U_TRACE_WHICH_OPENXR,
72 };
73 
74 /*!
75  * Internal setup function, use @ref U_TRACE_TARGET_SETUP, see @ref tracing.
76  *
77  * @ingroup aux_util
78  */
79 void
81 
82 /*!
83  * Must be called from a non-static/global constructor context.
84  *
85  * @ingroup aux_util
86  */
87 void
89 
90 #define COLOR_TRACE_MARKER(COLOR) U_TRACE_FUNC_COLOR(color, COLOR)
91 #define COLOR_TRACE_IDENT(IDENT, COLOR) U_TRACE_IDENT_COLOR(color, IDENT, COLOR)
92 #define COLOR_TRACE_BEGIN(IDENT, COLOR) U_TRACE_BEGIN_COLOR(color, IDENT, COLOR)
93 #define COLOR_TRACE_END(IDENT) U_TRACE_END(color, IDENT)
94 
95 #define VK_TRACE_MARKER() U_TRACE_FUNC_COLOR(vk, 0xffffff)
96 #define VK_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(vk, IDENT, 0xffffff)
97 #define VK_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(vk, IDENT, 0xffffff)
98 #define VK_TRACE_END(IDENT) U_TRACE_END(vk, IDENT)
99 
100 #define XRT_TRACE_MARKER() U_TRACE_FUNC_COLOR(xrt, 0x708090)
101 #define XRT_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(xrt, IDENT, 0x708090)
102 #define XRT_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(xrt, IDENT, 0x708090)
103 #define XRT_TRACE_END(IDENT) U_TRACE_END(xrt, IDENT)
104 
105 #define DRV_TRACE_MARKER() U_TRACE_FUNC_COLOR(drv, 0x000080)
106 #define DRV_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(drv, IDENT, 0x000080)
107 #define DRV_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(drv, IDENT, 0x000080)
108 #define DRV_TRACE_END(IDENT) U_TRACE_END(drv, IDENT)
109 
110 #define IPC_TRACE_MARKER() U_TRACE_FUNC_COLOR(ipc, 0x87cefa)
111 #define IPC_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(ipc, IDENT, 0x87cefa)
112 #define IPC_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(ipc, IDENT, 0x87cefa)
113 #define IPC_TRACE_END(IDENT) U_TRACE_END(ipc, IDENT)
114 
115 #define OXR_TRACE_MARKER() U_TRACE_FUNC_COLOR(oxr, 0x7fffd4)
116 #define OXR_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(oxr, IDENT, 0x7fffd4)
117 #define OXR_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(oxr, IDENT, 0x7fffd4)
118 #define OXR_TRACE_END(IDENT) U_TRACE_END(oxr, IDENT, 0x7fffd4)
119 
120 #define COMP_TRACE_MARKER() U_TRACE_FUNC_COLOR(comp, 0x00ff00)
121 #define COMP_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(comp, IDENT, 0x00ff00)
122 #define COMP_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(comp, IDENT, 0x00ff00)
123 #define COMP_TRACE_END(IDENT) U_TRACE_END(comp, IDENT)
124 
125 #define SINK_TRACE_MARKER() U_TRACE_FUNC_COLOR(sink, 0xffa500)
126 #define SINK_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(sink, IDENT, 0xffa500)
127 #define SINK_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(sink, IDENT, 0xffa500)
128 #define SINK_TRACE_END(IDENT) U_TRACE_END(sink, IDENT)
129 
130 #define SWAPCHAIN_TRACE_MARKER() U_TRACE_FUNC_COLOR(sc, 0x007700)
131 #define SWAPCHAIN_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(sc, IDENT, 0x007700)
132 #define SWAPCHAIN_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(sc, IDENT, 0x007700)
133 #define SWAPCHAIN_TRACE_END(IDENT) U_TRACE_END(sc, IDENT)
134 
135 #define TRACK_TRACE_MARKER() U_TRACE_FUNC_COLOR(track, 0xff0000)
136 #define TRACK_TRACE_IDENT(IDENT) U_TRACE_IDENT_COLOR(track, IDENT, 0xff0000)
137 #define TRACK_TRACE_BEGIN(IDENT) U_TRACE_BEGIN_COLOR(track, IDENT, 0xff0000)
138 #define TRACK_TRACE_END(IDENT) U_TRACE_END(track, IDENT, 0xff0000)
139 
140 
141 /*
142  *
143  * When disabled.
144  *
145  */
146 
147 #ifndef XRT_FEATURE_TRACING
148 
149 
150 #define U_TRACE_FUNC(CATEGORY) \
151  do { \
152  } while (false)
153 
154 #define U_TRACE_IDENT(CATEGORY, IDENT) \
155  do { \
156  } while (false)
157 
158 #define U_TRACE_BEGIN(CATEGORY, IDENT) \
159  int __trace_##IDENT = 0; /* To ensure they are balanced */ \
160  do { \
161  } while (false)
162 
163 #define U_TRACE_END(CATEGORY, IDENT) \
164  do { \
165  (void)__trace_##IDENT; /* To ensure they are balanced */ \
166  } while (false)
167 
168 #define U_TRACE_EVENT_BEGIN_ON_TRACK(CATEGORY, TRACK, TIME, NAME) \
169  do { \
170  } while (false)
171 
172 #define U_TRACE_EVENT_BEGIN_ON_TRACK_DATA(CATEGORY, TRACK, TIME, NAME, ...) \
173  do { \
174  } while (false)
175 
176 #define U_TRACE_EVENT_END_ON_TRACK(CATEGORY, TRACK, TIME) \
177  do { \
178  } while (false)
179 
180 #define U_TRACE_INSTANT_ON_TRACK(CATEGORY, TRACK, TIME, NAME) \
181  do { \
182  } while (false)
183 
184 #define U_TRACE_CATEGORY_IS_ENABLED(_) (false)
185 
186 #define U_TRACE_SET_THREAD_NAME(STRING) \
187  do { \
188  (void)STRING; \
189  } while (false)
190 
191 /*!
192  * Add to target c file to enable tracing, see @ref tracing.
193  *
194  * @ingroup aux_util
195  */
196 #define U_TRACE_TARGET_SETUP(WHICH)
197 
198 
199 /*
200  *
201  * Tracy support.
202  *
203  */
204 
205 #elif defined(XRT_HAVE_TRACY) // && XRT_FEATURE_TRACING
206 
207 // Different wrappers for different cases.
208 #ifdef __cplusplus
209 
210 #define U_TRACE_FUNC_COLOR(CATEGORY, COLOR) ZoneScopedC(COLOR)
211 
212 #define U_TRACE_FUNC(CATEGORY) ZoneScoped
213 
214 #define U_TRACE_IDENT_COLOR(CATEGORY, IDENT, COLOR) ZoneScopedNC(#IDENT, COLOR)
215 
216 #define U_TRACE_IDENT(CATEGORY, IDENT) ZoneScopedN(#IDENT)
217 
218 #elif !defined(XRT_OS_WINDOWS) // !__cplusplus
219 
220 static inline void
221 u_trace_scope_cleanup(TracyCZoneCtx *ctx_ptr)
222 {
223  TracyCZoneEnd(*ctx_ptr);
224 }
225 
226 #define U_TRACE_FUNC_COLOR(CATEGORY, COLOR) \
227  static const struct ___tracy_source_location_data __func_loc = { \
228  NULL, __func__, __FILE__, (uint32_t)__LINE__, COLOR, \
229  }; \
230  TracyCZoneCtx __attribute__((cleanup(u_trace_scope_cleanup))) ctx = \
231  ___tracy_emit_zone_begin(&__func_loc, true); \
232  (void)ctx
233 
234 
235 #define U_TRACE_FUNC(CATEGORY) \
236  static const struct ___tracy_source_location_data __func_loc = { \
237  NULL, __func__, __FILE__, (uint32_t)__LINE__, 0, \
238  }; \
239  TracyCZoneCtx __attribute__((cleanup(u_trace_scope_cleanup))) ctx = \
240  ___tracy_emit_zone_begin(&__func_loc, true); \
241  (void)ctx
242 
243 #define U_TRACE_IDENT_COLOR(CATEGORY, IDENT, COLOR) \
244  static const struct ___tracy_source_location_data __##IDENT##_loc = { \
245  #IDENT, __func__, __FILE__, (uint32_t)__LINE__, COLOR, \
246  }; \
247  TracyCZoneCtx __attribute__((cleanup(u_trace_scope_cleanup))) ctx##IDENT = \
248  ___tracy_emit_zone_begin(&__##IDENT##_loc, true); \
249  (void)ctx##IDENT
250 
251 #define U_TRACE_IDENT(CATEGORY, IDENT) \
252  static const struct ___tracy_source_location_data __##IDENT##_loc = { \
253  #IDENT, __func__, __FILE__, (uint32_t)__LINE__, 0, \
254  }; \
255  TracyCZoneCtx __attribute__((cleanup(u_trace_scope_cleanup))) ctx##IDENT = \
256  ___tracy_emit_zone_begin(&__##IDENT##_loc, true); \
257  (void)ctx##IDENT
258 
259 #else // !XRT_OS_WINDOWS && !__cplusplus
260 #define U_TRACE_FUNC_COLOR(CATEGORY, COLOR) \
261  do { \
262  } while (false)
263 
264 #define U_TRACE_FUNC(CATEGORY) \
265  do { \
266  } while (false)
267 
268 #define U_TRACE_IDENT_COLOR(CATEGORY, IDENT, COLOR) \
269  do { \
270  } while (false)
271 
272 #define U_TRACE_IDENT(CATEGORY, IDENT) \
273  do { \
274  } while (false)
275 
276 #endif // !XRT_OS_WINDOWS && !__cplusplus
277 
278 #define U_TRACE_BEGIN(CATEGORY, IDENT) TracyCZoneN(__trace_##IDENT, #IDENT, true)
279 #define U_TRACE_BEGIN_COLOR(CATEGORY, IDENT, COLOR) TracyCZoneNC(__trace_##IDENT, #IDENT, COLOR, true)
280 #define U_TRACE_END(CATEGORY, IDENT) TracyCZoneEnd(__trace_##IDENT)
281 
282 #define U_TRACE_EVENT_BEGIN_ON_TRACK(CATEGORY, TRACK, TIME, NAME) \
283  do { \
284  } while (false)
285 
286 #define U_TRACE_EVENT_BEGIN_ON_TRACK_DATA(CATEGORY, TRACK, TIME, NAME, ...) \
287  do { \
288  } while (false)
289 
290 #define U_TRACE_EVENT_END_ON_TRACK(CATEGORY, TRACK, TIME) \
291  do { \
292  } while (false)
293 
294 #define U_TRACE_INSTANT_ON_TRACK(CATEGORY, TRACK, TIME, NAME) \
295  do { \
296  } while (false)
297 
298 #define U_TRACE_CATEGORY_IS_ENABLED(_) (true) // All categories are always enabled with Tracy.
299 
300 #define U_TRACE_SET_THREAD_NAME(STRING) \
301  do { \
302  /* To help with thread ordering and seeing when a thread is created. */ \
303  TracyCZoneN(created, "created", true); \
304  TracyCSetThreadName(STRING); \
305  TracyCZoneEnd(created); \
306  } while (false)
307 
308 #define U_TRACE_TARGET_SETUP(WHICH)
309 
310 
311 /*
312  *
313  * Percetto support.
314  *
315  */
316 
317 #elif defined(XRT_HAVE_PERCETTO) // && XRT_FEATURE_TRACKING && !XRT_HAVE_TRACY
318 
319 #ifndef XRT_OS_LINUX
320 #error "Tracing only supported on Linux"
321 #endif
322 
323 
324 #define U_TRACE_CATEGORIES(C, G) \
325  C(vk, "vk") /* Vulkan calls */ \
326  C(xrt, "xrt") /* Misc XRT calls */ \
327  C(drv, "drv") /* Driver calls */ \
328  C(ipc, "ipc") /* IPC calls */ \
329  C(oxr, "st/oxr") /* OpenXR State Tracker calls */ \
330  C(sink, "sink") /* Sink/frameserver calls */ \
331  C(comp, "comp") /* Compositor calls */ \
332  C(sc, "sc") /* Swapchain calls */ \
333  C(track, "track") /* Tracking calls */ \
334  C(timing, "timing") /* Timing calls */
335 
336 PERCETTO_CATEGORY_DECLARE(U_TRACE_CATEGORIES)
337 
338 PERCETTO_TRACK_DECLARE(pc_cpu);
339 PERCETTO_TRACK_DECLARE(pc_allotted);
340 PERCETTO_TRACK_DECLARE(pc_gpu);
341 PERCETTO_TRACK_DECLARE(pc_margin);
342 PERCETTO_TRACK_DECLARE(pc_error);
343 PERCETTO_TRACK_DECLARE(pc_info);
344 PERCETTO_TRACK_DECLARE(pc_present);
345 PERCETTO_TRACK_DECLARE(pa_cpu);
346 PERCETTO_TRACK_DECLARE(pa_draw);
347 PERCETTO_TRACK_DECLARE(pa_wait);
348 
349 #define U_TRACE_FUNC(CATEGORY) TRACE_EVENT(CATEGORY, __func__)
350 #define U_TRACE_IDENT(CATEGORY, IDENT) TRACE_EVENT(CATEGORY, #IDENT)
351 #define U_TRACE_BEGIN(CATEGORY, IDENT) TRACE_EVENT_BEGIN(CATEGORY, #IDENT)
352 #define U_TRACE_END(CATEGORY, IDENT) TRACE_EVENT_END(CATEGORY)
353 #define U_TRACE_EVENT_BEGIN_ON_TRACK(CATEGORY, TRACK, TIME, NAME) \
354  TRACE_EVENT_BEGIN_ON_TRACK(CATEGORY, TRACK, TIME, NAME)
355 #define U_TRACE_EVENT_BEGIN_ON_TRACK_DATA(CATEGORY, TRACK, TIME, NAME, ...) \
356  TRACE_EVENT_BEGIN_ON_TRACK_DATA(CATEGORY, TRACK, TIME, NAME, __VA_ARGS__)
357 #define U_TRACE_EVENT_END_ON_TRACK(CATEGORY, TRACK, TIME) TRACE_EVENT_END_ON_TRACK(CATEGORY, TRACK, TIME)
358 #define U_TRACE_CATEGORY_IS_ENABLED(CATEGORY) PERCETTO_CATEGORY_IS_ENABLED(CATEGORY)
359 #define U_TRACE_INSTANT_ON_TRACK(CATEGORY, TRACK, TIME, NAME) \
360  TRACE_ANY_WITH_ARGS(PERCETTO_EVENT_INSTANT, CATEGORY, &g_percetto_track_##TRACK, TIME, NAME, 0)
361 #define U_TRACE_DATA(fd, type, data) u_trace_data(fd, type, (void *)&(data), sizeof(data))
362 
363 #define U_TRACE_SET_THREAD_NAME(STRING) \
364  do { \
365  (void)STRING; \
366  } while (false)
367 
368 #define U_TRACE_TARGET_SETUP(WHICH) \
369  void __attribute__((constructor(101))) u_trace_marker_constructor(void); \
370  \
371  void u_trace_marker_constructor(void) \
372  { \
373  u_trace_marker_setup(WHICH); \
374  }
375 
376 #else // !XRT_FEATURE_TRACING && !XRT_HAVE_PERCETTO && !XRT_HAVE_TRACY
377 
378 #error "Need to have Percetto/Perfetto"
379 
380 #endif // Error checking
381 
382 
383 #ifdef __cplusplus
384 }
385 #endif
386 
387 #if defined(__cplusplus) && (defined(__clang__) || defined(__GNUC__))
388 #pragma GCC diagnostic pop
389 #endif
u_trace_which
Should the extra tracks be enabled, see Tracing support.
Definition: u_trace_marker.h:69
void u_trace_marker_setup(enum u_trace_which which)
Internal setup function, use U_TRACE_TARGET_SETUP, see Tracing support.
Definition: u_trace_marker.c:106
void u_trace_marker_init(void)
Must be called from a non-static/global constructor context.
Definition: u_trace_marker.c:114
Header holding common defines.
Auto detect OS and certain features.