tu/perfetto: Handle tracepoint args from start and end
authorMark Collins <mark@igalia.com>
Fri, 16 Sep 2022 14:06:52 +0000 (14:06 +0000)
committerMarge Bot <emma+marge@anholt.net>
Fri, 11 Nov 2022 13:50:56 +0000 (13:50 +0000)
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>

src/freedreno/vulkan/tu_perfetto.cc
src/freedreno/vulkan/tu_perfetto.h
src/freedreno/vulkan/tu_tracepoints.py

index b85386de71a2aea8fe12dcc79b0f757a2dfae81a..312fcf298ea1a973ffaa739e82a3693d4cbf7f84 100644 (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)
index f01c4031a7c6c241db9848847c0ad8b5ff982537..12f2bce167803d037e1fa108efe5a6d490efe8b5 100644 (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 {
index 12654ccdaa4cc9c7074f7d79a40be3e7a3f31675..d00cb3e5094f32f2880f1b67a9d44e097a80df64 100644 (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',