• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Advanced Micro Devices, Inc.
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "si_utrace.h"
8 #include "si_perfetto.h"
9 #include "amd/common/ac_gpu_info.h"
10 
11 #include "util/u_trace_gallium.h"
12 #include "util/hash_table.h"
13 
14 
si_utrace_record_ts(struct u_trace * trace,void * cs,void * timestamps,unsigned idx,bool end_of_pipe)15 static void si_utrace_record_ts(struct u_trace *trace, void *cs, void *timestamps,
16                                 unsigned idx, bool end_of_pipe)
17 {
18    struct si_context *ctx = container_of(trace, struct si_context, trace);
19    struct pipe_resource *buffer = timestamps;
20    struct si_resource *ts_bo = si_resource(buffer);
21 
22    if (ctx->gfx_cs.current.buf == ctx->last_timestamp_cmd &&
23        ctx->gfx_cs.current.cdw == ctx->last_timestamp_cmd_cdw) {
24       uint64_t *ts = si_buffer_map(ctx, ts_bo, PIPE_MAP_READ);
25       ts[idx] = U_TRACE_NO_TIMESTAMP;
26       return;
27    }
28 
29    unsigned ts_offset = idx * sizeof(uint64_t);
30 
31    si_emit_ts(ctx, ts_bo, ts_offset);
32    ctx->last_timestamp_cmd = ctx->gfx_cs.current.buf;
33    ctx->last_timestamp_cmd_cdw = ctx->gfx_cs.current.cdw;
34 }
35 
si_utrace_read_ts(struct u_trace_context * utctx,void * timestamps,unsigned idx,void * flush_data)36 static uint64_t si_utrace_read_ts(struct u_trace_context *utctx, void *timestamps,
37                                   unsigned idx, void *flush_data)
38 {
39    struct si_context *ctx = container_of(utctx, struct si_context, ds.trace_context);
40    struct pipe_resource *buffer = timestamps;
41 
42    uint64_t *ts = si_buffer_map(ctx, si_resource(buffer), PIPE_MAP_READ);
43 
44    /* Don't translate the no-timestamp marker: */
45    if (ts[idx] == U_TRACE_NO_TIMESTAMP)
46       return U_TRACE_NO_TIMESTAMP;
47 
48    return (1000000 * ts[idx]) / ctx->screen->info.clock_crystal_freq;
49 }
50 
si_utrace_delete_flush_data(struct u_trace_context * utctx,void * flush_data)51 static void si_utrace_delete_flush_data(struct u_trace_context *utctx, void *flush_data)
52 {
53    free(flush_data);
54 }
55 
si_utrace_init(struct si_context * sctx)56 void si_utrace_init(struct si_context *sctx)
57 {
58    char buf[64];
59    snprintf(buf, sizeof(buf), "%u:%u:%u:%u:%u", sctx->screen->info.pci.domain,
60             sctx->screen->info.pci.bus, sctx->screen->info.pci.dev,
61             sctx->screen->info.pci.func, sctx->screen->info.pci_id);
62    uint32_t gpu_id = _mesa_hash_string(buf);
63 
64    si_ds_device_init(&sctx->ds, &sctx->screen->info, gpu_id, AMD_DS_API_OPENGL);
65    u_trace_pipe_context_init(&sctx->ds.trace_context, &sctx->b, si_utrace_record_ts,
66                              si_utrace_read_ts, si_utrace_delete_flush_data);
67 
68    si_ds_device_init_queue(&sctx->ds, &sctx->ds_queue, "%s", "render");
69 }
70 
si_utrace_fini(struct si_context * sctx)71 void si_utrace_fini(struct si_context *sctx)
72 {
73    si_ds_device_fini(&sctx->ds);
74 }
75 
si_utrace_flush(struct si_context * sctx,uint64_t submission_id)76 void si_utrace_flush(struct si_context *sctx, uint64_t submission_id)
77 {
78    struct si_ds_flush_data *flush_data = malloc(sizeof(*flush_data));
79    si_ds_flush_data_init(flush_data, &sctx->ds_queue, submission_id);
80    u_trace_flush(&sctx->trace, flush_data, false);
81 }
82