[Mesa-dev] [PATCH 6/6] gallium/radeon: add GPU-shaders-busy HUD query
Marek Olšák
maraeo at gmail.com
Mon Jan 16 02:00:06 UTC 2017
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,
--
2.7.4
More information about the mesa-dev
mailing list