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); +}
