radv: add new start/stop sqtt helpers for capturing with SQTT

They will be also used for per-submit captures.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32370>
This commit is contained in:
Samuel Pitoiset 2024-11-27 09:24:33 +01:00 committed by Marge Bot
parent df52c70b8a
commit f3272f0044
3 changed files with 59 additions and 39 deletions

View file

@ -667,50 +667,18 @@ radv_handle_sqtt(VkQueue _queue)
{
VK_FROM_HANDLE(radv_queue, queue, _queue);
struct radv_device *device = radv_queue_device(queue);
const struct radv_physical_device *pdev = radv_device_physical(device);
bool trigger = device->sqtt_triggered;
device->sqtt_triggered = false;
if (device->sqtt_enabled) {
struct ac_sqtt_trace sqtt_trace = {0};
struct ac_spm_trace spm_trace;
radv_end_sqtt(queue);
device->sqtt_enabled = false;
/* TODO: Do something better than this whole sync. */
device->vk.dispatch_table.QueueWaitIdle(_queue);
if (radv_get_sqtt_trace(queue, &sqtt_trace) && (!device->spm.bo || radv_get_spm_trace(queue, &spm_trace))) {
ac_dump_rgp_capture(&pdev->info, &sqtt_trace, device->spm.bo ? &spm_trace : NULL);
} else {
/* Trigger a new capture if the driver failed to get
* the trace because the buffer was too small.
*/
if (!radv_sqtt_stop_capturing(queue)) {
/* Try to capture the next frame if the buffer was too small initially. */
trigger = true;
}
/* Clear resources used for this capture. */
radv_reset_sqtt_trace(device);
}
if (trigger) {
if (ac_check_profile_state(&pdev->info)) {
fprintf(stderr, "radv: Canceling RGP trace request as a hang condition has been "
"detected. Force the GPU into a profiling mode with e.g. "
"\"echo profile_peak > "
"/sys/class/drm/card0/device/power_dpm_force_performance_level\"\n");
return;
}
/* Sample CPU/GPU clocks before starting the trace. */
if (!radv_sqtt_sample_clocks(device)) {
fprintf(stderr, "radv: Failed to sample clocks\n");
}
radv_begin_sqtt(queue);
assert(!device->sqtt_enabled);
device->sqtt_enabled = true;
radv_sqtt_start_capturing(queue);
}
}

View file

@ -498,7 +498,7 @@ radv_sqtt_resize_bo(struct radv_device *device)
return radv_sqtt_init_bo(device);
}
bool
static bool
radv_begin_sqtt(struct radv_queue *queue)
{
struct radv_device *device = radv_queue_device(queue);
@ -572,7 +572,7 @@ radv_begin_sqtt(struct radv_queue *queue)
return radv_queue_internal_submit(queue, cs);
}
bool
static bool
radv_end_sqtt(struct radv_queue *queue)
{
struct radv_device *device = radv_queue_device(queue);
@ -638,6 +638,58 @@ radv_end_sqtt(struct radv_queue *queue)
return radv_queue_internal_submit(queue, cs);
}
void
radv_sqtt_start_capturing(struct radv_queue *queue)
{
struct radv_device *device = radv_queue_device(queue);
const struct radv_physical_device *pdev = radv_device_physical(device);
if (ac_check_profile_state(&pdev->info)) {
fprintf(stderr, "radv: Canceling RGP trace request as a hang condition has been "
"detected. Force the GPU into a profiling mode with e.g. "
"\"echo profile_peak > "
"/sys/class/drm/card0/device/power_dpm_force_performance_level\"\n");
return;
}
/* Sample CPU/GPU clocks before starting the trace. */
if (!radv_sqtt_sample_clocks(device)) {
fprintf(stderr, "radv: Failed to sample clocks\n");
}
radv_begin_sqtt(queue);
assert(!device->sqtt_enabled);
device->sqtt_enabled = true;
}
bool
radv_sqtt_stop_capturing(struct radv_queue *queue)
{
struct radv_device *device = radv_queue_device(queue);
const struct radv_physical_device *pdev = radv_device_physical(device);
struct ac_sqtt_trace sqtt_trace = {0};
struct ac_spm_trace spm_trace;
bool captured = true;
radv_end_sqtt(queue);
device->sqtt_enabled = false;
/* TODO: Do something better than this whole sync. */
device->vk.dispatch_table.QueueWaitIdle(radv_queue_to_handle(queue));
if (radv_get_sqtt_trace(queue, &sqtt_trace) && (!device->spm.bo || radv_get_spm_trace(queue, &spm_trace))) {
ac_dump_rgp_capture(&pdev->info, &sqtt_trace, device->spm.bo ? &spm_trace : NULL);
} else {
/* Failed to capture because the buffer was too small. */
captured = false;
}
/* Clear resources used for this capture. */
radv_reset_sqtt_trace(device);
return captured;
}
bool
radv_get_sqtt_trace(struct radv_queue *queue, struct ac_sqtt_trace *sqtt_trace)
{

View file

@ -75,9 +75,9 @@ bool radv_sqtt_init(struct radv_device *device);
void radv_sqtt_finish(struct radv_device *device);
bool radv_begin_sqtt(struct radv_queue *queue);
void radv_sqtt_start_capturing(struct radv_queue *queue);
bool radv_end_sqtt(struct radv_queue *queue);
bool radv_sqtt_stop_capturing(struct radv_queue *queue);
bool radv_get_sqtt_trace(struct radv_queue *queue, struct ac_sqtt_trace *sqtt_trace);