From 698343edc57619de5bb85ce1f208633b96e2fea8 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 22 Nov 2021 12:56:20 +0200 Subject: [PATCH] util/u_trace/perfetto: add new env variable to enable perfetto When using the Vulkan API, command buffers can be recorded way before perfetto is enabled. This can be problematic if you want already recorded command buffers to produce traces. This new environment variable makes perfetto enabled internally so that command buffers are recorded with timestamps, even though no perfetto recording happens. v2: rename to GPU_TRACE_INSTRUMENT (Rob) v3: Move instrumentation check to generated headers (Danylo) Decouple instrumentation enabling from tracing (Danylo) Signed-off-by: Lionel Landwerlin Reviewed-by: Danylo Piliaiev Part-of: --- docs/perfetto.rst | 16 ++++++++++++++++ src/freedreno/vulkan/tu_drm.c | 2 +- src/util/perf/u_trace.c | 9 +++++++-- src/util/perf/u_trace.h | 14 +++++++++++++- src/util/perf/u_trace.py | 4 ++-- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/docs/perfetto.rst b/docs/perfetto.rst index dd78db564b4..17379e6f770 100644 --- a/docs/perfetto.rst +++ b/docs/perfetto.rst @@ -104,6 +104,22 @@ the steps above : # Back in the perfetto tmux, press enter to start the capture +Vulkan data sources +~~~~~~~~~~~~~~~~~~~ + +The Vulkan API gives the application control over recording of command +buffers as well as when they are submitted to the hardware. As a +consequence, we need to ensure command buffers are properly +instrumented for the perfetto driver data sources prior to Perfetto +actually collecting traces. + +This can be achieved by setting the ``GPU_TRACE_INSTRUMENT`` +environment variable before starting a Vulkan application : + +.. code-block:: console + + GPU_TRACE_INSTRUMENT=1 ./build/my_vulkan_app + Driver Specifics ~~~~~~~~~~~~~~~~ diff --git a/src/freedreno/vulkan/tu_drm.c b/src/freedreno/vulkan/tu_drm.c index ae8c037beb9..591115e738e 100644 --- a/src/freedreno/vulkan/tu_drm.c +++ b/src/freedreno/vulkan/tu_drm.c @@ -950,7 +950,7 @@ tu_queue_submit_create_locked(struct tu_queue *queue, } } - bool u_trace_enabled = u_trace_context_tracing(&queue->device->trace_context); + bool u_trace_enabled = u_trace_context_actively_tracing(&queue->device->trace_context); bool has_trace_points = false; uint32_t entry_count = 0; diff --git a/src/util/perf/u_trace.c b/src/util/perf/u_trace.c index 1252897688b..aae22856c20 100644 --- a/src/util/perf/u_trace.c +++ b/src/util/perf/u_trace.c @@ -38,6 +38,8 @@ #define TIMESTAMP_BUF_SIZE 0x1000 #define TRACES_PER_CHUNK (TIMESTAMP_BUF_SIZE / sizeof(uint64_t)) +bool ut_trace_instrument; + #ifdef HAVE_PERFETTO int ut_perfetto_enabled; @@ -217,6 +219,7 @@ get_chunk(struct u_trace *ut, size_t payload_size) return chunk; } +DEBUG_GET_ONCE_BOOL_OPTION(trace_instrument, "GPU_TRACE_INSTRUMENT", false) DEBUG_GET_ONCE_BOOL_OPTION(trace, "GPU_TRACE", false) DEBUG_GET_ONCE_FILE_OPTION(trace_file, "GPU_TRACEFILE", NULL, "w") @@ -232,6 +235,8 @@ get_tracefile(void) tracefile = stdout; } + ut_trace_instrument = debug_get_option_trace_instrument(); + firsttime = false; } @@ -281,7 +286,7 @@ u_trace_context_init(struct u_trace_context *utctx, list_add(&utctx->node, &ctx_list); #endif - if (!u_trace_context_tracing(utctx)) + if (!u_trace_context_actively_tracing(utctx)) return; queue_init(utctx); @@ -425,7 +430,7 @@ u_trace_init(struct u_trace *ut, struct u_trace_context *utctx) { ut->utctx = utctx; list_inithead(&ut->trace_chunks); - ut->enabled = u_trace_context_tracing(utctx); + ut->enabled = u_trace_context_instrumenting(utctx); } void diff --git a/src/util/perf/u_trace.h b/src/util/perf/u_trace.h index 7e3f7aaa2e2..8f21c4941dc 100644 --- a/src/util/perf/u_trace.h +++ b/src/util/perf/u_trace.h @@ -267,6 +267,12 @@ void u_trace_disable_event_range(struct u_trace_iterator begin_it, */ void u_trace_flush(struct u_trace *ut, void *flush_data, bool free_data); +/** + * Whether command buffers should be instrumented even if not collecting + * traces. + */ +extern bool ut_trace_instrument; + #ifdef HAVE_PERFETTO extern int ut_perfetto_enabled; @@ -277,11 +283,17 @@ void u_trace_perfetto_stop(void); #endif static inline bool -u_trace_context_tracing(struct u_trace_context *utctx) +u_trace_context_actively_tracing(struct u_trace_context *utctx) { return !!utctx->out || (ut_perfetto_enabled > 0); } +static inline bool +u_trace_context_instrumenting(struct u_trace_context *utctx) +{ + return !!utctx->out || ut_trace_instrument || (ut_perfetto_enabled > 0); +} + #ifdef __cplusplus } #endif diff --git a/src/util/perf/u_trace.py b/src/util/perf/u_trace.py index f80b253d899..374ec790c52 100644 --- a/src/util/perf/u_trace.py +++ b/src/util/perf/u_trace.py @@ -212,9 +212,9 @@ static inline void trace_${trace_name}(struct u_trace *ut, void *cs % endfor ) { % if trace.tp_perfetto is not None: - if (!unlikely(ut->enabled || ut_perfetto_enabled)) + if (!unlikely(ut->enabled || ut_trace_instrument || ut_perfetto_enabled)) % else: - if (!unlikely(ut->enabled)) + if (!unlikely(ut->enabled || ut_trace_instrument)) % endif return; __trace_${trace_name}(ut, cs