From a2b6b6f1f9514e36a5f1cdd25c9b2e817fc957f4 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 26 Mar 2025 16:23:11 +0100 Subject: [PATCH] radv: add more helpers to start/stop perfcounters Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_perfcounter.c | 89 ++++++++++++++++++++----------- src/amd/vulkan/radv_perfcounter.h | 2 +- src/amd/vulkan/radv_sqtt.c | 4 +- 3 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/amd/vulkan/radv_perfcounter.c b/src/amd/vulkan/radv_perfcounter.c index 2fe6de8200a..3d5f7721703 100644 --- a/src/amd/vulkan/radv_perfcounter.c +++ b/src/amd/vulkan/radv_perfcounter.c @@ -41,20 +41,56 @@ radv_emit_windowed_counters(struct radv_device *device, struct radeon_cmdbuf *cs } void -radv_perfcounter_emit_spm_reset(struct radeon_cmdbuf *cs) +radv_perfcounter_emit_reset(struct radeon_cmdbuf *cs, bool is_spm) { - radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, - S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET) | - S_036020_SPM_PERFMON_STATE(V_036020_STRM_PERFMON_STATE_DISABLE_AND_RESET)); + uint32_t cp_perfmon_cntl; + + if (is_spm) { + cp_perfmon_cntl = S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET) | + S_036020_SPM_PERFMON_STATE(V_036020_STRM_PERFMON_STATE_DISABLE_AND_RESET); + } else { + cp_perfmon_cntl = S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET); + } + + radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, cp_perfmon_cntl); +} + +static void +radv_perfcounter_emit_start(struct radeon_cmdbuf *cs, bool is_spm) +{ + uint32_t cp_perfmon_cntl; + + if (is_spm) { + cp_perfmon_cntl = S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET) | + S_036020_SPM_PERFMON_STATE(V_036020_STRM_PERFMON_STATE_START_COUNTING); + } else { + cp_perfmon_cntl = S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_START_COUNTING); + } + + radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, cp_perfmon_cntl); +} + +static void +radv_perfcounter_emit_stop(struct radeon_cmdbuf *cs, bool is_spm) +{ + uint32_t cp_perfmon_cntl; + + if (is_spm) { + cp_perfmon_cntl = S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET) | + S_036020_SPM_PERFMON_STATE(V_036020_STRM_PERFMON_STATE_STOP_COUNTING); + } else { + cp_perfmon_cntl = + S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_STOP_COUNTING) | S_036020_PERFMON_SAMPLE_ENABLE(1); + } + + radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, cp_perfmon_cntl); } void radv_perfcounter_emit_spm_start(struct radv_device *device, struct radeon_cmdbuf *cs, int family) { /* Start SPM counters. */ - radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, - S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET) | - S_036020_SPM_PERFMON_STATE(V_036020_STRM_PERFMON_STATE_START_COUNTING)); + radv_perfcounter_emit_start(cs, true); radv_emit_windowed_counters(device, cs, family, true); } @@ -67,11 +103,17 @@ radv_perfcounter_emit_spm_stop(struct radv_device *device, struct radeon_cmdbuf radv_emit_windowed_counters(device, cs, family, false); /* Stop SPM counters. */ - radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, - S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET) | - S_036020_SPM_PERFMON_STATE(pdev->info.never_stop_sq_perf_counters - ? V_036020_STRM_PERFMON_STATE_START_COUNTING - : V_036020_STRM_PERFMON_STATE_STOP_COUNTING)); + if (pdev->info.never_stop_sq_perf_counters) { + radv_perfcounter_emit_start(cs, true); + } else { + radv_perfcounter_emit_stop(cs, true); + } +} + +static void +radv_perfcounter_emit_sample(struct radeon_cmdbuf *cs) +{ + radeon_event_write(cs, V_028A90_PERFCOUNTER_SAMPLE); } enum radv_perfcounter_op { @@ -555,16 +597,11 @@ radv_pc_stop_and_sample(struct radv_cmd_buffer *cmd_buffer, struct radv_pc_query const struct radv_physical_device *pdev = radv_device_physical(device); struct radeon_cmdbuf *cs = cmd_buffer->cs; - radeon_event_write(cs, V_028A90_PERFCOUNTER_SAMPLE); - + radv_perfcounter_emit_sample(cs); radv_pc_wait_idle(cmd_buffer); - radv_emit_instance(cmd_buffer, -1, -1); radv_emit_windowed_counters(device, cs, cmd_buffer->qf, false); - - radeon_set_uconfig_reg( - cs, R_036020_CP_PERFMON_CNTL, - S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_STOP_COUNTING) | S_036020_PERFMON_SAMPLE_ENABLE(1)); + radv_perfcounter_emit_stop(cs, false); for (unsigned pass = 0; pass < pool->num_passes; ++pass) { uint64_t pred_va = radv_buffer_get_va(device->perf_counter_bo) + PERF_CTR_BO_PASS_OFFSET + 8 * pass; @@ -632,10 +669,7 @@ radv_pc_begin_query(struct radv_cmd_buffer *cmd_buffer, struct radv_pc_query_poo radv_cs_write_data_imm(cs, V_370_ME, perf_ctr_va, 0); radv_pc_wait_idle(cmd_buffer); - - radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, - S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET)); - + radv_perfcounter_emit_reset(cs, false); radv_emit_inhibit_clockgating(device, cs, true); radv_emit_spi_config_cntl(device, cs, true); radv_perfcounter_emit_shaders(device, cs, 0x7f); @@ -676,10 +710,7 @@ radv_pc_begin_query(struct radv_cmd_buffer *cmd_buffer, struct radv_pc_query_poo /* The following sequence actually starts the perfcounters. */ radv_pc_stop_and_sample(cmd_buffer, pool, va, false); - - radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, - S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_START_COUNTING)); - + radv_perfcounter_emit_start(cs, false); radv_emit_windowed_counters(device, cs, cmd_buffer->qf, true); assert(cmd_buffer->cs->cdw <= cdw_max); @@ -708,9 +739,7 @@ radv_pc_end_query(struct radv_cmd_buffer *cmd_buffer, struct radv_pc_query_pool radv_pc_wait_idle(cmd_buffer); radv_pc_stop_and_sample(cmd_buffer, pool, va, true); - - radeon_set_uconfig_reg(cs, R_036020_CP_PERFMON_CNTL, - S_036020_PERFMON_STATE(V_036020_CP_PERFMON_STATE_DISABLE_AND_RESET)); + radv_perfcounter_emit_reset(cs, false); radv_emit_spi_config_cntl(device, cs, false); radv_emit_inhibit_clockgating(device, cs, false); diff --git a/src/amd/vulkan/radv_perfcounter.h b/src/amd/vulkan/radv_perfcounter.h index 4fce96ad4f0..f3ddf28cbe0 100644 --- a/src/amd/vulkan/radv_perfcounter.h +++ b/src/amd/vulkan/radv_perfcounter.h @@ -32,7 +32,7 @@ struct radv_pc_query_pool { void radv_perfcounter_emit_shaders(struct radv_device *device, struct radeon_cmdbuf *cs, unsigned shaders); -void radv_perfcounter_emit_spm_reset(struct radeon_cmdbuf *cs); +void radv_perfcounter_emit_reset(struct radeon_cmdbuf *cs, bool is_spm); void radv_perfcounter_emit_spm_start(struct radv_device *device, struct radeon_cmdbuf *cs, int family); diff --git a/src/amd/vulkan/radv_sqtt.c b/src/amd/vulkan/radv_sqtt.c index 97f3f5438cd..8f13f239e3f 100644 --- a/src/amd/vulkan/radv_sqtt.c +++ b/src/amd/vulkan/radv_sqtt.c @@ -544,7 +544,7 @@ radv_begin_sqtt(struct radv_queue *queue) /* Enable SQG events that collects thread trace data. */ radv_emit_spi_config_cntl(device, cs, true); - radv_perfcounter_emit_spm_reset(cs); + radv_perfcounter_emit_reset(cs, true); if (device->spm.bo) { /* Enable all shader stages by default. */ @@ -619,7 +619,7 @@ radv_end_sqtt(struct radv_queue *queue) /* Stop SQTT. */ radv_emit_sqtt_stop(device, cs, family); - radv_perfcounter_emit_spm_reset(cs); + radv_perfcounter_emit_reset(cs, true); /* Restore previous state by disabling SQG events. */ radv_emit_spi_config_cntl(device, cs, false);