Module: Mesa
Branch: main
Commit: 28b15fa9e7706da41c3b6bed3c640b4198359984
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=28b15fa9e7706da41c3b6bed3c640b4198359984

Author: Lionel Landwerlin <[email protected]>
Date:   Sun May 22 13:18:42 2022 +0300

anv: add support for command buffer tagging in traces

Signed-off-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Emma Anholt <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16655>

---

 src/intel/ds/intel_driver_ds.cc   | 82 ++++++++++++++++++++++++++++++++++++---
 src/intel/ds/intel_driver_ds.h    | 17 +++++++-
 src/intel/ds/intel_tracepoints.py |  8 ++++
 src/intel/vulkan/anv_utrace.c     | 30 ++++++++++++++
 4 files changed, 131 insertions(+), 6 deletions(-)

diff --git a/src/intel/ds/intel_driver_ds.cc b/src/intel/ds/intel_driver_ds.cc
index 42e2b69e530..ca93d481d79 100644
--- a/src/intel/ds/intel_driver_ds.cc
+++ b/src/intel/ds/intel_driver_ds.cc
@@ -195,12 +195,15 @@ send_descriptors(IntelRenderpassDataSource::TraceContext 
&ctx,
    PERFETTO_LOG("Sending renderstage descriptors");
 
    device->event_id = 0;
+   device->current_app_event_iid = device->start_app_event_iids;
    u_vector_foreach(queue, &device->queues) {
       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();
 
@@ -271,13 +274,46 @@ begin_event(struct intel_ds_queue *queue, uint64_t ts_ns,
       return;
    }
 
+   if (level >= (ARRAY_SIZE(queue->stages[stage_id].start_ns) - 1))
+      return;
+
    queue->stages[stage_id].start_ns[level] = 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,
-          uint32_t submission_id, const void* payload = nullptr,
+          uint32_t submission_id,
+          const char *app_event,
+          const void* payload = nullptr,
           trace_payload_as_extra_func payload_as_extra = nullptr)
 {
    struct intel_ds_device *device = queue->device;
@@ -310,6 +346,13 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns,
 
       uint64_t evt_id = device->event_id++;
 
+      /* If this is an application event, we might need to generate a new
+       * stage_iid if not already seen. Otherwise, it's a driver event and we
+       * have use the internal stage_iid.
+       */
+      uint64_t stage_iid = app_event ?
+         add_app_event(tctx, queue->device, app_event) : stage->stage_iid;
+
       auto packet = tctx.NewTracePacket();
 
       packet->set_timestamp(start_ns);
@@ -321,7 +364,7 @@ end_event(struct intel_ds_queue *queue, uint64_t ts_ns,
       event->set_gpu_id(queue->device->gpu_id);
 
       event->set_hw_queue_iid(stage->queue_iid);
-      event->set_stage_iid(stage->stage_iid);
+      event->set_stage_iid(stage_iid);
       event->set_context(queue->device->iid);
       event->set_event_id(evt_id);
       event->set_duration(ts_ns - start_ns);
@@ -403,7 +446,7 @@ extern "C" {
       const struct intel_ds_flush_data *flush =                         \
          (const struct intel_ds_flush_data *) flush_data;               \
       end_event(flush->queue, ts_ns, stage, flush->submission_id,       \
-                payload,                                                \
+                NULL, payload,                                          \
                 (trace_payload_as_extra_func)                           \
                 &trace_payload_as_extra_intel_end_##event_name);        \
    }                                                                    \
@@ -430,6 +473,29 @@ CREATE_DUAL_EVENT_CALLBACK(compute, 
INTEL_DS_QUEUE_STAGE_COMPUTE)
 CREATE_DUAL_EVENT_CALLBACK(generate_draws, INTEL_DS_QUEUE_STAGE_GENERATE_DRAWS)
 CREATE_DUAL_EVENT_CALLBACK(trace_copy, INTEL_DS_QUEUE_STAGE_BLORP)
 
+void
+intel_ds_begin_cmd_buffer_annotation(struct intel_ds_device *device,
+                                     uint64_t ts_ns,
+                                     const void *flush_data,
+                                     const struct 
trace_intel_begin_cmd_buffer_annotation *payload)
+{
+   const struct intel_ds_flush_data *flush =
+      (const struct intel_ds_flush_data *) flush_data;
+   begin_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_CMD_BUFFER);
+}
+
+void
+intel_ds_end_cmd_buffer_annotation(struct intel_ds_device *device,
+                                   uint64_t ts_ns,
+                                   const void *flush_data,
+                                   const struct 
trace_intel_end_cmd_buffer_annotation *payload)
+{
+   const struct intel_ds_flush_data *flush =
+      (const struct intel_ds_flush_data *) flush_data;
+   end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_CMD_BUFFER,
+             flush->submission_id, payload->str, NULL, NULL);
+}
+
 void
 intel_ds_begin_stall(struct intel_ds_device *device,
                      uint64_t ts_ns,
@@ -450,7 +516,7 @@ intel_ds_end_stall(struct intel_ds_device *device,
    const struct intel_ds_flush_data *flush =
       (const struct intel_ds_flush_data *) flush_data;
    end_event(flush->queue, ts_ns, INTEL_DS_QUEUE_STAGE_STALL,
-             flush->submission_id, payload,
+             flush->submission_id, NULL, payload,
              
(trace_payload_as_extra_func)custom_trace_payload_as_extra_end_stall);
 }
 
@@ -510,10 +576,10 @@ intel_driver_ds_init_once(void)
 }
 
 static once_flag intel_driver_ds_once_flag = ONCE_FLAG_INIT;
+static uint64_t iid = 1;
 
 static uint64_t get_iid()
 {
-   static uint64_t iid = 1;
    return iid++;
 }
 
@@ -541,12 +607,18 @@ intel_ds_device_init(struct intel_ds_device *device,
    device->iid = get_iid();
    device->api = api;
    u_vector_init(&device->queues, 4, sizeof(struct intel_ds_queue));
+
+   /* 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);
    u_vector_finish(&device->queues);
 }
 
diff --git a/src/intel/ds/intel_driver_ds.h b/src/intel/ds/intel_driver_ds.h
index 52c5a436d5c..004864d622c 100644
--- a/src/intel/ds/intel_driver_ds.h
+++ b/src/intel/ds/intel_driver_ds.h
@@ -103,9 +103,24 @@ struct intel_ds_device {
    /* Unique perfetto identifier for the context */
    uint64_t iid;
 
-   /* Event ID generator */
+   /* Event ID generator (manipulate only inside
+    * IntelRenderpassDataSource::Trace)
+    */
    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 */
diff --git a/src/intel/ds/intel_tracepoints.py 
b/src/intel/ds/intel_tracepoints.py
index 8811f6db87e..71f13e9b097 100644
--- a/src/intel/ds/intel_tracepoints.py
+++ b/src/intel/ds/intel_tracepoints.py
@@ -57,6 +57,14 @@ def define_tracepoints(args):
                  tp_args=[Arg(type='uint8_t', var='level', c_format='%hhu'),],
                  end_pipelined=False)
 
+    # Annotations for Cmd(Begin|End)DebugUtilsLabelEXT
+    begin_end_tp('cmd_buffer_annotation',
+                 tp_args=[ArgStruct(type='unsigned', var='len'),
+                          ArgStruct(type='const char *', var='str'),],
+                 tp_struct=[Arg(type='uint8_t', name='dummy', var='0', 
c_format='%hhu'),
+                            Arg(type='char', name='str', var='str', 
c_format='%s', length_arg='len + 1', copy_func='strncpy'),],
+                 end_pipelined=True)
+
     begin_end_tp('xfb',
                  end_pipelined=False)
 
diff --git a/src/intel/vulkan/anv_utrace.c b/src/intel/vulkan/anv_utrace.c
index 1c2f0e4aca3..16728864f35 100644
--- a/src/intel/vulkan/anv_utrace.c
+++ b/src/intel/vulkan/anv_utrace.c
@@ -23,8 +23,11 @@
 
 #include "anv_private.h"
 
+#include "ds/intel_tracepoints.h"
 #include "perf/intel_perf.h"
 
+#include "vulkan/runtime/vk_common_entrypoints.h"
+
 static uint32_t
 command_buffers_count_utraces(struct anv_device *device,
                               uint32_t cmd_buffer_count,
@@ -332,3 +335,30 @@ anv_pipe_flush_bit_to_ds_stall_flag(enum anv_pipe_bits 
bits)
 
    return ret;
 }
+
+void anv_CmdBeginDebugUtilsLabelEXT(
+   VkCommandBuffer _commandBuffer,
+   const VkDebugUtilsLabelEXT *pLabelInfo)
+{
+   VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _commandBuffer);
+
+   vk_common_CmdBeginDebugUtilsLabelEXT(_commandBuffer, pLabelInfo);
+
+   trace_intel_begin_cmd_buffer_annotation(&cmd_buffer->trace);
+}
+
+void anv_CmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer)
+{
+   VK_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _commandBuffer);
+
+   if (cmd_buffer->vk.labels.size > 0) {
+      const VkDebugUtilsLabelEXT *label =
+         util_dynarray_top_ptr(&cmd_buffer->vk.labels, VkDebugUtilsLabelEXT);
+
+      trace_intel_end_cmd_buffer_annotation(&cmd_buffer->trace,
+                                            strlen(label->pLabelName),
+                                            label->pLabelName);
+   }
+
+   vk_common_CmdEndDebugUtilsLabelEXT(_commandBuffer);
+ }

Reply via email to