summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2013-04-11 06:11:29 -0700
committerZack Rusin <[email protected]>2013-04-16 23:38:47 -0700
commit80ee4a407a2668f6a6a410c3e56ae9910510f773 (patch)
treefef704d3c130eb615a0e9f4d9631288d45513749 /src/gallium/drivers/llvmpipe
parentb739376cffec19870804b1ebd4bef3c2f654e943 (diff)
draw: implement pipeline statistics in the draw module
This is a basic implementation of the pipeline statistics in the draw module. The interface is similar to the stream output statistics and also requires that the callers explicitly enable it. Included is the implementation of the interface in llvmpipe and softpipe. Only softpipe enables the pipeline statistics capability though because llvmpipe is lacking gathering of the fragment shading and rasterization statistics. Signed-off-by: Zack Rusin <[email protected]> Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.c37
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_vbuf.c23
6 files changed, 69 insertions, 0 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 6ee7b99f478..d605dba2260 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -94,6 +94,9 @@ struct llvmpipe_context {
struct pipe_query_data_so_statistics so_stats;
unsigned num_primitives_generated;
+ struct pipe_query_data_pipeline_statistics pipeline_statistics;
+ unsigned active_statistics_queries;
+
unsigned dirty; /**< Mask of LP_NEW_x flags */
unsigned active_occlusion_query;
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index efeca255755..e8a5880deef 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -108,6 +108,8 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
draw_vs_attach_so(lp->vs->draw_data, &lp->gs->shader.stream_output);
}
}
+ draw_collect_pipeline_statistics(draw,
+ lp->active_statistics_queries > 0);
/* draw! */
draw_vbo(draw, info);
diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c
index 013d1928c11..96e1e3ff1f3 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.c
+++ b/src/gallium/drivers/llvmpipe/lp_query.c
@@ -144,6 +144,12 @@ llvmpipe_get_query_result(struct pipe_context *pipe,
stats->primitives_storage_needed = pq->num_primitives_generated;
}
break;
+ case PIPE_QUERY_PIPELINE_STATISTICS: {
+ struct pipe_query_data_pipeline_statistics *stats =
+ (struct pipe_query_data_pipeline_statistics *)vresult;
+ *stats = pq->stats;
+ }
+ break;
default:
assert(0);
break;
@@ -188,6 +194,16 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
llvmpipe->num_primitives_generated = 0;
}
+ if (pq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
+ /* reset our cache */
+ if (llvmpipe->active_statistics_queries == 0) {
+ memset(&llvmpipe->pipeline_statistics, 0,
+ sizeof(llvmpipe->pipeline_statistics));
+ }
+ memcpy(&pq->stats, &llvmpipe->pipeline_statistics, sizeof(pq->stats));
+ llvmpipe->active_statistics_queries++;
+ }
+
if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
llvmpipe->active_occlusion_query = TRUE;
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
@@ -216,6 +232,27 @@ llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
pq->num_primitives_generated = llvmpipe->num_primitives_generated;
}
+ if (pq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
+ pq->stats.ia_vertices =
+ llvmpipe->pipeline_statistics.ia_vertices - pq->stats.ia_vertices;
+ pq->stats.ia_primitives =
+ llvmpipe->pipeline_statistics.ia_primitives - pq->stats.ia_primitives;
+ pq->stats.vs_invocations =
+ llvmpipe->pipeline_statistics.vs_invocations - pq->stats.vs_invocations;
+ pq->stats.gs_invocations =
+ llvmpipe->pipeline_statistics.gs_invocations - pq->stats.gs_invocations;
+ pq->stats.gs_primitives =
+ llvmpipe->pipeline_statistics.gs_primitives - pq->stats.gs_primitives;
+ pq->stats.c_invocations =
+ llvmpipe->pipeline_statistics.c_invocations - pq->stats.c_invocations;
+ pq->stats.c_primitives =
+ llvmpipe->pipeline_statistics.c_primitives - pq->stats.c_primitives;
+ pq->stats.ps_invocations =
+ llvmpipe->pipeline_statistics.ps_invocations - pq->stats.ps_invocations;
+
+ llvmpipe->active_statistics_queries--;
+ }
+
if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
assert(llvmpipe->active_occlusion_query);
llvmpipe->active_occlusion_query = FALSE;
diff --git a/src/gallium/drivers/llvmpipe/lp_query.h b/src/gallium/drivers/llvmpipe/lp_query.h
index 19d977fd2e4..68dfe99f428 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.h
+++ b/src/gallium/drivers/llvmpipe/lp_query.h
@@ -47,6 +47,8 @@ struct llvmpipe_query {
unsigned type; /* PIPE_QUERY_* */
unsigned num_primitives_generated;
unsigned num_primitives_written;
+
+ struct pipe_query_data_pipeline_statistics stats;
};
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 6cb27020566..29dd933c644 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -477,6 +477,7 @@ lp_rast_begin_query(struct lp_rasterizer_task *task,
case PIPE_QUERY_PRIMITIVES_GENERATED:
case PIPE_QUERY_PRIMITIVES_EMITTED:
case PIPE_QUERY_SO_STATISTICS:
+ case PIPE_QUERY_PIPELINE_STATISTICS:
break;
default:
assert(0);
@@ -509,6 +510,7 @@ lp_rast_end_query(struct lp_rasterizer_task *task,
case PIPE_QUERY_PRIMITIVES_GENERATED:
case PIPE_QUERY_PRIMITIVES_EMITTED:
case PIPE_QUERY_SO_STATISTICS:
+ case PIPE_QUERY_PIPELINE_STATISTICS:
break;
default:
assert(0);
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
index 9e0a5b39954..8173994e5c1 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
@@ -547,6 +547,28 @@ lp_setup_so_info(struct vbuf_render *vbr, uint primitives, uint vertices,
lp->num_primitives_generated += prim_generated;
}
+static void
+lp_setup_pipeline_statistics(
+ struct vbuf_render *vbr,
+ const struct pipe_query_data_pipeline_statistics *stats)
+{
+ struct lp_setup_context *setup = lp_setup_context(vbr);
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(setup->pipe);
+
+ llvmpipe->pipeline_statistics.ia_vertices +=
+ stats->ia_vertices;
+ llvmpipe->pipeline_statistics.ia_primitives +=
+ stats->ia_primitives;
+ llvmpipe->pipeline_statistics.vs_invocations +=
+ stats->vs_invocations;
+ llvmpipe->pipeline_statistics.gs_invocations +=
+ stats->gs_invocations;
+ llvmpipe->pipeline_statistics.gs_primitives +=
+ stats->gs_primitives;
+ llvmpipe->pipeline_statistics.c_invocations +=
+ stats->c_invocations;
+}
+
/**
* Create the post-transform vertex handler for the given context.
*/
@@ -566,4 +588,5 @@ lp_setup_init_vbuf(struct lp_setup_context *setup)
setup->base.release_vertices = lp_setup_release_vertices;
setup->base.destroy = lp_setup_vbuf_destroy;
setup->base.set_stream_output_info = lp_setup_so_info;
+ setup->base.pipeline_statistics = lp_setup_pipeline_statistics;
}