68
70
[CMD_BUFFER_STAGE_ID] = { "Command Buffer" },
71
[CMD_BUFFER_ANNOTATION_STAGE_ID] = { "Annotation", "Command Buffer Annotation" },
69
72
[RENDER_PASS_STAGE_ID] = { "Render Pass" },
73
[CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID] = { "Annotation", "Render Pass Command Buffer Annotation" },
70
74
[BINNING_STAGE_ID] = { "Binning", "Perform Visibility pass and determine target bins" },
71
75
[GMEM_STAGE_ID] = { "GMEM", "Rendering to GMEM" },
72
76
[BYPASS_STAGE_ID] = { "Bypass", "Rendering to system memory" },
128
132
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(TuRenderpassDataSource);
131
send_descriptors(TuRenderpassDataSource::TraceContext &ctx, uint64_t ts_ns)
135
send_descriptors(TuRenderpassDataSource::TraceContext &ctx)
133
137
PERFETTO_LOG("Sending renderstage descriptors");
135
139
auto packet = ctx.NewTracePacket();
141
/* This must be set before interned data is sent. */
142
packet->set_sequence_flags(perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
137
144
packet->set_timestamp(0);
139
146
auto event = packet->set_gpu_render_stage_event();
192
199
stage_start(struct tu_device *dev,
194
201
enum tu_stage_id stage_id,
202
const char *app_event,
195
203
const void *payload = nullptr,
196
204
size_t payload_size = 0,
197
205
trace_payload_as_extra_func payload_as_extra = nullptr)
215
223
*stage = (struct tu_perfetto_stage) {
216
224
.stage_id = stage_id,
217
226
.start_ts = ts_ns,
218
227
.payload = payload,
219
228
.start_payload_function = (void *) payload_as_extra,
232
TuRenderpassDataSource::Trace([=](auto tctx) {
234
tctx.GetDataSourceLocked()->debug_marker_stage(tctx, app_event);
224
240
stage_end(struct tu_device *dev, uint64_t ts_ns, enum tu_stage_id stage_id,
225
uint32_t submission_id, const void* payload = nullptr,
241
const void *flush_data,
242
const void* payload = nullptr,
226
243
trace_payload_as_extra_func payload_as_extra = nullptr)
228
245
struct tu_perfetto_stage *stage = stage_pop(dev);
246
auto trace_flush_data =
247
(const struct tu_u_trace_submission_data *) flush_data;
248
uint32_t submission_id =
249
tu_u_trace_submission_data_get_submit_id(trace_flush_data);
246
267
TuRenderpassDataSource::Trace([=](TuRenderpassDataSource::TraceContext tctx) {
247
268
if (auto state = tctx.GetIncrementalState(); state->was_cleared) {
248
send_descriptors(tctx, stage->start_ts);
269
send_descriptors(tctx);
249
270
state->was_cleared = false;
260
281
event->set_event_id(0); // ???
261
282
event->set_hw_queue_id(DEFAULT_HW_QUEUE_ID);
262
283
event->set_duration(ts_ns - stage->start_ts);
263
event->set_stage_id(stage->stage_id);
264
event->set_context((uintptr_t)dev);
284
if (stage->stage_iid)
285
event->set_stage_iid(stage->stage_iid);
287
event->set_stage_id(stage->stage_id);
288
event->set_context((uintptr_t) dev);
265
289
event->set_submission_id(submission_id);
267
291
if (stage->payload) {
381
405
* Trace callbacks, called from u_trace once the timestamps from GPU have been
408
* The default "extra" funcs are code-generated into tu_tracepoints_perfetto.h
409
* and just take the tracepoint's args and add them as name/value pairs in the
410
* perfetto events. This file can usually just map a tu_perfetto_* to
411
* stage_start/end with a call to that codegenned "extra" func. But you can
412
* also provide your own entrypoint and extra funcs if you want to change that
385
416
#define CREATE_EVENT_CALLBACK(event_name, stage_id) \
388
419
const struct trace_start_##event_name *payload) \
391
dev, ts_ns, stage_id, payload, \
392
sizeof(struct trace_start_##event_name), \
422
dev, ts_ns, stage_id, NULL, payload, sizeof(*payload), \
393
423
(trace_payload_as_extra_func) &trace_payload_as_extra_start_##event_name); \
397
427
struct tu_device *dev, uint64_t ts_ns, const void *flush_data, \
398
428
const struct trace_end_##event_name *payload) \
400
auto trace_flush_data = \
401
(const struct tu_u_trace_submission_data *) flush_data; \
402
uint32_t submission_id = \
403
tu_u_trace_submission_data_get_submit_id(trace_flush_data); \
405
dev, ts_ns, stage_id, submission_id, payload, \
431
dev, ts_ns, stage_id, flush_data, payload, \
406
432
(trace_payload_as_extra_func) &trace_payload_as_extra_end_##event_name); \
420
446
CREATE_EVENT_CALLBACK(gmem_store, GMEM_STORE_STAGE_ID)
421
447
CREATE_EVENT_CALLBACK(sysmem_resolve, SYSMEM_RESOLVE_STAGE_ID)
450
tu_perfetto_start_cmd_buffer_annotation(
451
struct tu_device *dev,
453
const void *flush_data,
454
const struct trace_start_cmd_buffer_annotation *payload)
456
/* No extra func necessary, the only arg is in the end payload.*/
457
stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_STAGE_ID, payload->str, payload,
458
sizeof(*payload), NULL);
462
tu_perfetto_end_cmd_buffer_annotation(
463
struct tu_device *dev,
465
const void *flush_data,
466
const struct trace_end_cmd_buffer_annotation *payload)
468
/* Pass the payload string as the app_event, which will appear right on the
469
* event block, rather than as metadata inside.
471
stage_end(dev, ts_ns, CMD_BUFFER_ANNOTATION_STAGE_ID, flush_data,
476
tu_perfetto_start_cmd_buffer_annotation_rp(
477
struct tu_device *dev,
479
const void *flush_data,
480
const struct trace_start_cmd_buffer_annotation_rp *payload)
482
/* No extra func necessary, the only arg is in the end payload.*/
483
stage_start(dev, ts_ns, CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID,
484
payload->str, payload, sizeof(*payload), NULL);
488
tu_perfetto_end_cmd_buffer_annotation_rp(
489
struct tu_device *dev,
491
const void *flush_data,
492
const struct trace_end_cmd_buffer_annotation_rp *payload)
494
/* Pass the payload string as the app_event, which will appear right on the
495
* event block, rather than as metadata inside.
497
stage_end(dev, ts_ns, CMD_BUFFER_ANNOTATION_RENDER_PASS_STAGE_ID,
498
flush_data, payload, NULL);
423
501
#ifdef __cplusplus