tu/perfetto: Handle tracepoint args from start and end

Perfetto's tracing backend was designed to only handle arguments
at the end event, we want to cover arguments both at the start
and end of the trace.

Signed-off-by: Mark Collins <mark@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18271>
This commit is contained in:
Mark Collins 2022-09-16 14:06:52 +00:00 committed by Marge Bot
parent f14e2ca099
commit e954ec7fef
3 changed files with 55 additions and 28 deletions

View file

@ -193,6 +193,8 @@ stage_push(struct tu_device *dev)
return &p->stages[p->stage_depth++];
}
typedef void (*trace_payload_as_extra_func)(perfetto::protos::pbzero::GpuRenderStageEvent *, const void*);
static struct tu_perfetto_stage *
stage_pop(struct tu_device *dev)
{
@ -210,7 +212,12 @@ stage_pop(struct tu_device *dev)
}
static void
stage_start(struct tu_device *dev, uint64_t ts_ns, enum tu_stage_id stage_id)
stage_start(struct tu_device *dev,
uint64_t ts_ns,
enum tu_stage_id stage_id,
const void *payload = nullptr,
size_t payload_size = 0,
trace_payload_as_extra_func payload_as_extra = nullptr)
{
struct tu_perfetto_stage *stage = stage_push(dev);
@ -219,14 +226,23 @@ stage_start(struct tu_device *dev, uint64_t ts_ns, enum tu_stage_id stage_id)
return;
}
*stage = (struct tu_perfetto_stage){
if (payload) {
void* new_payload = malloc(payload_size);
if (new_payload)
memcpy(new_payload, payload, payload_size);
else
PERFETTO_ELOG("Failed to allocate payload for stage %d", stage_id);
payload = new_payload;
}
*stage = (struct tu_perfetto_stage) {
.stage_id = stage_id,
.start_ts = ts_ns,
.payload = payload,
.start_payload_function = (void *) payload_as_extra,
};
}
typedef void (*trace_payload_as_extra_func)(perfetto::protos::pbzero::GpuRenderStageEvent *, const void*);
static void
stage_end(struct tu_device *dev, uint64_t ts_ns, enum tu_stage_id stage_id,
uint32_t submission_id, const void* payload = nullptr,
@ -271,9 +287,15 @@ stage_end(struct tu_device *dev, uint64_t ts_ns, enum tu_stage_id stage_id,
event->set_context((uintptr_t)dev);
event->set_submission_id(submission_id);
if (payload && payload_as_extra) {
payload_as_extra(event, payload);
if (stage->payload) {
if (stage->start_payload_function)
((trace_payload_as_extra_func) stage->start_payload_function)(
event, stage->payload);
free((void *)stage->payload);
}
if (payload && payload_as_extra)
payload_as_extra(event, payload);
});
}
@ -400,26 +422,29 @@ tu_perfetto_submit(struct tu_device *dev, uint32_t submission_id)
* collected.
*/
#define CREATE_EVENT_CALLBACK(event_name, stage_id) \
void \
tu_start_##event_name(struct tu_device *dev, uint64_t ts_ns, \
const void *flush_data, \
const struct trace_start_##event_name *payload) \
{ \
stage_start(dev, ts_ns, stage_id); \
} \
\
void \
tu_end_##event_name(struct tu_device *dev, uint64_t ts_ns, \
const void *flush_data, \
const struct trace_end_##event_name *payload) \
{ \
auto trace_flush_data = (const struct tu_u_trace_submission_data *) flush_data; \
uint32_t submission_id = \
tu_u_trace_submission_data_get_submit_id(trace_flush_data); \
stage_end(dev, ts_ns, stage_id, submission_id, payload, \
(trace_payload_as_extra_func) &trace_payload_as_extra_end_##event_name); \
}
#define CREATE_EVENT_CALLBACK(event_name, stage_id) \
void tu_perfetto_start_##event_name( \
struct tu_device *dev, uint64_t ts_ns, const void *flush_data, \
const struct trace_start_##event_name *payload) \
{ \
stage_start( \
dev, ts_ns, stage_id, payload, \
sizeof(struct trace_start_##event_name), \
(trace_payload_as_extra_func) &trace_payload_as_extra_start_##event_name); \
} \
\
void tu_perfetto_end_##event_name( \
struct tu_device *dev, uint64_t ts_ns, const void *flush_data, \
const struct trace_end_##event_name *payload) \
{ \
auto trace_flush_data = \
(const struct tu_u_trace_submission_data *) flush_data; \
uint32_t submission_id = \
tu_u_trace_submission_data_get_submit_id(trace_flush_data); \
stage_end( \
dev, ts_ns, stage_id, submission_id, payload, \
(trace_payload_as_extra_func) &trace_payload_as_extra_end_##event_name); \
}
CREATE_EVENT_CALLBACK(cmd_buffer, CMD_BUFFER_STAGE_ID)
CREATE_EVENT_CALLBACK(render_pass, RENDER_PASS_STAGE_ID)

View file

@ -23,6 +23,8 @@ struct tu_u_trace_submission_data;
struct tu_perfetto_stage {
int stage_id;
uint64_t start_ts;
const void* payload;
void* start_payload_function;
};
struct tu_perfetto_state {

View file

@ -51,12 +51,12 @@ def begin_end_tp(name, args=[], tp_struct=None, tp_print=None,
tu_default_tps.append(name)
Tracepoint('start_{0}'.format(name),
toggle_name=name,
tp_perfetto='tu_start_{0}'.format(name))
tp_perfetto='tu_perfetto_start_{0}'.format(name))
Tracepoint('end_{0}'.format(name),
toggle_name=name,
args=args,
tp_struct=tp_struct,
tp_perfetto='tu_end_{0}'.format(name),
tp_perfetto='tu_perfetto_end_{0}'.format(name),
tp_print=tp_print)
begin_end_tp('cmd_buffer',