1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2021 Google, Inc.
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #include <perfetto.h>
7*61046927SAndroid Build Coastguard Worker
8*61046927SAndroid Build Coastguard Worker #include "tu_perfetto.h"
9*61046927SAndroid Build Coastguard Worker #include "tu_buffer.h"
10*61046927SAndroid Build Coastguard Worker #include "tu_device.h"
11*61046927SAndroid Build Coastguard Worker #include "tu_image.h"
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
14*61046927SAndroid Build Coastguard Worker #include "util/perf/u_perfetto.h"
15*61046927SAndroid Build Coastguard Worker #include "util/perf/u_perfetto_renderpass.h"
16*61046927SAndroid Build Coastguard Worker
17*61046927SAndroid Build Coastguard Worker #include "tu_tracepoints.h"
18*61046927SAndroid Build Coastguard Worker #include "tu_tracepoints_perfetto.h"
19*61046927SAndroid Build Coastguard Worker
20*61046927SAndroid Build Coastguard Worker /* we can't include tu_knl.h and tu_device.h */
21*61046927SAndroid Build Coastguard Worker
22*61046927SAndroid Build Coastguard Worker int
23*61046927SAndroid Build Coastguard Worker tu_device_get_gpu_timestamp(struct tu_device *dev,
24*61046927SAndroid Build Coastguard Worker uint64_t *ts);
25*61046927SAndroid Build Coastguard Worker int
26*61046927SAndroid Build Coastguard Worker tu_device_get_suspend_count(struct tu_device *dev,
27*61046927SAndroid Build Coastguard Worker uint64_t *suspend_count);
28*61046927SAndroid Build Coastguard Worker uint64_t
29*61046927SAndroid Build Coastguard Worker tu_device_ticks_to_ns(struct tu_device *dev, uint64_t ts);
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker struct u_trace_context *
32*61046927SAndroid Build Coastguard Worker tu_device_get_u_trace(struct tu_device *device);
33*61046927SAndroid Build Coastguard Worker
34*61046927SAndroid Build Coastguard Worker /**
35*61046927SAndroid Build Coastguard Worker * Queue-id's
36*61046927SAndroid Build Coastguard Worker */
37*61046927SAndroid Build Coastguard Worker enum {
38*61046927SAndroid Build Coastguard Worker DEFAULT_HW_QUEUE_ID,
39*61046927SAndroid Build Coastguard Worker };
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker /**
42*61046927SAndroid Build Coastguard Worker * Render-stage id's
43*61046927SAndroid Build Coastguard Worker */
44*61046927SAndroid Build Coastguard Worker enum tu_stage_id {
45*61046927SAndroid Build Coastguard Worker CMD_BUFFER_STAGE_ID,
46*61046927SAndroid Build Coastguard Worker CMD_BUFFER_ANNOTATION_STAGE_ID,
47*61046927SAndroid Build Coastguard Worker RENDER_PASS_STAGE_ID,
48*61046927SAndroid Build Coastguard Worker CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID,
49*61046927SAndroid Build Coastguard Worker BINNING_STAGE_ID,
50*61046927SAndroid Build Coastguard Worker GMEM_STAGE_ID,
51*61046927SAndroid Build Coastguard Worker BYPASS_STAGE_ID,
52*61046927SAndroid Build Coastguard Worker BLIT_STAGE_ID,
53*61046927SAndroid Build Coastguard Worker COMPUTE_STAGE_ID,
54*61046927SAndroid Build Coastguard Worker CLEAR_SYSMEM_STAGE_ID,
55*61046927SAndroid Build Coastguard Worker CLEAR_GMEM_STAGE_ID,
56*61046927SAndroid Build Coastguard Worker GENERIC_CLEAR_STAGE_ID,
57*61046927SAndroid Build Coastguard Worker GMEM_LOAD_STAGE_ID,
58*61046927SAndroid Build Coastguard Worker GMEM_STORE_STAGE_ID,
59*61046927SAndroid Build Coastguard Worker SYSMEM_RESOLVE_STAGE_ID,
60*61046927SAndroid Build Coastguard Worker // TODO add the rest from fd_stage_id
61*61046927SAndroid Build Coastguard Worker };
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker static const struct {
64*61046927SAndroid Build Coastguard Worker const char *name;
65*61046927SAndroid Build Coastguard Worker const char *desc;
66*61046927SAndroid Build Coastguard Worker } queues[] = {
67*61046927SAndroid Build Coastguard Worker [DEFAULT_HW_QUEUE_ID] = {"GPU Queue 0", "Default Adreno Hardware Queue"},
68*61046927SAndroid Build Coastguard Worker };
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker static const struct {
71*61046927SAndroid Build Coastguard Worker const char *name;
72*61046927SAndroid Build Coastguard Worker const char *desc;
73*61046927SAndroid Build Coastguard Worker } stages[] = {
74*61046927SAndroid Build Coastguard Worker [CMD_BUFFER_STAGE_ID] = { "Command Buffer" },
75*61046927SAndroid Build Coastguard Worker [CMD_BUFFER_ANNOTATION_STAGE_ID] = { "Annotation", "Command Buffer Annotation" },
76*61046927SAndroid Build Coastguard Worker [RENDER_PASS_STAGE_ID] = { "Render Pass" },
77*61046927SAndroid Build Coastguard Worker [CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID] = { "Annotation", "Render Pass Command Buffer Annotation" },
78*61046927SAndroid Build Coastguard Worker [BINNING_STAGE_ID] = { "Binning", "Perform Visibility pass and determine target bins" },
79*61046927SAndroid Build Coastguard Worker [GMEM_STAGE_ID] = { "GMEM", "Rendering to GMEM" },
80*61046927SAndroid Build Coastguard Worker [BYPASS_STAGE_ID] = { "Bypass", "Rendering to system memory" },
81*61046927SAndroid Build Coastguard Worker [BLIT_STAGE_ID] = { "Blit", "Performing a Blit operation" },
82*61046927SAndroid Build Coastguard Worker [COMPUTE_STAGE_ID] = { "Compute", "Compute job" },
83*61046927SAndroid Build Coastguard Worker [CLEAR_SYSMEM_STAGE_ID] = { "Clear Sysmem", "" },
84*61046927SAndroid Build Coastguard Worker [CLEAR_GMEM_STAGE_ID] = { "Clear GMEM", "Per-tile (GMEM) clear" },
85*61046927SAndroid Build Coastguard Worker [GENERIC_CLEAR_STAGE_ID] = { "Clear Sysmem/Gmem", ""},
86*61046927SAndroid Build Coastguard Worker [GMEM_LOAD_STAGE_ID] = { "GMEM Load", "Per tile system memory to GMEM load" },
87*61046927SAndroid Build Coastguard Worker [GMEM_STORE_STAGE_ID] = { "GMEM Store", "Per tile GMEM to system memory store" },
88*61046927SAndroid Build Coastguard Worker [SYSMEM_RESOLVE_STAGE_ID] = { "SysMem Resolve", "System memory MSAA resolve" },
89*61046927SAndroid Build Coastguard Worker // TODO add the rest
90*61046927SAndroid Build Coastguard Worker };
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker static uint32_t gpu_clock_id;
93*61046927SAndroid Build Coastguard Worker static uint64_t next_clock_sync_ns; /* cpu time of next clk sync */
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker /**
96*61046927SAndroid Build Coastguard Worker * The timestamp at the point where we first emitted the clock_sync..
97*61046927SAndroid Build Coastguard Worker * this will be a *later* timestamp that the first GPU traces (since
98*61046927SAndroid Build Coastguard Worker * we capture the first clock_sync from the CPU *after* the first GPU
99*61046927SAndroid Build Coastguard Worker * tracepoints happen). To avoid confusing perfetto we need to drop
100*61046927SAndroid Build Coastguard Worker * the GPU traces with timestamps before this.
101*61046927SAndroid Build Coastguard Worker */
102*61046927SAndroid Build Coastguard Worker static uint64_t sync_gpu_ts;
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker static uint64_t last_suspend_count;
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker static uint64_t gpu_max_timestamp;
107*61046927SAndroid Build Coastguard Worker static uint64_t gpu_timestamp_offset;
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker struct TuRenderpassIncrementalState {
110*61046927SAndroid Build Coastguard Worker bool was_cleared = true;
111*61046927SAndroid Build Coastguard Worker };
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker struct TuRenderpassTraits : public perfetto::DefaultDataSourceTraits {
114*61046927SAndroid Build Coastguard Worker using IncrementalStateType = TuRenderpassIncrementalState;
115*61046927SAndroid Build Coastguard Worker };
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker class TuRenderpassDataSource : public MesaRenderpassDataSource<TuRenderpassDataSource,
118*61046927SAndroid Build Coastguard Worker TuRenderpassTraits> {
OnStart(const StartArgs & args)119*61046927SAndroid Build Coastguard Worker void OnStart(const StartArgs &args) override
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker MesaRenderpassDataSource<TuRenderpassDataSource, TuRenderpassTraits>::OnStart(args);
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker /* Note: clock_id's below 128 are reserved.. for custom clock sources,
124*61046927SAndroid Build Coastguard Worker * using the hash of a namespaced string is the recommended approach.
125*61046927SAndroid Build Coastguard Worker * See: https://perfetto.dev/docs/concepts/clock-sync
126*61046927SAndroid Build Coastguard Worker */
127*61046927SAndroid Build Coastguard Worker gpu_clock_id =
128*61046927SAndroid Build Coastguard Worker _mesa_hash_string("org.freedesktop.mesa.freedreno") | 0x80000000;
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker gpu_timestamp_offset = 0;
131*61046927SAndroid Build Coastguard Worker gpu_max_timestamp = 0;
132*61046927SAndroid Build Coastguard Worker last_suspend_count = 0;
133*61046927SAndroid Build Coastguard Worker }
134*61046927SAndroid Build Coastguard Worker };
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(TuRenderpassDataSource);
137*61046927SAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(TuRenderpassDataSource);
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker static void
send_descriptors(TuRenderpassDataSource::TraceContext & ctx)140*61046927SAndroid Build Coastguard Worker send_descriptors(TuRenderpassDataSource::TraceContext &ctx)
141*61046927SAndroid Build Coastguard Worker {
142*61046927SAndroid Build Coastguard Worker PERFETTO_LOG("Sending renderstage descriptors");
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker /* This must be set before interned data is sent. */
147*61046927SAndroid Build Coastguard Worker packet->set_sequence_flags(perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker packet->set_timestamp(0);
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker auto event = packet->set_gpu_render_stage_event();
152*61046927SAndroid Build Coastguard Worker event->set_gpu_id(0);
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker auto spec = event->set_specifications();
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(queues); i++) {
157*61046927SAndroid Build Coastguard Worker auto desc = spec->add_hw_queue();
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker desc->set_name(queues[i].name);
160*61046927SAndroid Build Coastguard Worker desc->set_description(queues[i].desc);
161*61046927SAndroid Build Coastguard Worker }
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(stages); i++) {
164*61046927SAndroid Build Coastguard Worker auto desc = spec->add_stage();
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker desc->set_name(stages[i].name);
167*61046927SAndroid Build Coastguard Worker if (stages[i].desc)
168*61046927SAndroid Build Coastguard Worker desc->set_description(stages[i].desc);
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker }
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker static struct tu_perfetto_stage *
stage_push(struct tu_device * dev)173*61046927SAndroid Build Coastguard Worker stage_push(struct tu_device *dev)
174*61046927SAndroid Build Coastguard Worker {
175*61046927SAndroid Build Coastguard Worker struct tu_perfetto_state *p = &dev->perfetto;
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Worker if (p->stage_depth >= ARRAY_SIZE(p->stages)) {
178*61046927SAndroid Build Coastguard Worker p->skipped_depth++;
179*61046927SAndroid Build Coastguard Worker return NULL;
180*61046927SAndroid Build Coastguard Worker }
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker return &p->stages[p->stage_depth++];
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker
185*61046927SAndroid Build Coastguard Worker typedef void (*trace_payload_as_extra_func)(perfetto::protos::pbzero::GpuRenderStageEvent *, const void*);
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker static struct tu_perfetto_stage *
stage_pop(struct tu_device * dev)188*61046927SAndroid Build Coastguard Worker stage_pop(struct tu_device *dev)
189*61046927SAndroid Build Coastguard Worker {
190*61046927SAndroid Build Coastguard Worker struct tu_perfetto_state *p = &dev->perfetto;
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker if (!p->stage_depth)
193*61046927SAndroid Build Coastguard Worker return NULL;
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker if (p->skipped_depth) {
196*61046927SAndroid Build Coastguard Worker p->skipped_depth--;
197*61046927SAndroid Build Coastguard Worker return NULL;
198*61046927SAndroid Build Coastguard Worker }
199*61046927SAndroid Build Coastguard Worker
200*61046927SAndroid Build Coastguard Worker return &p->stages[--p->stage_depth];
201*61046927SAndroid Build Coastguard Worker }
202*61046927SAndroid Build Coastguard Worker
203*61046927SAndroid Build Coastguard Worker static void
stage_start(struct tu_device * dev,uint64_t ts_ns,enum tu_stage_id stage_id,const char * app_event,const void * payload=nullptr,size_t payload_size=0,trace_payload_as_extra_func payload_as_extra=nullptr)204*61046927SAndroid Build Coastguard Worker stage_start(struct tu_device *dev,
205*61046927SAndroid Build Coastguard Worker uint64_t ts_ns,
206*61046927SAndroid Build Coastguard Worker enum tu_stage_id stage_id,
207*61046927SAndroid Build Coastguard Worker const char *app_event,
208*61046927SAndroid Build Coastguard Worker const void *payload = nullptr,
209*61046927SAndroid Build Coastguard Worker size_t payload_size = 0,
210*61046927SAndroid Build Coastguard Worker trace_payload_as_extra_func payload_as_extra = nullptr)
211*61046927SAndroid Build Coastguard Worker {
212*61046927SAndroid Build Coastguard Worker struct tu_perfetto_stage *stage = stage_push(dev);
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker if (!stage) {
215*61046927SAndroid Build Coastguard Worker PERFETTO_ELOG("stage %d is nested too deep", stage_id);
216*61046927SAndroid Build Coastguard Worker return;
217*61046927SAndroid Build Coastguard Worker }
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker if (payload) {
220*61046927SAndroid Build Coastguard Worker void* new_payload = malloc(payload_size);
221*61046927SAndroid Build Coastguard Worker if (new_payload)
222*61046927SAndroid Build Coastguard Worker memcpy(new_payload, payload, payload_size);
223*61046927SAndroid Build Coastguard Worker else
224*61046927SAndroid Build Coastguard Worker PERFETTO_ELOG("Failed to allocate payload for stage %d", stage_id);
225*61046927SAndroid Build Coastguard Worker payload = new_payload;
226*61046927SAndroid Build Coastguard Worker }
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker *stage = (struct tu_perfetto_stage) {
229*61046927SAndroid Build Coastguard Worker .stage_id = stage_id,
230*61046927SAndroid Build Coastguard Worker .stage_iid = 0,
231*61046927SAndroid Build Coastguard Worker .start_ts = ts_ns,
232*61046927SAndroid Build Coastguard Worker .payload = payload,
233*61046927SAndroid Build Coastguard Worker .start_payload_function = (void *) payload_as_extra,
234*61046927SAndroid Build Coastguard Worker };
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker if (app_event) {
237*61046927SAndroid Build Coastguard Worker TuRenderpassDataSource::Trace([=](auto tctx) {
238*61046927SAndroid Build Coastguard Worker stage->stage_iid =
239*61046927SAndroid Build Coastguard Worker tctx.GetDataSourceLocked()->debug_marker_stage(tctx, app_event);
240*61046927SAndroid Build Coastguard Worker });
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker }
243*61046927SAndroid Build Coastguard Worker
244*61046927SAndroid Build Coastguard Worker static void
stage_end(struct tu_device * dev,uint64_t ts_ns,enum tu_stage_id stage_id,const void * flush_data,const void * payload=nullptr,trace_payload_as_extra_func payload_as_extra=nullptr)245*61046927SAndroid Build Coastguard Worker stage_end(struct tu_device *dev, uint64_t ts_ns, enum tu_stage_id stage_id,
246*61046927SAndroid Build Coastguard Worker const void *flush_data,
247*61046927SAndroid Build Coastguard Worker const void* payload = nullptr,
248*61046927SAndroid Build Coastguard Worker trace_payload_as_extra_func payload_as_extra = nullptr)
249*61046927SAndroid Build Coastguard Worker {
250*61046927SAndroid Build Coastguard Worker struct tu_perfetto_stage *stage = stage_pop(dev);
251*61046927SAndroid Build Coastguard Worker auto trace_flush_data =
252*61046927SAndroid Build Coastguard Worker (const struct tu_u_trace_submission_data *) flush_data;
253*61046927SAndroid Build Coastguard Worker uint32_t submission_id = trace_flush_data->submission_id;
254*61046927SAndroid Build Coastguard Worker uint64_t gpu_ts_offset = trace_flush_data->gpu_ts_offset;
255*61046927SAndroid Build Coastguard Worker
256*61046927SAndroid Build Coastguard Worker if (!stage)
257*61046927SAndroid Build Coastguard Worker return;
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker if (stage->stage_id != stage_id) {
260*61046927SAndroid Build Coastguard Worker PERFETTO_ELOG("stage %d ended while stage %d is expected",
261*61046927SAndroid Build Coastguard Worker stage_id, stage->stage_id);
262*61046927SAndroid Build Coastguard Worker return;
263*61046927SAndroid Build Coastguard Worker }
264*61046927SAndroid Build Coastguard Worker
265*61046927SAndroid Build Coastguard Worker /* If we haven't managed to calibrate the alignment between GPU and CPU
266*61046927SAndroid Build Coastguard Worker * timestamps yet, then skip this trace, otherwise perfetto won't know
267*61046927SAndroid Build Coastguard Worker * what to do with it.
268*61046927SAndroid Build Coastguard Worker */
269*61046927SAndroid Build Coastguard Worker if (!sync_gpu_ts)
270*61046927SAndroid Build Coastguard Worker return;
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker TuRenderpassDataSource::Trace([=](TuRenderpassDataSource::TraceContext tctx) {
273*61046927SAndroid Build Coastguard Worker if (auto state = tctx.GetIncrementalState(); state->was_cleared) {
274*61046927SAndroid Build Coastguard Worker send_descriptors(tctx);
275*61046927SAndroid Build Coastguard Worker state->was_cleared = false;
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker auto packet = tctx.NewTracePacket();
279*61046927SAndroid Build Coastguard Worker
280*61046927SAndroid Build Coastguard Worker gpu_max_timestamp = MAX2(gpu_max_timestamp, ts_ns + gpu_ts_offset);
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker packet->set_timestamp(stage->start_ts + gpu_ts_offset);
283*61046927SAndroid Build Coastguard Worker packet->set_timestamp_clock_id(gpu_clock_id);
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker auto event = packet->set_gpu_render_stage_event();
286*61046927SAndroid Build Coastguard Worker event->set_event_id(0); // ???
287*61046927SAndroid Build Coastguard Worker event->set_hw_queue_id(DEFAULT_HW_QUEUE_ID);
288*61046927SAndroid Build Coastguard Worker event->set_duration(ts_ns - stage->start_ts);
289*61046927SAndroid Build Coastguard Worker if (stage->stage_iid)
290*61046927SAndroid Build Coastguard Worker event->set_stage_iid(stage->stage_iid);
291*61046927SAndroid Build Coastguard Worker else
292*61046927SAndroid Build Coastguard Worker event->set_stage_id(stage->stage_id);
293*61046927SAndroid Build Coastguard Worker event->set_context((uintptr_t) dev);
294*61046927SAndroid Build Coastguard Worker event->set_submission_id(submission_id);
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker if (stage->payload) {
297*61046927SAndroid Build Coastguard Worker if (stage->start_payload_function)
298*61046927SAndroid Build Coastguard Worker ((trace_payload_as_extra_func) stage->start_payload_function)(
299*61046927SAndroid Build Coastguard Worker event, stage->payload);
300*61046927SAndroid Build Coastguard Worker free((void *)stage->payload);
301*61046927SAndroid Build Coastguard Worker }
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker if (payload && payload_as_extra)
304*61046927SAndroid Build Coastguard Worker payload_as_extra(event, payload);
305*61046927SAndroid Build Coastguard Worker });
306*61046927SAndroid Build Coastguard Worker }
307*61046927SAndroid Build Coastguard Worker
308*61046927SAndroid Build Coastguard Worker class TuMemoryDataSource : public perfetto::DataSource<TuMemoryDataSource> {
309*61046927SAndroid Build Coastguard Worker public:
OnSetup(const SetupArgs &)310*61046927SAndroid Build Coastguard Worker void OnSetup(const SetupArgs &) override
311*61046927SAndroid Build Coastguard Worker {
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker
OnStart(const StartArgs &)314*61046927SAndroid Build Coastguard Worker void OnStart(const StartArgs &) override
315*61046927SAndroid Build Coastguard Worker {
316*61046927SAndroid Build Coastguard Worker PERFETTO_LOG("Memory tracing started");
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
OnStop(const StopArgs &)319*61046927SAndroid Build Coastguard Worker void OnStop(const StopArgs &) override
320*61046927SAndroid Build Coastguard Worker {
321*61046927SAndroid Build Coastguard Worker PERFETTO_LOG("Memory tracing stopped");
322*61046927SAndroid Build Coastguard Worker }
323*61046927SAndroid Build Coastguard Worker };
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(TuMemoryDataSource);
326*61046927SAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(TuMemoryDataSource);
327*61046927SAndroid Build Coastguard Worker
328*61046927SAndroid Build Coastguard Worker
329*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
330*61046927SAndroid Build Coastguard Worker extern "C" {
331*61046927SAndroid Build Coastguard Worker #endif
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker void
tu_perfetto_init(void)334*61046927SAndroid Build Coastguard Worker tu_perfetto_init(void)
335*61046927SAndroid Build Coastguard Worker {
336*61046927SAndroid Build Coastguard Worker util_perfetto_init();
337*61046927SAndroid Build Coastguard Worker
338*61046927SAndroid Build Coastguard Worker {
339*61046927SAndroid Build Coastguard Worker perfetto::DataSourceDescriptor dsd;
340*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
341*61046927SAndroid Build Coastguard Worker /* AGI requires this name */
342*61046927SAndroid Build Coastguard Worker dsd.set_name("gpu.renderstages");
343*61046927SAndroid Build Coastguard Worker #else
344*61046927SAndroid Build Coastguard Worker dsd.set_name("gpu.renderstages.msm");
345*61046927SAndroid Build Coastguard Worker #endif
346*61046927SAndroid Build Coastguard Worker TuRenderpassDataSource::Register(dsd);
347*61046927SAndroid Build Coastguard Worker }
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker {
350*61046927SAndroid Build Coastguard Worker perfetto::DataSourceDescriptor dsd;
351*61046927SAndroid Build Coastguard Worker dsd.set_name("gpu.memory.msm");
352*61046927SAndroid Build Coastguard Worker TuMemoryDataSource::Register(dsd);
353*61046927SAndroid Build Coastguard Worker }
354*61046927SAndroid Build Coastguard Worker }
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker static void
emit_sync_timestamp(uint64_t cpu_ts,uint64_t gpu_ts)357*61046927SAndroid Build Coastguard Worker emit_sync_timestamp(uint64_t cpu_ts, uint64_t gpu_ts)
358*61046927SAndroid Build Coastguard Worker {
359*61046927SAndroid Build Coastguard Worker TuRenderpassDataSource::Trace([=](auto tctx) {
360*61046927SAndroid Build Coastguard Worker MesaRenderpassDataSource<TuRenderpassDataSource,
361*61046927SAndroid Build Coastguard Worker TuRenderpassTraits>::EmitClockSync(tctx, cpu_ts,
362*61046927SAndroid Build Coastguard Worker gpu_ts, gpu_clock_id);
363*61046927SAndroid Build Coastguard Worker });
364*61046927SAndroid Build Coastguard Worker }
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker static void
emit_submit_id(uint32_t submission_id)367*61046927SAndroid Build Coastguard Worker emit_submit_id(uint32_t submission_id)
368*61046927SAndroid Build Coastguard Worker {
369*61046927SAndroid Build Coastguard Worker TuRenderpassDataSource::Trace([=](TuRenderpassDataSource::TraceContext tctx) {
370*61046927SAndroid Build Coastguard Worker auto packet = tctx.NewTracePacket();
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker packet->set_timestamp(perfetto::base::GetBootTimeNs().count());
373*61046927SAndroid Build Coastguard Worker
374*61046927SAndroid Build Coastguard Worker auto event = packet->set_vulkan_api_event();
375*61046927SAndroid Build Coastguard Worker auto submit = event->set_vk_queue_submit();
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker submit->set_submission_id(submission_id);
378*61046927SAndroid Build Coastguard Worker });
379*61046927SAndroid Build Coastguard Worker }
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker struct tu_perfetto_clocks
tu_perfetto_submit(struct tu_device * dev,uint32_t submission_id,struct tu_perfetto_clocks * gpu_clocks)382*61046927SAndroid Build Coastguard Worker tu_perfetto_submit(struct tu_device *dev,
383*61046927SAndroid Build Coastguard Worker uint32_t submission_id,
384*61046927SAndroid Build Coastguard Worker struct tu_perfetto_clocks *gpu_clocks)
385*61046927SAndroid Build Coastguard Worker {
386*61046927SAndroid Build Coastguard Worker struct tu_perfetto_clocks clocks {};
387*61046927SAndroid Build Coastguard Worker if (gpu_clocks) {
388*61046927SAndroid Build Coastguard Worker clocks = *gpu_clocks;
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker if (!u_trace_perfetto_active(tu_device_get_u_trace(dev)))
392*61046927SAndroid Build Coastguard Worker return {};
393*61046927SAndroid Build Coastguard Worker
394*61046927SAndroid Build Coastguard Worker clocks.cpu = perfetto::base::GetBootTimeNs().count();
395*61046927SAndroid Build Coastguard Worker
396*61046927SAndroid Build Coastguard Worker if (gpu_clocks) {
397*61046927SAndroid Build Coastguard Worker /* TODO: It would be better to use CPU time that comes
398*61046927SAndroid Build Coastguard Worker * together with GPU time from the KGSL, but it's not
399*61046927SAndroid Build Coastguard Worker * equal to GetBootTimeNs.
400*61046927SAndroid Build Coastguard Worker */
401*61046927SAndroid Build Coastguard Worker
402*61046927SAndroid Build Coastguard Worker clocks.gpu_ts_offset = MAX2(gpu_timestamp_offset, clocks.gpu_ts_offset);
403*61046927SAndroid Build Coastguard Worker gpu_timestamp_offset = clocks.gpu_ts_offset;
404*61046927SAndroid Build Coastguard Worker sync_gpu_ts = clocks.gpu_ts + clocks.gpu_ts_offset;
405*61046927SAndroid Build Coastguard Worker } else {
406*61046927SAndroid Build Coastguard Worker clocks.gpu_ts = 0;
407*61046927SAndroid Build Coastguard Worker clocks.gpu_ts_offset = gpu_timestamp_offset;
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker if (clocks.cpu < next_clock_sync_ns)
410*61046927SAndroid Build Coastguard Worker return clocks;
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker if (tu_device_get_gpu_timestamp(dev, &clocks.gpu_ts)) {
413*61046927SAndroid Build Coastguard Worker PERFETTO_ELOG("Could not sync CPU and GPU clocks");
414*61046927SAndroid Build Coastguard Worker return {};
415*61046927SAndroid Build Coastguard Worker }
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker clocks.gpu_ts = tu_device_ticks_to_ns(dev, clocks.gpu_ts);
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker /* get cpu timestamp again because tu_device_get_gpu_timestamp can take
420*61046927SAndroid Build Coastguard Worker * >100us
421*61046927SAndroid Build Coastguard Worker */
422*61046927SAndroid Build Coastguard Worker clocks.cpu = perfetto::base::GetBootTimeNs().count();
423*61046927SAndroid Build Coastguard Worker
424*61046927SAndroid Build Coastguard Worker uint64_t current_suspend_count = 0;
425*61046927SAndroid Build Coastguard Worker /* If we fail to get it we will use a fallback */
426*61046927SAndroid Build Coastguard Worker tu_device_get_suspend_count(dev, ¤t_suspend_count);
427*61046927SAndroid Build Coastguard Worker
428*61046927SAndroid Build Coastguard Worker /* GPU timestamp is being reset after suspend-resume cycle.
429*61046927SAndroid Build Coastguard Worker * Perfetto requires clock snapshots to be monotonic,
430*61046927SAndroid Build Coastguard Worker * so we have to fix-up the time.
431*61046927SAndroid Build Coastguard Worker */
432*61046927SAndroid Build Coastguard Worker if (current_suspend_count != last_suspend_count) {
433*61046927SAndroid Build Coastguard Worker gpu_timestamp_offset = gpu_max_timestamp;
434*61046927SAndroid Build Coastguard Worker last_suspend_count = current_suspend_count;
435*61046927SAndroid Build Coastguard Worker }
436*61046927SAndroid Build Coastguard Worker clocks.gpu_ts_offset = gpu_timestamp_offset;
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker uint64_t gpu_absolute_ts = clocks.gpu_ts + clocks.gpu_ts_offset;
439*61046927SAndroid Build Coastguard Worker
440*61046927SAndroid Build Coastguard Worker /* Fallback check, detect non-monotonic cases which would happen
441*61046927SAndroid Build Coastguard Worker * if we cannot retrieve suspend count.
442*61046927SAndroid Build Coastguard Worker */
443*61046927SAndroid Build Coastguard Worker if (sync_gpu_ts > gpu_absolute_ts) {
444*61046927SAndroid Build Coastguard Worker gpu_absolute_ts += (gpu_max_timestamp - gpu_timestamp_offset);
445*61046927SAndroid Build Coastguard Worker gpu_timestamp_offset = gpu_max_timestamp;
446*61046927SAndroid Build Coastguard Worker clocks.gpu_ts = gpu_absolute_ts - gpu_timestamp_offset;
447*61046927SAndroid Build Coastguard Worker }
448*61046927SAndroid Build Coastguard Worker
449*61046927SAndroid Build Coastguard Worker if (sync_gpu_ts > gpu_absolute_ts) {
450*61046927SAndroid Build Coastguard Worker PERFETTO_ELOG("Non-monotonic gpu timestamp detected, bailing out");
451*61046927SAndroid Build Coastguard Worker return {};
452*61046927SAndroid Build Coastguard Worker }
453*61046927SAndroid Build Coastguard Worker
454*61046927SAndroid Build Coastguard Worker gpu_max_timestamp = clocks.gpu_ts;
455*61046927SAndroid Build Coastguard Worker sync_gpu_ts = clocks.gpu_ts;
456*61046927SAndroid Build Coastguard Worker next_clock_sync_ns = clocks.cpu + 30000000;
457*61046927SAndroid Build Coastguard Worker }
458*61046927SAndroid Build Coastguard Worker
459*61046927SAndroid Build Coastguard Worker emit_sync_timestamp(clocks.cpu, clocks.gpu_ts + clocks.gpu_ts_offset);
460*61046927SAndroid Build Coastguard Worker emit_submit_id(submission_id);
461*61046927SAndroid Build Coastguard Worker return clocks;
462*61046927SAndroid Build Coastguard Worker }
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker /*
465*61046927SAndroid Build Coastguard Worker * Trace callbacks, called from u_trace once the timestamps from GPU have been
466*61046927SAndroid Build Coastguard Worker * collected.
467*61046927SAndroid Build Coastguard Worker *
468*61046927SAndroid Build Coastguard Worker * The default "extra" funcs are code-generated into tu_tracepoints_perfetto.h
469*61046927SAndroid Build Coastguard Worker * and just take the tracepoint's args and add them as name/value pairs in the
470*61046927SAndroid Build Coastguard Worker * perfetto events. This file can usually just map a tu_perfetto_* to
471*61046927SAndroid Build Coastguard Worker * stage_start/end with a call to that codegenned "extra" func. But you can
472*61046927SAndroid Build Coastguard Worker * also provide your own entrypoint and extra funcs if you want to change that
473*61046927SAndroid Build Coastguard Worker * mapping.
474*61046927SAndroid Build Coastguard Worker */
475*61046927SAndroid Build Coastguard Worker
476*61046927SAndroid Build Coastguard Worker #define CREATE_EVENT_CALLBACK(event_name, stage_id) \
477*61046927SAndroid Build Coastguard Worker void tu_perfetto_start_##event_name( \
478*61046927SAndroid Build Coastguard Worker struct tu_device *dev, uint64_t ts_ns, uint16_t tp_idx, \
479*61046927SAndroid Build Coastguard Worker const void *flush_data, const struct trace_start_##event_name *payload, \
480*61046927SAndroid Build Coastguard Worker const void *indirect_data) \
481*61046927SAndroid Build Coastguard Worker { \
482*61046927SAndroid Build Coastguard Worker stage_start( \
483*61046927SAndroid Build Coastguard Worker dev, ts_ns, stage_id, NULL, payload, sizeof(*payload), \
484*61046927SAndroid Build Coastguard Worker (trace_payload_as_extra_func) &trace_payload_as_extra_start_##event_name); \
485*61046927SAndroid Build Coastguard Worker } \
486*61046927SAndroid Build Coastguard Worker \
487*61046927SAndroid Build Coastguard Worker void tu_perfetto_end_##event_name( \
488*61046927SAndroid Build Coastguard Worker struct tu_device *dev, uint64_t ts_ns, uint16_t tp_idx, \
489*61046927SAndroid Build Coastguard Worker const void *flush_data, const struct trace_end_##event_name *payload, \
490*61046927SAndroid Build Coastguard Worker const void *indirect_data) \
491*61046927SAndroid Build Coastguard Worker { \
492*61046927SAndroid Build Coastguard Worker stage_end( \
493*61046927SAndroid Build Coastguard Worker dev, ts_ns, stage_id, flush_data, payload, \
494*61046927SAndroid Build Coastguard Worker (trace_payload_as_extra_func) &trace_payload_as_extra_end_##event_name); \
495*61046927SAndroid Build Coastguard Worker }
496*61046927SAndroid Build Coastguard Worker
CREATE_EVENT_CALLBACK(cmd_buffer,CMD_BUFFER_STAGE_ID)497*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(cmd_buffer, CMD_BUFFER_STAGE_ID)
498*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(render_pass, RENDER_PASS_STAGE_ID)
499*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(binning_ib, BINNING_STAGE_ID)
500*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(draw_ib_gmem, GMEM_STAGE_ID)
501*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(draw_ib_sysmem, BYPASS_STAGE_ID)
502*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(blit, BLIT_STAGE_ID)
503*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(compute, COMPUTE_STAGE_ID)
504*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(compute_indirect, COMPUTE_STAGE_ID)
505*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(generic_clear, GENERIC_CLEAR_STAGE_ID)
506*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(gmem_clear, CLEAR_GMEM_STAGE_ID)
507*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(sysmem_clear, CLEAR_SYSMEM_STAGE_ID)
508*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(sysmem_clear_all, CLEAR_SYSMEM_STAGE_ID)
509*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(gmem_load, GMEM_LOAD_STAGE_ID)
510*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(gmem_store, GMEM_STORE_STAGE_ID)
511*61046927SAndroid Build Coastguard Worker CREATE_EVENT_CALLBACK(sysmem_resolve, SYSMEM_RESOLVE_STAGE_ID)
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker void
514*61046927SAndroid Build Coastguard Worker tu_perfetto_start_cmd_buffer_annotation(
515*61046927SAndroid Build Coastguard Worker struct tu_device *dev,
516*61046927SAndroid Build Coastguard Worker uint64_t ts_ns,
517*61046927SAndroid Build Coastguard Worker uint16_t tp_idx,
518*61046927SAndroid Build Coastguard Worker const void *flush_data,
519*61046927SAndroid Build Coastguard Worker const struct trace_start_cmd_buffer_annotation *payload,
520*61046927SAndroid Build Coastguard Worker const void *indirect_data)
521*61046927SAndroid Build Coastguard Worker {
522*61046927SAndroid Build Coastguard Worker /* No extra func necessary, the only arg is in the end payload.*/
523*61046927SAndroid Build Coastguard Worker stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_STAGE_ID, payload->str, payload,
524*61046927SAndroid Build Coastguard Worker sizeof(*payload), NULL);
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker void
tu_perfetto_end_cmd_buffer_annotation(struct tu_device * dev,uint64_t ts_ns,uint16_t tp_idx,const void * flush_data,const struct trace_end_cmd_buffer_annotation * payload,const void * indirect_data)528*61046927SAndroid Build Coastguard Worker tu_perfetto_end_cmd_buffer_annotation(
529*61046927SAndroid Build Coastguard Worker struct tu_device *dev,
530*61046927SAndroid Build Coastguard Worker uint64_t ts_ns,
531*61046927SAndroid Build Coastguard Worker uint16_t tp_idx,
532*61046927SAndroid Build Coastguard Worker const void *flush_data,
533*61046927SAndroid Build Coastguard Worker const struct trace_end_cmd_buffer_annotation *payload,
534*61046927SAndroid Build Coastguard Worker const void *indirect_data)
535*61046927SAndroid Build Coastguard Worker {
536*61046927SAndroid Build Coastguard Worker /* Pass the payload string as the app_event, which will appear right on the
537*61046927SAndroid Build Coastguard Worker * event block, rather than as metadata inside.
538*61046927SAndroid Build Coastguard Worker */
539*61046927SAndroid Build Coastguard Worker stage_end(dev, ts_ns, CMD_BUFFER_ANNOTATION_STAGE_ID, flush_data,
540*61046927SAndroid Build Coastguard Worker payload, NULL);
541*61046927SAndroid Build Coastguard Worker }
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker void
tu_perfetto_start_cmd_buffer_annotation_rp(struct tu_device * dev,uint64_t ts_ns,uint16_t tp_idx,const void * flush_data,const struct trace_start_cmd_buffer_annotation_rp * payload,const void * indirect_data)544*61046927SAndroid Build Coastguard Worker tu_perfetto_start_cmd_buffer_annotation_rp(
545*61046927SAndroid Build Coastguard Worker struct tu_device *dev,
546*61046927SAndroid Build Coastguard Worker uint64_t ts_ns,
547*61046927SAndroid Build Coastguard Worker uint16_t tp_idx,
548*61046927SAndroid Build Coastguard Worker const void *flush_data,
549*61046927SAndroid Build Coastguard Worker const struct trace_start_cmd_buffer_annotation_rp *payload,
550*61046927SAndroid Build Coastguard Worker const void *indirect_data)
551*61046927SAndroid Build Coastguard Worker {
552*61046927SAndroid Build Coastguard Worker /* No extra func necessary, the only arg is in the end payload.*/
553*61046927SAndroid Build Coastguard Worker stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID,
554*61046927SAndroid Build Coastguard Worker payload->str, payload, sizeof(*payload), NULL);
555*61046927SAndroid Build Coastguard Worker }
556*61046927SAndroid Build Coastguard Worker
557*61046927SAndroid Build Coastguard Worker void
tu_perfetto_end_cmd_buffer_annotation_rp(struct tu_device * dev,uint64_t ts_ns,uint16_t tp_idx,const void * flush_data,const struct trace_end_cmd_buffer_annotation_rp * payload,const void * indirect_data)558*61046927SAndroid Build Coastguard Worker tu_perfetto_end_cmd_buffer_annotation_rp(
559*61046927SAndroid Build Coastguard Worker struct tu_device *dev,
560*61046927SAndroid Build Coastguard Worker uint64_t ts_ns,
561*61046927SAndroid Build Coastguard Worker uint16_t tp_idx,
562*61046927SAndroid Build Coastguard Worker const void *flush_data,
563*61046927SAndroid Build Coastguard Worker const struct trace_end_cmd_buffer_annotation_rp *payload,
564*61046927SAndroid Build Coastguard Worker const void *indirect_data)
565*61046927SAndroid Build Coastguard Worker {
566*61046927SAndroid Build Coastguard Worker /* Pass the payload string as the app_event, which will appear right on the
567*61046927SAndroid Build Coastguard Worker * event block, rather than as metadata inside.
568*61046927SAndroid Build Coastguard Worker */
569*61046927SAndroid Build Coastguard Worker stage_end(dev, ts_ns, CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID,
570*61046927SAndroid Build Coastguard Worker flush_data, payload, NULL);
571*61046927SAndroid Build Coastguard Worker }
572*61046927SAndroid Build Coastguard Worker
573*61046927SAndroid Build Coastguard Worker
574*61046927SAndroid Build Coastguard Worker static void
log_mem(struct tu_device * dev,struct tu_buffer * buffer,struct tu_image * image,perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::Operation op)575*61046927SAndroid Build Coastguard Worker log_mem(struct tu_device *dev, struct tu_buffer *buffer, struct tu_image *image,
576*61046927SAndroid Build Coastguard Worker perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::Operation op)
577*61046927SAndroid Build Coastguard Worker {
578*61046927SAndroid Build Coastguard Worker TuMemoryDataSource::Trace([=](TuMemoryDataSource::TraceContext tctx) {
579*61046927SAndroid Build Coastguard Worker auto packet = tctx.NewTracePacket();
580*61046927SAndroid Build Coastguard Worker
581*61046927SAndroid Build Coastguard Worker packet->set_timestamp(perfetto::base::GetBootTimeNs().count());
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker auto event = packet->set_vulkan_memory_event();
584*61046927SAndroid Build Coastguard Worker
585*61046927SAndroid Build Coastguard Worker event->set_timestamp(perfetto::base::GetBootTimeNs().count());
586*61046927SAndroid Build Coastguard Worker event->set_operation(op);
587*61046927SAndroid Build Coastguard Worker event->set_pid(getpid());
588*61046927SAndroid Build Coastguard Worker
589*61046927SAndroid Build Coastguard Worker if (buffer) {
590*61046927SAndroid Build Coastguard Worker event->set_source(perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::SOURCE_BUFFER);
591*61046927SAndroid Build Coastguard Worker event->set_memory_size(buffer->vk.size);
592*61046927SAndroid Build Coastguard Worker if (buffer->bo)
593*61046927SAndroid Build Coastguard Worker event->set_memory_address(buffer->iova);
594*61046927SAndroid Build Coastguard Worker } else {
595*61046927SAndroid Build Coastguard Worker assert(image);
596*61046927SAndroid Build Coastguard Worker event->set_source(perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::SOURCE_IMAGE);
597*61046927SAndroid Build Coastguard Worker event->set_memory_size(image->layout[0].size);
598*61046927SAndroid Build Coastguard Worker if (image->bo)
599*61046927SAndroid Build Coastguard Worker event->set_memory_address(image->iova);
600*61046927SAndroid Build Coastguard Worker }
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker });
603*61046927SAndroid Build Coastguard Worker }
604*61046927SAndroid Build Coastguard Worker
605*61046927SAndroid Build Coastguard Worker void
tu_perfetto_log_create_buffer(struct tu_device * dev,struct tu_buffer * buffer)606*61046927SAndroid Build Coastguard Worker tu_perfetto_log_create_buffer(struct tu_device *dev, struct tu_buffer *buffer)
607*61046927SAndroid Build Coastguard Worker {
608*61046927SAndroid Build Coastguard Worker log_mem(dev, buffer, NULL, perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_CREATE);
609*61046927SAndroid Build Coastguard Worker }
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker void
tu_perfetto_log_bind_buffer(struct tu_device * dev,struct tu_buffer * buffer)612*61046927SAndroid Build Coastguard Worker tu_perfetto_log_bind_buffer(struct tu_device *dev, struct tu_buffer *buffer)
613*61046927SAndroid Build Coastguard Worker {
614*61046927SAndroid Build Coastguard Worker log_mem(dev, buffer, NULL, perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_BIND);
615*61046927SAndroid Build Coastguard Worker }
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker void
tu_perfetto_log_destroy_buffer(struct tu_device * dev,struct tu_buffer * buffer)618*61046927SAndroid Build Coastguard Worker tu_perfetto_log_destroy_buffer(struct tu_device *dev, struct tu_buffer *buffer)
619*61046927SAndroid Build Coastguard Worker {
620*61046927SAndroid Build Coastguard Worker log_mem(dev, buffer, NULL, buffer->bo ?
621*61046927SAndroid Build Coastguard Worker perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_DESTROY_BOUND :
622*61046927SAndroid Build Coastguard Worker perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_DESTROY);
623*61046927SAndroid Build Coastguard Worker }
624*61046927SAndroid Build Coastguard Worker
625*61046927SAndroid Build Coastguard Worker void
tu_perfetto_log_create_image(struct tu_device * dev,struct tu_image * image)626*61046927SAndroid Build Coastguard Worker tu_perfetto_log_create_image(struct tu_device *dev, struct tu_image *image)
627*61046927SAndroid Build Coastguard Worker {
628*61046927SAndroid Build Coastguard Worker log_mem(dev, NULL, image, perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_CREATE);
629*61046927SAndroid Build Coastguard Worker }
630*61046927SAndroid Build Coastguard Worker
631*61046927SAndroid Build Coastguard Worker void
tu_perfetto_log_bind_image(struct tu_device * dev,struct tu_image * image)632*61046927SAndroid Build Coastguard Worker tu_perfetto_log_bind_image(struct tu_device *dev, struct tu_image *image)
633*61046927SAndroid Build Coastguard Worker {
634*61046927SAndroid Build Coastguard Worker log_mem(dev, NULL, image, perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_BIND);
635*61046927SAndroid Build Coastguard Worker }
636*61046927SAndroid Build Coastguard Worker
637*61046927SAndroid Build Coastguard Worker void
tu_perfetto_log_destroy_image(struct tu_device * dev,struct tu_image * image)638*61046927SAndroid Build Coastguard Worker tu_perfetto_log_destroy_image(struct tu_device *dev, struct tu_image *image)
639*61046927SAndroid Build Coastguard Worker {
640*61046927SAndroid Build Coastguard Worker log_mem(dev, NULL, image, image->bo ?
641*61046927SAndroid Build Coastguard Worker perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_DESTROY_BOUND :
642*61046927SAndroid Build Coastguard Worker perfetto::protos::pbzero::perfetto_pbzero_enum_VulkanMemoryEvent::OP_DESTROY);
643*61046927SAndroid Build Coastguard Worker }
644*61046927SAndroid Build Coastguard Worker
645*61046927SAndroid Build Coastguard Worker
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
648*61046927SAndroid Build Coastguard Worker }
649*61046927SAndroid Build Coastguard Worker #endif
650