hasvk: Emit CS stall on INTEL_MEASURE timestamp
authorFelix DeGrood <felix.j.degrood@intel.com>
Wed, 4 Jan 2023 01:31:37 +0000 (01:31 +0000)
committerMarge Bot <emma+marge@anholt.net>
Wed, 4 Jan 2023 22:43:36 +0000 (22:43 +0000)
For INTEL_MEASURE, ensure all prior instructions completed before
timestamp taken. Continue to support no CS flush case for Perfetto.
CS stall was dropped from pipecontrol when adding u_trace support.

Fixes: cc5843a573b ("anv: implement u_trace support")
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20502>

src/intel/vulkan_hasvk/anv_genX.h
src/intel/vulkan_hasvk/anv_measure.c
src/intel/vulkan_hasvk/anv_private.h
src/intel/vulkan_hasvk/anv_utrace.c
src/intel/vulkan_hasvk/genX_cmd_buffer.c

index aba6096..ce2c9ae 100644 (file)
@@ -136,7 +136,7 @@ void genX(blorp_exec)(struct blorp_batch *batch,
 void genX(cmd_emit_timestamp)(struct anv_batch *batch,
                               struct anv_device *device,
                               struct anv_address addr,
-                              bool end_of_pipe);
+                              enum anv_timestamp_capture_type);
 
 void
 genX(rasterization_mode)(VkPolygonMode raster_mode,
index ebeeb3b..ddc3c51 100644 (file)
@@ -150,7 +150,7 @@ anv_measure_start_snapshot(struct anv_cmd_buffer *cmd_buffer,
                                  (struct anv_address) {
                                     .bo = measure->bo,
                                     .offset = index * sizeof(uint64_t) },
-                                 true /* end_of_pipe */);
+                                 ANV_TIMESTAMP_CAPTURE_AT_CS_STALL);
 
    if (event_name == NULL)
       event_name = intel_measure_snapshot_string(type);
@@ -191,7 +191,7 @@ anv_measure_end_snapshot(struct anv_cmd_buffer *cmd_buffer,
                                  (struct anv_address) {
                                     .bo = measure->bo,
                                     .offset = index * sizeof(uint64_t) },
-                                 true /* end_of_pipe */);
+                                 ANV_TIMESTAMP_CAPTURE_AT_CS_STALL);
 
    struct intel_measure_snapshot *snapshot = &(measure->base.snapshots[index]);
    memset(snapshot, 0, sizeof(*snapshot));
index 88abb06..24f7475 100644 (file)
@@ -898,6 +898,12 @@ struct anv_memregion {
    uint64_t available;
 };
 
+enum anv_timestamp_capture_type {
+    ANV_TIMESTAMP_CAPTURE_TOP_OF_PIPE,
+    ANV_TIMESTAMP_CAPTURE_END_OF_PIPE,
+    ANV_TIMESTAMP_CAPTURE_AT_CS_STALL,
+};
+
 struct anv_physical_device {
     struct vk_physical_device                   vk;
 
@@ -987,7 +993,7 @@ struct anv_physical_device {
     int64_t                                     master_minor;
     struct intel_query_engine_info *            engine_info;
 
-    void (*cmd_emit_timestamp)(struct anv_batch *, struct anv_device *, struct anv_address, bool);
+    void (*cmd_emit_timestamp)(struct anv_batch *, struct anv_device *, struct anv_address, enum anv_timestamp_capture_type);
     struct intel_measure_device                 measure_device;
 };
 
index 898c918..3e347ec 100644 (file)
@@ -227,11 +227,14 @@ anv_utrace_record_ts(struct u_trace *ut, void *cs,
    struct anv_device *device = cmd_buffer->device;
    struct anv_bo *bo = timestamps;
 
+   enum anv_timestamp_capture_type capture_type =
+      (end_of_pipe) ? ANV_TIMESTAMP_CAPTURE_END_OF_PIPE
+                    : ANV_TIMESTAMP_CAPTURE_TOP_OF_PIPE;
    device->physical->cmd_emit_timestamp(&cmd_buffer->batch, device,
                                         (struct anv_address) {
                                            .bo = bo,
                                            .offset = idx * sizeof(uint64_t) },
-                                        end_of_pipe);
+                                        capture_type);
 }
 
 static uint64_t
index 984ae42..b04c141 100644 (file)
@@ -6032,16 +6032,33 @@ VkResult genX(CmdSetPerformanceStreamMarkerINTEL)(
 void genX(cmd_emit_timestamp)(struct anv_batch *batch,
                               struct anv_device *device,
                               struct anv_address addr,
-                              bool end_of_pipe) {
-   if (end_of_pipe) {
+                              enum anv_timestamp_capture_type type) {
+   switch (type) {
+   case ANV_TIMESTAMP_CAPTURE_TOP_OF_PIPE: {
+      struct mi_builder b;
+      mi_builder_init(&b, device->info, batch);
+      mi_store(&b, mi_mem64(addr), mi_reg64(TIMESTAMP));
+      break;
+   }
+
+   case ANV_TIMESTAMP_CAPTURE_END_OF_PIPE:
       anv_batch_emit(batch, GENX(PIPE_CONTROL), pc) {
          pc.PostSyncOperation   = WriteTimestamp;
          pc.Address             = addr;
          anv_debug_dump_pc(pc);
       }
-   } else {
-      struct mi_builder b;
-      mi_builder_init(&b, device->info, batch);
-      mi_store(&b, mi_mem64(addr), mi_reg64(TIMESTAMP));
+      break;
+
+   case ANV_TIMESTAMP_CAPTURE_AT_CS_STALL:
+      anv_batch_emit(batch, GENX(PIPE_CONTROL), pc) {
+         pc.CommandStreamerStallEnable = true;
+         pc.PostSyncOperation    = WriteTimestamp;
+         pc.Address              = addr;
+         anv_debug_dump_pc(pc);
+      }
+      break;
+
+   default:
+      unreachable("invalid");
    }
 }