gallium/radeon: add GPU-shaders-busy HUD query

It should be close to the GPU load, but it can be much lower if something
is stalling shader execution (e.g. CP DMA).

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
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
@@ -42,6 +42,7 @@
 #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,
@@ -51,6 +52,11 @@
 
 	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
@@ -144,6 +150,16 @@
 #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));
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
@@ -354,6 +354,8 @@
 
 union r600_grbm_counters {
 	struct {
+		unsigned spi_busy;
+		unsigned spi_idle;
 		unsigned gui_busy;
 		unsigned gui_idle;
 	} named;
@@ -746,6 +748,8 @@
 
 /* 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);
 
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
@@ -147,6 +147,9 @@
 	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;
@@ -240,6 +243,11 @@
 							 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;
@@ -1716,6 +1724,7 @@
 	/* 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),
@@ -1732,7 +1741,7 @@
 	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,
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
@@ -70,6 +70,7 @@
 	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,