Mesa (lp-binning): llvmpipe: added simple perf/statistics counting facility

Brian Paul brianp at kemper.freedesktop.org
Fri Jan 22 02:10:47 UTC 2010


Module: Mesa
Branch: lp-binning
Commit: cd9d9e2436a0815f6ed3a61d2cdf8fad53278506
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=cd9d9e2436a0815f6ed3a61d2cdf8fad53278506

Author: Brian Paul <brianp at vmware.com>
Date:   Thu Jan 21 14:59:01 2010 -0700

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(-)

diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 666aa72..899af6a 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 c4e7a4a..d7a3962 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 c5b00f8..51de6f9 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 7128e8e..7e04bd4 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 0000000..2628d51
--- /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 0000000..9886088
--- /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 b3d1e7d..e9d1572 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c
@@ -32,6 +32,7 @@
 #include <limits.h>
 #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 72f2e8e..9dd4ea7 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 d4a4724..f8fc912 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 5081da2..0e155a7 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 0d89bef..76ecab7 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) );




More information about the mesa-commit mailing list