diff --git a/docs/u_trace.rst b/docs/u_trace.rst index e7dafc07001..f055e44397c 100644 --- a/docs/u_trace.rst +++ b/docs/u_trace.rst @@ -37,6 +37,9 @@ u_trace is controlled by environment variables: enables perfetto instrumentation prior to connecting, perfetto traces can be collected without setting this but it may miss some events prior to the tracing session being started. + ``markers`` + enables marker instrumentation, will print utrace markers into + the CS which can then be viewed by dumping the CS from the driver. :envvar:`MESA_GPU_TRACEFILE` specifies a file where to write the output instead of ``stdout`` diff --git a/src/util/perf/u_trace.c b/src/util/perf/u_trace.c index 7ddcfed894b..13af48b9a68 100644 --- a/src/util/perf/u_trace.c +++ b/src/util/perf/u_trace.c @@ -365,6 +365,7 @@ static const struct debug_named_value config_control[] = { #ifdef HAVE_PERFETTO { "perfetto", U_TRACE_TYPE_PERFETTO_ENV, "Enable perfetto" }, #endif + { "markers", U_TRACE_TYPE_MARKERS, "Enable marker trace"}, DEBUG_NAMED_VALUE_END }; diff --git a/src/util/perf/u_trace.h b/src/util/perf/u_trace.h index a8c6d2f0306..7b2e9049025 100644 --- a/src/util/perf/u_trace.h +++ b/src/util/perf/u_trace.h @@ -137,6 +137,7 @@ enum u_trace_type { U_TRACE_TYPE_JSON = 1u << 1, U_TRACE_TYPE_PERFETTO_ACTIVE = 1u << 2, U_TRACE_TYPE_PERFETTO_ENV = 1u << 3, + U_TRACE_TYPE_MARKERS = 1u << 4, U_TRACE_TYPE_PRINT_JSON = U_TRACE_TYPE_PRINT | U_TRACE_TYPE_JSON, U_TRACE_TYPE_PERFETTO = U_TRACE_TYPE_PERFETTO_ACTIVE | U_TRACE_TYPE_PERFETTO_ENV, @@ -326,6 +327,15 @@ u_trace_should_process(struct u_trace_context *utctx) { return p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_REQUIRE_PROCESSING; } +/** + * Return whether to emit markers into the command stream even if the queue + * isn't active. + */ +static ALWAYS_INLINE bool +u_trace_markers_enabled(struct u_trace_context *utctx) { + return p_atomic_read_relaxed(&utctx->enabled_traces) & U_TRACE_TYPE_MARKERS; +} + #ifdef __cplusplus } #endif diff --git a/src/util/perf/u_trace.py b/src/util/perf/u_trace.py index bbcd942cc7b..521723249da 100644 --- a/src/util/perf/u_trace.py +++ b/src/util/perf/u_trace.py @@ -34,7 +34,7 @@ class Tracepoint(object): """ def __init__(self, name, args=[], toggle_name=None, tp_struct=None, tp_print=None, tp_perfetto=None, - end_of_pipe=False): + tp_markers=None, end_of_pipe=False): """Parameters: - name: the tracepoint name, a tracepoint function with the given @@ -45,6 +45,9 @@ class Tracepoint(object): - tp_print: (optional) array of format string followed by expressions - tp_perfetto: (optional) driver provided callback which can generate perfetto events + - tp_markers: (optional) driver provided printf-style callback which can + generate CS markers, this requires 'need_cs_param' as the first param + is the CS that the label should be emitted into """ assert isinstance(name, str) assert isinstance(args, list) @@ -57,6 +60,7 @@ class Tracepoint(object): self.tp_struct = tp_struct self.tp_print = tp_print self.tp_perfetto = tp_perfetto + self.tp_markers = tp_markers self.end_of_pipe = end_of_pipe self.toggle_name = toggle_name @@ -405,6 +409,27 @@ static void __print_json_${trace_name}(FILE *out, const void *arg) { #define __print_${trace_name} NULL #define __print_json_${trace_name} NULL % endif + % if trace.tp_markers is not None: + +__attribute__((format(printf, 2, 3))) void ${trace.tp_markers}(void *, const char *, ...); + +static void __emit_label_${trace_name}(void *cs, struct trace_${trace_name} *entry) { + ${trace.tp_markers}(cs, "${trace_name}(" + % for idx,arg in enumerate(trace.tp_struct): + "${"," if idx != 0 else ""}${arg.name}=${arg.c_format}" + % endfor + ")" + % for arg in trace.tp_struct: + % if arg.to_prim_type: + ,${arg.to_prim_type.format('entry->' + arg.name)} + % else: + ,entry->${arg.name} + % endif + % endfor + ); +} + + % endif static const struct u_tracepoint __tp_${trace_name} = { ALIGN_POT(sizeof(struct trace_${trace_name}), 8), /* keep size 64b aligned */ "${trace_name}", @@ -435,6 +460,10 @@ void __trace_${trace_name}( % for arg in trace.tp_struct: __entry->${arg.name} = ${arg.var}; % endfor + % if trace.tp_markers is not None: + if (enabled_traces & U_TRACE_TYPE_MARKERS) + __emit_label_${trace_name}(cs, __entry); + % endif } % endfor