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.
This commit is contained in:
@@ -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 \
|
||||
|
@@ -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',
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
86
src/gallium/drivers/llvmpipe/lp_perf.c
Normal file
86
src/gallium/drivers/llvmpipe/lp_perf.c
Normal file
@@ -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);
|
||||
}
|
||||
}
|
74
src/gallium/drivers/llvmpipe/lp_perf.h
Normal file
74
src/gallium/drivers/llvmpipe/lp_perf.h
Normal file
@@ -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 */
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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 )
|
||||
{
|
||||
|
@@ -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 );
|
||||
|
||||
|
@@ -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) );
|
||||
|
Reference in New Issue
Block a user