[Mesa-dev] [PATCH 6/6] gallium/radeon: add GPU-shaders-busy HUD query
Nicolai Hähnle
nhaehnle at gmail.com
Mon Jan 16 08:57:20 UTC 2017
This series is:
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
On 16.01.2017 03:00, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> It should be close to the GPU load, but it can be much lower if something
> is stalling shader execution (e.g. CP DMA).
> ---
> src/gallium/drivers/radeon/r600_gpu_load.c | 16 ++++++++++++++++
> src/gallium/drivers/radeon/r600_pipe_common.h | 4 ++++
> src/gallium/drivers/radeon/r600_query.c | 11 ++++++++++-
> src/gallium/drivers/radeon/r600_query.h | 1 +
> 4 files changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_gpu_load.c b/src/gallium/drivers/radeon/r600_gpu_load.c
> index 764d9b5..e3488b3 100644
> --- a/src/gallium/drivers/radeon/r600_gpu_load.c
> +++ b/src/gallium/drivers/radeon/r600_gpu_load.c
> @@ -35,29 +35,35 @@
> */
>
> #include "r600_pipe_common.h"
> #include "os/os_time.h"
>
> /* For good accuracy at 1000 fps or lower. This will be inaccurate for higher
> * fps (there are too few samples per frame). */
> #define SAMPLES_PER_SEC 10000
>
> #define GRBM_STATUS 0x8010
> +#define SPI_BUSY(x) (((x) >> 22) & 0x1)
> #define GUI_ACTIVE(x) (((x) >> 31) & 0x1)
>
> static void r600_update_grbm_counters(struct r600_common_screen *rscreen,
> union r600_grbm_counters *counters)
> {
> uint32_t value = 0;
>
> rscreen->ws->read_registers(rscreen->ws, GRBM_STATUS, 1, &value);
>
> + if (SPI_BUSY(value))
> + p_atomic_inc(&counters->named.spi_busy);
> + else
> + p_atomic_inc(&counters->named.spi_idle);
> +
> if (GUI_ACTIVE(value))
> p_atomic_inc(&counters->named.gui_busy);
> else
> p_atomic_inc(&counters->named.gui_idle);
> }
>
> static PIPE_THREAD_ROUTINE(r600_gpu_load_thread, param)
> {
> struct r600_common_screen *rscreen = (struct r600_common_screen*)param;
> const int period_us = 1000000 / SAMPLES_PER_SEC;
> @@ -137,19 +143,29 @@ static unsigned r600_end_counter(struct r600_common_screen *rscreen,
>
> memset(&counters, 0, sizeof(counters));
> r600_update_grbm_counters(rscreen, &counters);
> return counters.array[busy_index] ? 100 : 0;
> }
> }
>
> #define BUSY_INDEX(rscreen, field) (&rscreen->grbm_counters.named.field##_busy - \
> rscreen->grbm_counters.array)
>
> +uint64_t r600_begin_counter_spi(struct r600_common_screen *rscreen)
> +{
> + return r600_read_counter(rscreen, BUSY_INDEX(rscreen, spi));
> +}
> +
> +unsigned r600_end_counter_spi(struct r600_common_screen *rscreen, uint64_t begin)
> +{
> + return r600_end_counter(rscreen, begin, BUSY_INDEX(rscreen, spi));
> +}
> +
> uint64_t r600_begin_counter_gui(struct r600_common_screen *rscreen)
> {
> return r600_read_counter(rscreen, BUSY_INDEX(rscreen, gui));
> }
>
> unsigned r600_end_counter_gui(struct r600_common_screen *rscreen, uint64_t begin)
> {
> return r600_end_counter(rscreen, begin, BUSY_INDEX(rscreen, gui));
> }
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index 9f69298..97e9441 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -347,20 +347,22 @@ struct r600_surface {
> unsigned db_stencil_base; /* EG and later */
> unsigned db_stencil_info; /* EG and later */
> unsigned db_prefetch_limit; /* R600 only */
> unsigned db_htile_surface;
> unsigned db_htile_data_base;
> unsigned db_preload_control; /* EG and later */
> };
>
> union r600_grbm_counters {
> struct {
> + unsigned spi_busy;
> + unsigned spi_idle;
> unsigned gui_busy;
> unsigned gui_idle;
> } named;
> unsigned array[0];
> };
>
> struct r600_common_screen {
> struct pipe_screen b;
> struct radeon_winsys *ws;
> enum radeon_family family;
> @@ -739,20 +741,22 @@ struct pipe_resource *r600_resource_create_common(struct pipe_screen *screen,
> const char *r600_get_llvm_processor_name(enum radeon_family family);
> void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw,
> struct r600_resource *dst, struct r600_resource *src);
> void radeon_save_cs(struct radeon_winsys *ws, struct radeon_winsys_cs *cs,
> struct radeon_saved_cs *saved);
> void radeon_clear_saved_cs(struct radeon_saved_cs *saved);
> bool r600_check_device_reset(struct r600_common_context *rctx);
>
> /* r600_gpu_load.c */
> void r600_gpu_load_kill_thread(struct r600_common_screen *rscreen);
> +uint64_t r600_begin_counter_spi(struct r600_common_screen *rscreen);
> +unsigned r600_end_counter_spi(struct r600_common_screen *rscreen, uint64_t begin);
> uint64_t r600_begin_counter_gui(struct r600_common_screen *rscreen);
> unsigned r600_end_counter_gui(struct r600_common_screen *rscreen, uint64_t begin);
>
> /* r600_perfcounters.c */
> void r600_perfcounters_destroy(struct r600_common_screen *rscreen);
>
> /* r600_query.c */
> void r600_init_screen_query_functions(struct r600_common_screen *rscreen);
> void r600_query_init(struct r600_common_context *rctx);
> void r600_suspend_queries(struct r600_common_context *ctx);
> diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c
> index b7fbd37..5712cbe 100644
> --- a/src/gallium/drivers/radeon/r600_query.c
> +++ b/src/gallium/drivers/radeon/r600_query.c
> @@ -140,20 +140,23 @@ static bool r600_query_sw_begin(struct r600_common_context *rctx,
> case R600_QUERY_NUM_SDMA_IBS:
> case R600_QUERY_NUM_BYTES_MOVED:
> case R600_QUERY_NUM_EVICTIONS: {
> enum radeon_value_id ws_id = winsys_id_from_type(query->b.type);
> query->begin_result = rctx->ws->query_value(rctx->ws, ws_id);
> break;
> }
> case R600_QUERY_GPU_LOAD:
> query->begin_result = r600_begin_counter_gui(rctx->screen);
> break;
> + case R600_QUERY_GPU_SHADERS_BUSY:
> + query->begin_result = r600_begin_counter_spi(rctx->screen);
> + break;
> case R600_QUERY_NUM_COMPILATIONS:
> query->begin_result = p_atomic_read(&rctx->screen->num_compilations);
> break;
> case R600_QUERY_NUM_SHADERS_CREATED:
> query->begin_result = p_atomic_read(&rctx->screen->num_shaders_created);
> break;
> case R600_QUERY_NUM_SHADER_CACHE_HITS:
> query->begin_result =
> p_atomic_read(&rctx->screen->num_shader_cache_hits);
> break;
> @@ -233,20 +236,25 @@ static bool r600_query_sw_end(struct r600_common_context *rctx,
> case R600_QUERY_NUM_EVICTIONS: {
> enum radeon_value_id ws_id = winsys_id_from_type(query->b.type);
> query->end_result = rctx->ws->query_value(rctx->ws, ws_id);
> break;
> }
> case R600_QUERY_GPU_LOAD:
> query->end_result = r600_end_counter_gui(rctx->screen,
> query->begin_result);
> query->begin_result = 0;
> break;
> + case R600_QUERY_GPU_SHADERS_BUSY:
> + query->end_result = r600_end_counter_spi(rctx->screen,
> + query->begin_result);
> + query->begin_result = 0;
> + break;
> case R600_QUERY_NUM_COMPILATIONS:
> query->end_result = p_atomic_read(&rctx->screen->num_compilations);
> break;
> case R600_QUERY_NUM_SHADERS_CREATED:
> query->end_result = p_atomic_read(&rctx->screen->num_shaders_created);
> break;
> case R600_QUERY_BACK_BUFFER_PS_DRAW_RATIO:
> query->end_result = rctx->last_tex_ps_draw_ratio;
> break;
> case R600_QUERY_NUM_SHADER_CACHE_HITS:
> @@ -1709,37 +1717,38 @@ static struct pipe_driver_query_info r600_driver_query_list[] = {
> * (and possibly their order as well). */
> XG(GPIN, "GPIN_000", GPIN_ASIC_ID, UINT, AVERAGE),
> XG(GPIN, "GPIN_001", GPIN_NUM_SIMD, UINT, AVERAGE),
> XG(GPIN, "GPIN_002", GPIN_NUM_RB, UINT, AVERAGE),
> XG(GPIN, "GPIN_003", GPIN_NUM_SPI, UINT, AVERAGE),
> XG(GPIN, "GPIN_004", GPIN_NUM_SE, UINT, AVERAGE),
>
> /* The following queries must be at the end of the list because their
> * availability is adjusted dynamically based on the DRM version. */
> X("GPU-load", GPU_LOAD, UINT64, AVERAGE),
> + X("GPU-shaders-busy", GPU_SHADERS_BUSY, UINT64, AVERAGE),
> X("temperature", GPU_TEMPERATURE, UINT64, AVERAGE),
> X("shader-clock", CURRENT_GPU_SCLK, HZ, AVERAGE),
> X("memory-clock", CURRENT_GPU_MCLK, HZ, AVERAGE),
> };
>
> #undef X
> #undef XG
> #undef XFULL
>
> static unsigned r600_get_num_queries(struct r600_common_screen *rscreen)
> {
> if (rscreen->info.drm_major == 2 && rscreen->info.drm_minor >= 42)
> return ARRAY_SIZE(r600_driver_query_list);
> else if (rscreen->info.drm_major == 3)
> return ARRAY_SIZE(r600_driver_query_list) - 3;
> else
> - return ARRAY_SIZE(r600_driver_query_list) - 4;
> + return ARRAY_SIZE(r600_driver_query_list) - 5;
> }
>
> static int r600_get_driver_query_info(struct pipe_screen *screen,
> unsigned index,
> struct pipe_driver_query_info *info)
> {
> struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
> unsigned num_queries = r600_get_num_queries(rscreen);
>
> if (!info) {
> diff --git a/src/gallium/drivers/radeon/r600_query.h b/src/gallium/drivers/radeon/r600_query.h
> index 3791ec6..43bca2b 100644
> --- a/src/gallium/drivers/radeon/r600_query.h
> +++ b/src/gallium/drivers/radeon/r600_query.h
> @@ -63,20 +63,21 @@ enum {
> R600_QUERY_NUM_GFX_IBS,
> R600_QUERY_NUM_SDMA_IBS,
> R600_QUERY_NUM_BYTES_MOVED,
> R600_QUERY_NUM_EVICTIONS,
> R600_QUERY_VRAM_USAGE,
> R600_QUERY_GTT_USAGE,
> R600_QUERY_GPU_TEMPERATURE,
> R600_QUERY_CURRENT_GPU_SCLK,
> R600_QUERY_CURRENT_GPU_MCLK,
> R600_QUERY_GPU_LOAD,
> + R600_QUERY_GPU_SHADERS_BUSY,
> R600_QUERY_NUM_COMPILATIONS,
> R600_QUERY_NUM_SHADERS_CREATED,
> R600_QUERY_BACK_BUFFER_PS_DRAW_RATIO,
> R600_QUERY_NUM_SHADER_CACHE_HITS,
> R600_QUERY_GPIN_ASIC_ID,
> R600_QUERY_GPIN_NUM_SIMD,
> R600_QUERY_GPIN_NUM_RB,
> R600_QUERY_GPIN_NUM_SPI,
> R600_QUERY_GPIN_NUM_SE,
>
>
More information about the mesa-dev
mailing list