From: Marek Olšák <marek.ol...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev