diff options
Diffstat (limited to 'src/util/perf/u_trace.h')
-rw-r--r-- | src/util/perf/u_trace.h | 186 |
1 files changed, 128 insertions, 58 deletions
diff --git a/src/util/perf/u_trace.h b/src/util/perf/u_trace.h index c184a14e94d..b61b7cfb800 100644 --- a/src/util/perf/u_trace.h +++ b/src/util/perf/u_trace.h @@ -16,9 +16,9 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef _U_TRACE_H @@ -28,9 +28,11 @@ #include <stdint.h> #include <stdio.h> +#include "util/macros.h" +#include "util/u_atomic.h" #include "util/u_queue.h" -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -69,25 +71,26 @@ extern "C" { struct u_trace_context; struct u_trace; struct u_trace_chunk; +struct u_trace_printer; /** * Special reserved value to indicate that no timestamp was captured, * and that the timestamp of the previous trace should be reused. */ -#define U_TRACE_NO_TIMESTAMP ((uint64_t)0) +#define U_TRACE_NO_TIMESTAMP ((uint64_t) 0) /** * Driver provided callback to create a timestamp buffer which will be * read by u_trace_read_ts function. */ -typedef void* (*u_trace_create_ts_buffer)(struct u_trace_context *utctx, - uint32_t timestamps_count); +typedef void *(*u_trace_create_ts_buffer)(struct u_trace_context *utctx, + uint32_t timestamps_count); /** * Driver provided callback to delete a timestamp buffer. */ typedef void (*u_trace_delete_ts_buffer)(struct u_trace_context *utctx, - void *timestamps); + void *timestamps); /** * Driver provided callback to emit commands into the soecified command @@ -98,8 +101,11 @@ typedef void (*u_trace_delete_ts_buffer)(struct u_trace_context *utctx, * a fixed rate, even as the GPU freq changes. The same source used for * GL_TIMESTAMP queries should be appropriate. */ -typedef void (*u_trace_record_ts)(struct u_trace *ut, void *cs, - void *timestamps, unsigned idx); +typedef void (*u_trace_record_ts)(struct u_trace *ut, + void *cs, + void *timestamps, + unsigned idx, + bool end_of_pipe); /** * Driver provided callback to read back a previously recorded timestamp. @@ -120,28 +126,56 @@ typedef void (*u_trace_record_ts)(struct u_trace *ut, void *cs, * capturing the same timestamp multiple times in a row. */ typedef uint64_t (*u_trace_read_ts)(struct u_trace_context *utctx, - void *timestamps, unsigned idx, void *flush_data); + void *timestamps, + unsigned idx, + void *flush_data); /** * Driver provided callback to delete flush data. */ typedef void (*u_trace_delete_flush_data)(struct u_trace_context *utctx, - void *flush_data); + void *flush_data); + +enum u_trace_type { + U_TRACE_TYPE_PRINT = 1u << 0, + 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, + + /* + * A mask of traces that require appending to the tracepoint chunk list. + */ + U_TRACE_TYPE_REQUIRE_QUEUING = U_TRACE_TYPE_PRINT | U_TRACE_TYPE_PERFETTO, + /* + * A mask of traces that require processing the tracepoint chunk list. + */ + U_TRACE_TYPE_REQUIRE_PROCESSING = + U_TRACE_TYPE_PRINT | U_TRACE_TYPE_PERFETTO_ACTIVE, +}; /** * The trace context provides tracking for "in-flight" traces, once the * cmdstream that records timestamps has been flushed. */ struct u_trace_context { + /* All traces enabled in this context */ + enum u_trace_type enabled_traces; + void *pctx; - u_trace_create_ts_buffer create_timestamp_buffer; - u_trace_delete_ts_buffer delete_timestamp_buffer; - u_trace_record_ts record_timestamp; - u_trace_read_ts read_timestamp; + u_trace_create_ts_buffer create_timestamp_buffer; + u_trace_delete_ts_buffer delete_timestamp_buffer; + u_trace_record_ts record_timestamp; + u_trace_read_ts read_timestamp; u_trace_delete_flush_data delete_flush_data; FILE *out; + struct u_trace_printer *out_printer; /* Once u_trace_flush() is called u_trace_chunk's are queued up to * render tracepoints on a queue. The per-chunk queue jobs block until @@ -161,6 +195,9 @@ struct u_trace_context { uint64_t first_time_ns; uint32_t frame_nr; + uint32_t batch_nr; + uint32_t event_nr; + bool start_of_frame; /* list of unprocessed trace chunks in fifo order: */ struct list_head flushed_trace_chunks; @@ -180,23 +217,24 @@ struct u_trace_context { struct u_trace { struct u_trace_context *utctx; - struct list_head trace_chunks; /* list of unflushed trace chunks in fifo order */ + uint32_t num_traces; - bool enabled; + struct list_head + trace_chunks; /* list of unflushed trace chunks in fifo order */ }; void u_trace_context_init(struct u_trace_context *utctx, - void *pctx, - u_trace_create_ts_buffer create_timestamp_buffer, - u_trace_delete_ts_buffer delete_timestamp_buffer, - u_trace_record_ts record_timestamp, - u_trace_read_ts read_timestamp, - u_trace_delete_flush_data delete_flush_data); + void *pctx, + u_trace_create_ts_buffer create_timestamp_buffer, + u_trace_delete_ts_buffer delete_timestamp_buffer, + u_trace_record_ts record_timestamp, + u_trace_read_ts read_timestamp, + u_trace_delete_flush_data delete_flush_data); void u_trace_context_fini(struct u_trace_context *utctx); /** - * Flush (trigger processing) of traces previously flushed to the trace-context - * by u_trace_flush(). + * Flush (trigger processing) of traces previously flushed to the + * trace-context by u_trace_flush(). * * This should typically be called in the driver's pctx->flush(). */ @@ -205,39 +243,37 @@ void u_trace_context_process(struct u_trace_context *utctx, bool eof); void u_trace_init(struct u_trace *ut, struct u_trace_context *utctx); void u_trace_fini(struct u_trace *ut); +void u_trace_state_init(void); +bool u_trace_is_enabled(enum u_trace_type type); + bool u_trace_has_points(struct u_trace *ut); -struct u_trace_iterator -{ +struct u_trace_iterator { struct u_trace *ut; struct u_trace_chunk *chunk; uint32_t event_idx; }; -struct u_trace_iterator -u_trace_begin_iterator(struct u_trace *ut); +struct u_trace_iterator u_trace_begin_iterator(struct u_trace *ut); -struct u_trace_iterator -u_trace_end_iterator(struct u_trace *ut); +struct u_trace_iterator u_trace_end_iterator(struct u_trace *ut); -bool -u_trace_iterator_equal(struct u_trace_iterator a, - struct u_trace_iterator b); +bool u_trace_iterator_equal(struct u_trace_iterator a, + struct u_trace_iterator b); typedef void (*u_trace_copy_ts_buffer)(struct u_trace_context *utctx, - void *cmdstream, - void *ts_from, uint32_t from_offset, - void *ts_to, uint32_t to_offset, - uint32_t count); + void *cmdstream, + void *ts_from, + uint32_t from_offset, + void *ts_to, + uint32_t to_offset, + uint32_t count); /** * Clones tracepoints range into target u_trace. * Provides callback for driver to copy timestamps on GPU from * one buffer to another. * - * The payload is shared and remains owned by the original u_trace - * if tracepoints are being copied between different u_trace! - * * It allows: * - Tracing re-usable command buffer in Vulkan, by copying tracepoints * each time it is submitted. @@ -255,37 +291,71 @@ void u_trace_disable_event_range(struct u_trace_iterator begin_it, /** * Flush traces to the parent trace-context. At this point, the expectation - * is that all the tracepoints are "executed" by the GPU following any previously - * flushed u_trace batch. + * is that all the tracepoints are "executed" by the GPU following any + * previously flushed u_trace batch. * - * flush_data is a way for driver to pass additional data, which becomes available - * only at the point of flush, to the u_trace_read_ts callback and perfetto. - * The typical example of such data would be a fence to wait on in u_trace_read_ts, - * and a submission_id to pass into perfetto. - * The destruction of the data is done via u_trace_delete_flush_data. + * flush_data is a way for driver to pass additional data, which becomes + * available only at the point of flush, to the u_trace_read_ts callback and + * perfetto. The typical example of such data would be a fence to wait on in + * u_trace_read_ts, and a submission_id to pass into perfetto. The destruction + * of the data is done via u_trace_delete_flush_data. * - * This should typically be called when the corresponding cmdstream (containing - * the timestamp reads) is flushed to the kernel. + * This should typically be called when the corresponding cmdstream + * (containing the timestamp reads) is flushed to the kernel. */ void u_trace_flush(struct u_trace *ut, void *flush_data, bool free_data); #ifdef HAVE_PERFETTO -extern int ut_perfetto_enabled; +static ALWAYS_INLINE bool +u_trace_perfetto_active(struct u_trace_context *utctx) +{ + return p_atomic_read_relaxed(&utctx->enabled_traces) & + U_TRACE_TYPE_PERFETTO_ACTIVE; +} void u_trace_perfetto_start(void); void u_trace_perfetto_stop(void); #else -# define ut_perfetto_enabled 0 +static ALWAYS_INLINE bool +u_trace_perfetto_active(UNUSED struct u_trace_context *utctx) +{ + return false; +} #endif -static inline bool -u_trace_context_tracing(struct u_trace_context *utctx) +/** + * Return whether utrace is enabled at all or not, this can be used to + * gate any expensive traces. + */ +static ALWAYS_INLINE bool +u_trace_enabled(struct u_trace_context *utctx) +{ + return p_atomic_read_relaxed(&utctx->enabled_traces) != 0; +} + +/** + * Return whether chunks should be processed or not. + */ +static ALWAYS_INLINE bool +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 !!utctx->out || (ut_perfetto_enabled > 0); + return p_atomic_read_relaxed(&utctx->enabled_traces) & + U_TRACE_TYPE_MARKERS; } -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* _U_TRACE_H */ +#endif /* _U_TRACE_H */ |