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

Author: Samuel Pitoiset <[email protected]>
Date:   Thu Apr 20 12:44:23 2023 +0200

radv/sqtt: sample CPU/GPU clocks before starting the trace

RGP seems to use that to calibrate timestamps. This also introduces
a new helper to reset thread data between captures.

Signed-off-by: Samuel Pitoiset <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22594>

---

 src/amd/vulkan/layers/radv_sqtt_layer.c |  8 +++++
 src/amd/vulkan/radv_private.h           |  2 ++
 src/amd/vulkan/radv_sqtt.c              | 61 +++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/src/amd/vulkan/layers/radv_sqtt_layer.c 
b/src/amd/vulkan/layers/radv_sqtt_layer.c
index 0f776427eba..01eae492742 100644
--- a/src/amd/vulkan/layers/radv_sqtt_layer.c
+++ b/src/amd/vulkan/layers/radv_sqtt_layer.c
@@ -554,6 +554,9 @@ radv_handle_thread_trace(VkQueue _queue)
           */
          resize_trigger = true;
       }
+
+      /* Clear resources used for this capture. */
+      radv_reset_thread_trace(queue->device);
    }
 
    if (!thread_trace_enabled) {
@@ -581,6 +584,11 @@ radv_handle_thread_trace(VkQueue _queue)
             return;
          }
 
+         /* Sample CPU/GPU clocks before starting the trace. */
+         if (!radv_thread_trace_sample_clocks(queue->device)) {
+            fprintf(stderr, "radv: Failed to sample clocks\n");
+         }
+
          radv_begin_thread_trace(queue);
          assert(!thread_trace_enabled);
          thread_trace_enabled = true;
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 8fa8165ad55..df0f21ee10c 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -3076,9 +3076,11 @@ void radv_thread_trace_finish(struct radv_device 
*device);
 bool radv_begin_thread_trace(struct radv_queue *queue);
 bool radv_end_thread_trace(struct radv_queue *queue);
 bool radv_get_thread_trace(struct radv_queue *queue, struct ac_thread_trace 
*thread_trace);
+void radv_reset_thread_trace(struct radv_device *device);
 void radv_emit_thread_trace_userdata(struct radv_cmd_buffer *cmd_buffer, const 
void *data,
                                      uint32_t num_dwords);
 bool radv_is_instruction_timing_enabled(void);
+bool radv_thread_trace_sample_clocks(struct radv_device *device);
 
 void radv_emit_inhibit_clockgating(struct radv_device *device, struct 
radeon_cmdbuf *cs,
                                    bool inhibit);
diff --git a/src/amd/vulkan/radv_sqtt.c b/src/amd/vulkan/radv_sqtt.c
index eeacdf2b723..6dbe378983e 100644
--- a/src/amd/vulkan/radv_sqtt.c
+++ b/src/amd/vulkan/radv_sqtt.c
@@ -793,3 +793,64 @@ radv_get_thread_trace(struct radv_queue *queue, struct 
ac_thread_trace *thread_t
    thread_trace->data = &device->thread_trace;
    return true;
 }
+
+void
+radv_reset_thread_trace(struct radv_device *device)
+{
+   struct ac_thread_trace_data *thread_trace_data = &device->thread_trace;
+   struct rgp_clock_calibration *clock_calibration = 
&thread_trace_data->rgp_clock_calibration;
+
+   /* Clear clock calibration records. */
+   simple_mtx_lock(&clock_calibration->lock);
+   list_for_each_entry_safe(struct rgp_clock_calibration_record, record, 
&clock_calibration->record,
+                            list)
+   {
+      clock_calibration->record_count--;
+      list_del(&record->list);
+      free(record);
+   }
+   simple_mtx_unlock(&clock_calibration->lock);
+}
+
+static VkResult
+radv_get_calibrated_timestamps(struct radv_device *device, uint64_t 
*cpu_timestamp,
+                               uint64_t *gpu_timestamp)
+{
+   uint64_t timestamps[2];
+   uint64_t max_deviation;
+   VkResult result;
+
+   const VkCalibratedTimestampInfoEXT timestamp_infos[2] = {
+      {
+         .sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT,
+         .timeDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+      },
+      {
+         .sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT,
+         .timeDomain = VK_TIME_DOMAIN_DEVICE_EXT,
+      }
+   };
+
+   result = radv_GetCalibratedTimestampsEXT(radv_device_to_handle(device), 2, 
timestamp_infos,
+                                            timestamps, &max_deviation);
+   if (result != VK_SUCCESS)
+      return result;
+
+   *cpu_timestamp = timestamps[0];
+   *gpu_timestamp = timestamps[1];
+
+   return result;
+}
+
+bool
+radv_thread_trace_sample_clocks(struct radv_device *device)
+{
+   uint64_t cpu_timestamp = 0, gpu_timestamp = 0;
+   VkResult result;
+
+   result = radv_get_calibrated_timestamps(device, &cpu_timestamp, 
&gpu_timestamp);
+   if (result != VK_SUCCESS)
+      return false;
+
+   return ac_sqtt_add_clock_calibration(&device->thread_trace, cpu_timestamp, 
gpu_timestamp);
+}

Reply via email to