perfetto: Move intel's cmdbuf/queue annotation code to the shared util.
authorEmma Anholt <emma@anholt.net>
Thu, 16 Mar 2023 22:46:46 +0000 (15:46 -0700)
committerMarge Bot <emma+marge@anholt.net>
Thu, 30 Mar 2023 02:19:35 +0000 (02:19 +0000)
This will let other drivers use the same way of presenting annotations
without duplicating the whole hash table thing.

Reviewed-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22157>

src/intel/ds/intel_driver_ds.cc
src/intel/ds/intel_driver_ds.h
src/util/perf/u_perfetto_renderpass.h

index 54218b0..c88fc83 100644 (file)
@@ -139,15 +139,12 @@ send_descriptors(IntelRenderpassDataSource::TraceContext &ctx,
    PERFETTO_LOG("Sending renderstage descriptors");
 
    device->event_id = 0;
-   device->current_app_event_iid = device->start_app_event_iids;
    list_for_each_entry_safe(struct intel_ds_queue, queue, &device->queues, link) {
       for (uint32_t s = 0; s < ARRAY_SIZE(queue->stages); s++) {
          queue->stages[s].start_ns[0] = 0;
       }
    }
 
-   _mesa_hash_table_clear(device->app_events, NULL);
-
    {
       auto packet = ctx.NewTracePacket();
 
@@ -225,33 +222,6 @@ begin_event(struct intel_ds_queue *queue, uint64_t ts_ns,
    queue->stages[stage_id].level++;
 }
 
-static uint64_t
-add_app_event(IntelRenderpassDataSource::TraceContext &tctx,
-              struct intel_ds_device *device,
-              const char *app_event)
-{
-   struct hash_entry *entry =
-      _mesa_hash_table_search(device->app_events, app_event);
-   if (entry)
-      return (uint64_t) entry->data;
-
-   /* Allocate a new iid for the string */
-   uint64_t iid = device->current_app_event_iid++;
-   _mesa_hash_table_insert(device->app_events, app_event, (void*)(uintptr_t)iid);
-
-   /* Send the definition of iid/string to perfetto */
-   {
-      auto packet = tctx.NewTracePacket();
-      auto interned_data = packet->set_interned_data();
-
-      auto desc = interned_data->add_gpu_specifications();
-      desc->set_iid(iid);
-      desc->set_name(app_event);
-   }
-
-   return iid;
-}
-
 static void
 end_event(struct intel_ds_queue *queue, uint64_t ts_ns,
           enum intel_ds_queue_stage stage_id,
@@ -295,7 +265,8 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns,
        * have use the internal stage_iid.
        */
       uint64_t stage_iid = app_event ?
-         add_app_event(tctx, queue->device, app_event) : stage->stage_iid;
+         tctx.GetDataSourceLocked()->debug_marker_stage(tctx, app_event) :
+         stage->stage_iid;
 
       auto packet = tctx.NewTracePacket();
 
@@ -576,18 +547,12 @@ intel_ds_device_init(struct intel_ds_device *device,
    device->iid = get_iid();
    device->api = api;
    list_inithead(&device->queues);
-
-   /* Reserve iids for the application generated events */
-   device->start_app_event_iids = 1ull << 32;
-   device->app_events =
-      _mesa_hash_table_create(NULL, _mesa_hash_string, _mesa_key_string_equal);
 }
 
 void
 intel_ds_device_fini(struct intel_ds_device *device)
 {
    u_trace_context_fini(&device->trace_context);
-   _mesa_hash_table_destroy(device->app_events, NULL);
 }
 
 struct intel_ds_queue *
index dc4bc04..b2169cf 100644 (file)
@@ -110,19 +110,6 @@ struct intel_ds_device {
     */
    uint64_t event_id;
 
-   /* Start of unique IID for device generated events */
-   uint64_t start_app_event_iids;
-
-   /* Last app event iid (manipulate only inside
-    * IntelRenderpassDataSource::Trace)
-    */
-   uint64_t current_app_event_iid;
-
-   /* Hash table of application generated events (string -> iid) (manipulate
-    * only inside IntelRenderpassDataSource::Trace)
-    */
-   struct hash_table *app_events;
-
    struct u_trace_context trace_context;
 
    /* List of intel_ds_queue */
index 5083795..a128cf6 100644 (file)
@@ -23,7 +23,9 @@
 
 #include "perfetto.h"
 
+#include "util/hash_table.h"
 #include "util/perf/u_trace.h"
+#include "util/ralloc.h"
 
 using perfetto::DataSource;
 template <typename DataSourceType, typename DataSourceTraits>
@@ -39,10 +41,13 @@ class MesaRenderpassDataSource
    {
       // Use this callback to apply any custom configuration to your data
       // source based on the TraceConfig in SetupArgs.
+      debug_markers = NULL;
    }
 
    void OnStart(const perfetto::DataSourceBase::StartArgs &) override
    {
+      debug_markers = _mesa_hash_table_create(NULL, _mesa_hash_string,
+                                              _mesa_key_string_equal);
       // This notification can be used to initialize the GPU driver, enable
       // counters, etc. StartArgs will contains the DataSourceDescriptor,
       // which can be extended.
@@ -63,6 +68,8 @@ class MesaRenderpassDataSource
          packet->Finalize();
          ctx.Flush();
       });
+
+      ralloc_free(debug_markers);
    }
 
    /* Emits a clock sync trace event.  Perfetto uses periodic clock events
@@ -100,6 +107,47 @@ class MesaRenderpassDataSource
          clock->set_timestamp(gpu_ts);
       }
    }
+
+   /* Returns a stage iid to use for a command stream or queue annotation.
+    *
+    * Using a new stage lets the annotation string show up right on the track
+    * event in the UI, rather than needing to click into the event to find the
+    * name in the metadata.  Intended for use with
+    * vkCmdBeginDebugUtilsLabelEXT() and glPushDebugGroup().
+    */
+   uint64_t debug_marker_stage(TraceContext &ctx, const char *name)
+   {
+      struct hash_entry *entry = _mesa_hash_table_search(debug_markers, name);
+      const uint64_t dynamic_iid_base = 1ull << 32;
+
+      if (entry) {
+         return dynamic_iid_base + (uint32_t) (uintptr_t) entry->data;
+      } else {
+         uint64_t iid = dynamic_iid_base + debug_markers->entries;
+
+         auto packet = ctx.NewTracePacket();
+         auto interned_data = packet->set_interned_data();
+
+         auto desc = interned_data->add_gpu_specifications();
+         desc->set_iid(iid);
+         desc->set_name(name);
+
+         /* We only track the entry count in entry->data, because the
+          * dynamic_iid_base would get lost on 32-bit builds.
+          */
+         _mesa_hash_table_insert(debug_markers,
+                                 ralloc_strdup(debug_markers, name),
+                                 (void *) (uintptr_t) debug_markers->entries);
+
+         return iid;
+      }
+   }
+
+ private:
+   /* Hash table of application generated events (string -> iid) (use
+    * tctx.GetDataSourceLocked()->debug_marker_stage() to get a stage iid)
+    */
+   struct hash_table *debug_markers;
 };
 
 /* Begin the C API section. */