summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c16
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.c24
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c15
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c7
-rw-r--r--src/gallium/auxiliary/draw/draw_vbuf.h8
-rw-r--r--src/gallium/auxiliary/util/u_prim.h35
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;
}
}