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