[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