No measurable overhead when off (glxgears within 0.5%). v2: Cosmetic changes. v3: Moved file handling into winsys
Signed-off-by: Lauri Kasanen <c...@gmx.com> --- src/gallium/drivers/radeon/r600_pipe_common.c | 5 ++++ src/gallium/drivers/radeon/r600_pipe_common.h | 1 + src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 16 +++++++++++ src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 9 ++++++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 35 +++++++++++++++++++++++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 2 ++ src/gallium/winsys/radeon/drm/radeon_winsys.h | 5 ++++ 7 files changed, 73 insertions(+) diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 28921be..f2a5794 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -38,6 +38,7 @@ static const struct debug_named_value common_debug_options[] = { { "compute", DBG_COMPUTE, "Print compute info" }, { "vm", DBG_VM, "Print virtual addresses when creating resources" }, { "trace_cs", DBG_TRACE_CS, "Trace cs and write rlockup_<csid>.c file with faulty cs" }, + { "bostats", DBG_BO_STATS, "Write bo statistics to /tmp/bostats.<pid>[.name]" }, /* shaders */ { "fs", DBG_FS, "Print fetch shaders" }, @@ -209,6 +210,10 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen, return false; } + if (rscreen->debug_flags & DBG_BO_STATS) { + ws->enable_bo_stats(ws); + } + util_format_s3tc_init(); pipe_mutex_init(rscreen->aux_context_lock); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index bf0b968..4c35e66 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -67,6 +67,7 @@ #define DBG_COMPUTE (1 << 2) #define DBG_VM (1 << 3) #define DBG_TRACE_CS (1 << 4) +#define DBG_BO_STATS (1 << 5) /* shaders */ #define DBG_FS (1 << 8) #define DBG_VS (1 << 9) diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index ca569a1..ea99351 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -370,6 +370,7 @@ static void radeon_bo_destroy(struct pb_buffer *_buf) { struct radeon_bo *bo = radeon_bo(_buf); struct radeon_bomgr *mgr = bo->mgr; + struct radeon_drm_winsys *ws = mgr->rws; struct drm_gem_close args; memset(&args, 0, sizeof(args)); @@ -399,6 +400,11 @@ static void radeon_bo_destroy(struct pb_buffer *_buf) bo->rws->allocated_vram -= align(bo->base.size, 4096); else if (bo->initial_domain & RADEON_DOMAIN_GTT) bo->rws->allocated_gtt -= align(bo->base.size, 4096); + + if (ws->bo_stats_file) { + fprintf(ws->bo_stats_file, "%p destroyed @%llu\n", bo, stats_time_get(ws)); + } + FREE(bo); } @@ -450,6 +456,7 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf, { struct radeon_bo *bo = (struct radeon_bo*)buf; struct radeon_drm_cs *cs = (struct radeon_drm_cs*)rcs; + struct radeon_drm_winsys *ws = bo->mgr->rws; /* If it's not unsynchronized bo_map, flush CS if needed and then wait. */ if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { @@ -518,6 +525,10 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf, } } + if (ws->bo_stats_file) { + fprintf(ws->bo_stats_file, "%p cpu mapped @%llu\n", bo, stats_time_get(ws)); + } + return radeon_bo_do_map(bo); } @@ -636,6 +647,11 @@ static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr, else if (rdesc->initial_domains & RADEON_DOMAIN_GTT) rws->allocated_gtt += align(size, 4096); + if (rws->bo_stats_file) { + fprintf(rws->bo_stats_file, "%p created, size %u, prio %u, @%llu\n", bo, size, + bo->stats.high_prio, stats_time_get(rws)); + } + return &bo->base; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index d8ad297..845603d 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -344,6 +344,7 @@ static unsigned radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs, { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_bo *bo = (struct radeon_bo*)buf; + struct radeon_drm_winsys *ws = cs->ws; enum radeon_bo_domain added_domains; unsigned index = radeon_add_reloc(cs, bo, usage, domains, &added_domains); @@ -352,6 +353,14 @@ static unsigned radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs, if (added_domains & RADEON_DOMAIN_VRAM) cs->csc->used_vram += bo->base.size; + if (ws->bo_stats_file) { + if (usage & RADEON_USAGE_WRITE) { + fprintf(ws->bo_stats_file, "%p write @%llu\n", bo, stats_time_get(ws)); + } else { + fprintf(ws->bo_stats_file, "%p read @%llu\n", bo, stats_time_get(ws)); + } + } + return index; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 7bedf92..bb17a21 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -45,6 +45,13 @@ #include <sys/stat.h> #include <unistd.h> +#ifdef __GLIBC__ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <errno.h> +#endif + /* * this are copy from radeon_drm, once an updated libdrm is released * we should bump configure.ac requirement for it and remove the following @@ -445,6 +452,12 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws) ws->kill_timing_thread = 1; pipe_thread_wait(ws->timing_thread); + if (ws->bo_stats_file) { + fflush(ws->bo_stats_file); + fclose(ws->bo_stats_file); + ws->bo_stats_file = NULL; + } + pipe_mutex_destroy(ws->hyperz_owner_mutex); pipe_mutex_destroy(ws->cmask_owner_mutex); pipe_mutex_destroy(ws->cs_stack_lock); @@ -530,6 +543,27 @@ static uint64_t radeon_query_value(struct radeon_winsys *rws, return 0; } +static void radeon_enable_bo_stats(struct radeon_winsys *rws) +{ + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; + + char statsfile[80]; + const pid_t pid = getpid(); + +#ifdef __GLIBC__ + snprintf(statsfile, 80, "/tmp/bostats.%u.%s", pid, program_invocation_short_name); +#else + snprintf(statsfile, 80, "/tmp/bostats.%u", pid); +#endif + + ws->bo_stats_file = fopen(statsfile, "w"); + if (!ws->bo_stats_file) + fprintf(stderr, "Failed to open bo stats file %s\n", statsfile); + else + fprintf(ws->bo_stats_file, "started @%llu\n", + stats_time_get(ws)); +} + static unsigned hash_fd(void *key) { int fd = pointer_to_intptr(key); @@ -666,6 +700,7 @@ PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd) ws->base.surface_init = radeon_drm_winsys_surface_init; ws->base.surface_best = radeon_drm_winsys_surface_best; ws->base.query_value = radeon_query_value; + ws->base.enable_bo_stats = radeon_enable_bo_stats; radeon_bomgr_init_functions(ws); radeon_drm_cs_init_functions(ws); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h index 01c2d9c..7d93960 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h @@ -77,6 +77,8 @@ struct radeon_drm_winsys { pipe_thread timing_thread; int kill_timing_thread; uint64_t time; + + FILE *bo_stats_file; }; static INLINE struct radeon_drm_winsys * diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 55f60d3..bee22f8 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -536,6 +536,11 @@ struct radeon_winsys { uint64_t (*query_value)(struct radeon_winsys *ws, enum radeon_value_id value); + + /** + * Enable bo statistics logging. + */ + void (*enable_bo_stats)(struct radeon_winsys *ws); }; /** -- 1.8.3.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev