From cd9d9e2436a0815f6ed3a61d2cdf8fad53278506 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 21 Jan 2010 14:59:01 -0700 Subject: llvmpipe: added simple perf/statistics counting facility Currently counting number of tris, how many tiles of each size are fully covered, partially covered or empty, etc. Set LP_DEBUG=counters to enable. Results are printed upon context destruction. --- src/gallium/drivers/llvmpipe/Makefile | 1 + src/gallium/drivers/llvmpipe/SConscript | 1 + src/gallium/drivers/llvmpipe/lp_context.c | 5 ++ src/gallium/drivers/llvmpipe/lp_debug.h | 1 + src/gallium/drivers/llvmpipe/lp_perf.c | 86 +++++++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_perf.h | 74 +++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast_tri.c | 6 ++ src/gallium/drivers/llvmpipe/lp_screen.c | 1 + src/gallium/drivers/llvmpipe/lp_setup.c | 2 +- src/gallium/drivers/llvmpipe/lp_setup.h | 2 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 16 ++++-- 11 files changed, 189 insertions(+), 6 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_perf.c create mode 100644 src/gallium/drivers/llvmpipe/lp_perf.h (limited to 'src') diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 666aa7293e..899af6acf8 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -36,6 +36,7 @@ C_SOURCES = \ lp_fence.c \ lp_flush.c \ lp_jit.c \ + lp_perf.c \ lp_query.c \ lp_rast.c \ lp_rast_tri.c \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index c4e7a4a22f..d7a396292c 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -52,6 +52,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_fence.c', 'lp_flush.c', 'lp_jit.c', + 'lp_perf.c', 'lp_query.c', 'lp_rast.c', 'lp_rast_tri.c', diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index c5b00f8e23..51de6f93ca 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -38,6 +38,7 @@ #include "lp_clear.h" #include "lp_context.h" #include "lp_flush.h" +#include "lp_perf.h" #include "lp_state.h" #include "lp_surface.h" #include "lp_texture.h" @@ -54,6 +55,8 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); uint i; + lp_print_counters(); + /* This will also destroy llvmpipe->setup: */ if (llvmpipe->draw) @@ -195,6 +198,8 @@ llvmpipe_create( struct pipe_screen *screen ) lp_init_surface_functions(llvmpipe); + lp_reset_counters(); + return &llvmpipe->pipe; fail: diff --git a/src/gallium/drivers/llvmpipe/lp_debug.h b/src/gallium/drivers/llvmpipe/lp_debug.h index 7128e8eb4b..7e04bd471e 100644 --- a/src/gallium/drivers/llvmpipe/lp_debug.h +++ b/src/gallium/drivers/llvmpipe/lp_debug.h @@ -47,6 +47,7 @@ st_print_current(void); #define DEBUG_JIT 0x100 #define DEBUG_SHOW_TILES 0x200 #define DEBUG_SHOW_SUBTILES 0x400 +#define DEBUG_COUNTERS 0x800 #ifdef DEBUG diff --git a/src/gallium/drivers/llvmpipe/lp_perf.c b/src/gallium/drivers/llvmpipe/lp_perf.c new file mode 100644 index 0000000000..2628d51069 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_perf.c @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_debug.h" +#include "lp_debug.h" +#include "lp_perf.h" + + + +struct lp_counters lp_count; + + +void +lp_reset_counters(void) +{ + memset(&lp_count, 0, sizeof(lp_count)); +} + + +void +lp_print_counters(void) +{ + if (LP_DEBUG & DEBUG_COUNTERS) { + unsigned total_64, total_16, total_4; + float p1, p2, p3; + + debug_printf("llvmpipe: nr_triangles: %9u\n", lp_count.nr_tris); + debug_printf("llvmpipe: nr_culled_triangles: %9u\n", lp_count.nr_culled_tris); + + total_64 = (lp_count.nr_empty_64 + + lp_count.nr_fully_covered_64 + + lp_count.nr_partially_covered_64); + + p1 = 100.0 * (float) lp_count.nr_empty_64 / (float) total_64; + p2 = 100.0 * (float) lp_count.nr_fully_covered_64 / (float) total_64; + p3 = 100.0 * (float) lp_count.nr_partially_covered_64 / (float) total_64; + + debug_printf("llvmpipe: nr_empty_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_64, p1, total_64); + debug_printf("llvmpipe: nr_fully_covered_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_64, p2, total_64); + debug_printf("llvmpipe: nr_partially_covered_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_64, p3, total_64); + + total_16 = (lp_count.nr_empty_16 + + lp_count.nr_fully_covered_16 + + lp_count.nr_partially_covered_16); + + p1 = 100.0 * (float) lp_count.nr_empty_16 / (float) total_16; + p2 = 100.0 * (float) lp_count.nr_fully_covered_16 / (float) total_16; + p3 = 100.0 * (float) lp_count.nr_partially_covered_16 / (float) total_16; + + debug_printf("llvmpipe: nr_empty_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_16, p1, total_16); + debug_printf("llvmpipe: nr_fully_covered_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_16, p2, total_16); + debug_printf("llvmpipe: nr_partially_covered_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_16, p3, total_16); + + total_4 = (lp_count.nr_empty_4 + lp_count.nr_non_empty_4); + + p1 = 100.0 * (float) lp_count.nr_empty_4 / (float) total_4; + p2 = 100.0 * (float) lp_count.nr_non_empty_4 / (float) total_4; + + debug_printf("llvmpipe: nr_empty_4x4: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_4, p1, total_4); + debug_printf("llvmpipe: nr_non_empty_4x4: %9u (%2.0f%% of %u)\n", lp_count.nr_non_empty_4, p2, total_4); + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_perf.h b/src/gallium/drivers/llvmpipe/lp_perf.h new file mode 100644 index 0000000000..9886088c38 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_perf.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Performance / statistic counters, etc. + */ + + +#ifndef LP_PERF_H +#define LP_PERF_H + + +/** + * Various counters + */ +struct lp_counters +{ + unsigned nr_tris; + unsigned nr_culled_tris; + unsigned nr_empty_64; + unsigned nr_fully_covered_64; + unsigned nr_partially_covered_64; + unsigned nr_empty_16; + unsigned nr_fully_covered_16; + unsigned nr_partially_covered_16; + unsigned nr_empty_4; + unsigned nr_non_empty_4; +}; + + +extern struct lp_counters lp_count; + + +/** Increment the named counter (only for debug builds) */ +#ifdef DEBUG +#define LP_COUNT(counter) lp_count.counter++ +#else +#define LP_COUNT(counter) +#endif + + +extern void +lp_reset_counters(void); + + +extern void +lp_print_counters(void); + + +#endif /* LP_PERF_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index b3d1e7dee4..e9d15727a7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -32,6 +32,7 @@ #include #include "util/u_math.h" #include "lp_debug.h" +#include "lp_perf.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" @@ -167,6 +168,7 @@ do_block_16( struct lp_rasterizer_task *rast_task, cx2 + eo2 < 0 || cx3 + eo3 < 0) { /* the block is completely outside the triangle - nop */ + LP_COUNT(nr_empty_4); } else { int px = x + pos_table4[i][0]; @@ -174,6 +176,7 @@ do_block_16( struct lp_rasterizer_task *rast_task, /* Don't bother testing if the 4x4 block is entirely in/out of * the triangle. It's a little faster to do it in the jit code. */ + LP_COUNT(nr_non_empty_4); do_block_4(rast_task, tri, px, py, cx1, cx2, cx3); } } @@ -223,6 +226,7 @@ lp_rast_triangle( struct lp_rasterizer *rast, cx2 + eo2 < 0 || cx3 + eo3 < 0) { /* the block is completely outside the triangle - nop */ + LP_COUNT(nr_empty_16); } else { int px = x + pos_table16[i][0]; @@ -232,10 +236,12 @@ lp_rast_triangle( struct lp_rasterizer *rast, cx2 + ei2 > 0 && cx3 + ei3 > 0) { /* the block is completely inside the triangle */ + LP_COUNT(nr_fully_covered_16); block_full_16(rast_task, tri, px, py); } else { /* the block is partially in/out of the triangle */ + LP_COUNT(nr_partially_covered_16); do_block_16(rast_task, tri, px, py, cx1, cx2, cx3); } } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 72f2e8ebf8..9dd4ea7ef6 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -54,6 +54,7 @@ static const struct debug_named_value lp_debug_flags[] = { { "jit", DEBUG_JIT }, { "show_tiles", DEBUG_SHOW_TILES }, { "show_subtiles", DEBUG_SHOW_SUBTILES }, + { "counters", DEBUG_COUNTERS }, {NULL, 0} }; #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index d4a4724ad1..f8fc912fa1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -499,7 +499,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup, * Note: we have to check all scenes including any scenes currently * being rendered and the current scene being built. */ -boolean +unsigned lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 5081da29d1..0e155a7dc3 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -123,7 +123,7 @@ void lp_setup_set_sampler_textures( struct setup_context *setup, unsigned num, struct pipe_texture **texture); -boolean +unsigned lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 0d89bef606..76ecab7644 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -29,10 +29,11 @@ * Binning code for triangles */ -#include "lp_setup_context.h" -#include "lp_rast.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "lp_perf.h" +#include "lp_setup_context.h" +#include "lp_rast.h" #define NUM_CHANNELS 4 @@ -278,12 +279,15 @@ do_triangle_ccw(struct setup_context *setup, area = (tri->dx12 * tri->dy31 - tri->dx31 * tri->dy12); + LP_COUNT(nr_tris); + /* Cull non-ccw and zero-sized triangles. * * XXX: subject to overflow?? */ if (area <= 0.0f) { lp_scene_putback_data( scene, sizeof *tri ); + LP_COUNT(nr_culled_tris); return; } @@ -303,6 +307,7 @@ do_triangle_ccw(struct setup_context *setup, if (miny == maxy || minx == maxx) { lp_scene_putback_data( scene, sizeof *tri ); + LP_COUNT(nr_culled_tris); return; } @@ -459,6 +464,7 @@ do_triangle_ccw(struct setup_context *setup, cx3 + eo3 < 0) { /* do nothing */ + LP_COUNT(nr_empty_64); if (in) break; /* exiting triangle, all done with this row */ } @@ -466,8 +472,9 @@ do_triangle_ccw(struct setup_context *setup, cx2 + ei2 > 0 && cx3 + ei3 > 0) { - in = TRUE; /* triangle covers the whole tile- shade whole tile */ + LP_COUNT(nr_fully_covered_64); + in = TRUE; if(setup->fs.current.opaque) { lp_scene_bin_reset( scene, x, y ); lp_scene_bin_command( scene, x, y, @@ -480,8 +487,9 @@ do_triangle_ccw(struct setup_context *setup, } else { + /* rasterizer/shade partial tile */ + LP_COUNT(nr_partially_covered_64); in = TRUE; - /* shade partial tile */ lp_scene_bin_command( scene, x, y, lp_rast_triangle, lp_rast_arg_triangle(tri) ); -- cgit v1.2.3