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