diff options
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 16 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_gs.c | 24 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.c | 11 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_emit.c | 15 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 6 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vbuf.h | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_prim.h | 35 |
10 files changed, 112 insertions, 20 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 2fb9bacf4c6..0f98021247a 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -842,3 +842,19 @@ draw_get_shader_param(unsigned shader, enum pipe_shader_cap param) return draw_get_shader_param_no_llvm(shader, param); } +/** + * Enables or disables collection of statistics. + * + * Draw module is capable of generating statistics for the vertex + * processing pipeline. Collection of that data isn't free and so + * it's disabled by default. The users of the module can enable + * (or disable) this functionality through this function. + * The actual data will be emitted through the VBUF interface, + * the 'pipeline_statistics' callback to be exact. + */ +void +draw_collect_pipeline_statistics(struct draw_context *draw, + boolean enable) +{ + draw->collect_statistics = enable; +} diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 1d25b7f255e..94fac880c68 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -264,6 +264,13 @@ void draw_set_driver_clipping( struct draw_context *draw, void draw_set_force_passthrough( struct draw_context *draw, boolean enable ); + +/******************************************************************************* + * Draw statistics + */ +void draw_collect_pipeline_statistics(struct draw_context *draw, + boolean enable); + /******************************************************************************* * Draw pipeline */ diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index d95a4c5705b..f8cb04a8f39 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -353,6 +353,10 @@ static void gs_flush(struct draw_geometry_shader *shader) unsigned input_primitives = shader->fetched_prim_count; + if (shader->draw->collect_statistics) { + shader->draw->statistics.gs_invocations += input_primitives; + } + debug_assert(input_primitives > 0 && input_primitives <= 4); @@ -493,11 +497,14 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, input_prim->count; unsigned num_in_primitives = align( - MAX2(u_gs_prims_for_vertices(input_prim->prim, num_input_verts), - u_gs_prims_for_vertices(shader->input_primitive, num_input_verts)), + MAX2(u_decomposed_prims_for_vertices(input_prim->prim, + num_input_verts), + u_decomposed_prims_for_vertices(shader->input_primitive, + num_input_verts)), shader->vector_length); - unsigned max_out_prims = u_gs_prims_for_vertices(shader->output_primitive, - shader->max_output_vertices) + unsigned max_out_prims = + u_decomposed_prims_for_vertices(shader->output_primitive, + shader->max_output_vertices) * num_in_primitives; //Assume at least one primitive @@ -593,6 +600,15 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, output_prims->primitive_count = shader->emitted_primitives; output_verts->count = shader->emitted_vertices; + if (shader->draw->collect_statistics) { + unsigned i; + for (i = 0; i < shader->emitted_primitives; ++i) { + shader->draw->statistics.gs_primitives += + u_decomposed_prims_for_vertices(shader->output_primitive, + shader->primitive_lengths[i]); + } + } + #if 0 debug_printf("GS finished, prims = %d, verts = %d\n", output_prims->primitive_count, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 757ed2645ef..d6a3e7c2cee 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -312,6 +312,9 @@ struct draw_context const struct pipe_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; unsigned num_samplers[PIPE_SHADER_TYPES]; + struct pipe_query_data_pipeline_statistics statistics; + boolean collect_statistics; + void *driver_private; }; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 853bd6716e6..10f32fd929f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -34,6 +34,7 @@ #include "draw/draw_gs.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" +#include "draw/draw_vbuf.h" #include "draw/draw_vs.h" #include "tgsi/tgsi_dump.h" #include "util/u_math.h" @@ -545,6 +546,11 @@ draw_vbo(struct draw_context *draw, return; } + /* If we're collecting stats then make sure we start from scratch */ + if (draw->collect_statistics) { + memset(&draw->statistics, 0, sizeof(draw->statistics)); + } + draw->pt.max_index = index_limit - 1; /* @@ -562,4 +568,9 @@ draw_vbo(struct draw_context *draw, draw_pt_arrays(draw, info->mode, info->start, count); } } + + /* If requested emit the pipeline statistics for this run */ + if (draw->collect_statistics) { + draw->render->pipeline_statistics(draw->render, &draw->statistics); + } } diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 942ddc4d7bc..b3d3546402d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -33,6 +33,7 @@ #include "draw/draw_pt.h" #include "translate/translate.h" #include "translate/translate_cache.h" +#include "util/u_prim.h" struct pt_emit { struct draw_context *draw; @@ -179,6 +180,12 @@ draw_pt_emit(struct pt_emit *emit, i < prim_info->primitive_count; start += prim_info->primitive_lengths[i], i++) { + if (draw->collect_statistics) { + draw->statistics.c_invocations += + u_decomposed_prims_for_vertices(prim_info->prim, + prim_info->primitive_lengths[i]); + } + render->draw_elements(render, elts + start, prim_info->primitive_lengths[i]); @@ -252,11 +259,17 @@ draw_pt_emit_linear(struct pt_emit *emit, i < prim_info->primitive_count; start += prim_info->primitive_lengths[i], i++) { + if (draw->collect_statistics) { + draw->statistics.c_invocations += + u_decomposed_prims_for_vertices(prim_info->prim, + prim_info->primitive_lengths[i]); + } + render->draw_arrays(render, start, prim_info->primitive_lengths[i]); } - + render->release_vertices(render); return; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 72d391257aa..e17f16147b2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -240,6 +240,12 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, assert(0); return; } + if (draw->collect_statistics) { + draw->statistics.ia_vertices += fetch_info->count; + draw->statistics.ia_primitives += + u_decomposed_prims_for_vertices(prim_info->prim, fetch_info->count); + draw->statistics.vs_invocations += fetch_info->count; + } /* Fetch into our vertex buffer. */ diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index ec0f758d453..d312dc48289 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -27,6 +27,7 @@ #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_prim.h" #include "draw/draw_context.h" #include "draw/draw_gs.h" #include "draw/draw_vbuf.h" @@ -333,6 +334,12 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, assert(0); return; } + if (draw->collect_statistics) { + draw->statistics.ia_vertices += fetch_info->count; + draw->statistics.ia_primitives += + u_decomposed_prims_for_vertices(prim_info->prim, fetch_info->count); + draw->statistics.vs_invocations += fetch_info->count; + } if (fetch_info->linear) clipped = fpme->current_variant->jit_func( &fpme->llvm->jit_context, diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h index f10d185868d..bf1c73cad5f 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.h +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -43,6 +43,7 @@ struct pipe_rasterizer_state; struct draw_context; struct vertex_info; +struct pipe_query_data_pipeline_statistics; /** @@ -126,6 +127,13 @@ struct vbuf_render { unsigned primitive_count, unsigned vertices_count, unsigned primitive_generated ); + + /** + * Called after all relevant statistics have been accumulated. + */ + void (*pipeline_statistics)( + struct vbuf_render *vbufr, + const struct pipe_query_data_pipeline_statistics *stats ); }; diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index d62c636f2ee..99bb66c9b89 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -165,12 +165,14 @@ u_vertices_per_prim(int primitive) /** * Returns the number of decomposed primitives for the given * vertex count. - * Geometry shader is invoked once for each triangle in + * Parts of the pipline are invoked once for each triangle in * triangle strip, triangle fans and triangles and once - * for each line in line strip, line loop, lines. + * for each line in line strip, line loop, lines. Also + * statistics depend on knowing the exact number of decomposed + * primitives for a set of vertices. */ static INLINE unsigned -u_gs_prims_for_vertices(int primitive, int vertices) +u_decomposed_prims_for_vertices(int primitive, int vertices) { switch(primitive) { case PIPE_PRIM_POINTS: @@ -180,31 +182,34 @@ u_gs_prims_for_vertices(int primitive, int vertices) case PIPE_PRIM_LINE_LOOP: return vertices; case PIPE_PRIM_LINE_STRIP: - return vertices - 1; + return (vertices > 1) ? vertices - 1 : 0; case PIPE_PRIM_TRIANGLES: return vertices / 3; case PIPE_PRIM_TRIANGLE_STRIP: - return vertices - 2; + return (vertices > 2) ? vertices - 2 : 0; case PIPE_PRIM_TRIANGLE_FAN: - return vertices - 2; + return (vertices > 2) ? vertices - 2 : 0; case PIPE_PRIM_LINES_ADJACENCY: return vertices / 2; case PIPE_PRIM_LINE_STRIP_ADJACENCY: - return vertices - 1; + return (vertices > 1) ? vertices - 1 : 0; case PIPE_PRIM_TRIANGLES_ADJACENCY: return vertices / 3; case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: - return vertices - 2; - - /* following primitives should never be used - * with geometry shaders abd their size is - * undefined */ - case PIPE_PRIM_POLYGON: + return (vertices > 2) ? vertices - 2 : 0; case PIPE_PRIM_QUADS: + return vertices / 4; case PIPE_PRIM_QUAD_STRIP: + return (vertices > 4) ? (vertices - 2) / 2 : 0; + /* Polygons can't be decomposed + * because the number of their vertices isn't known so + * for them and whatever else we don't recognize just + * return 1 if the number of vertices is greater than + * 3 and zero otherwise */ + case PIPE_PRIM_POLYGON: default: - debug_printf("Unrecognized geometry shader primitive"); - return 3; + debug_printf("Invalid decomposition primitive!\n"); + return (vertices > 3) ? 1 : 0; } } |