aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2013-06-26 23:11:03 +0200
committerRoland Scheidegger <[email protected]>2013-06-26 23:17:53 +0200
commit2e4da1f59444c550e4b1e31dd5cfec39d7ef2a26 (patch)
treed87e8968c3f791cfb6eba87daa4860c6ac90d603 /src/gallium/drivers
parent08203428800554215657f1ebf19d74328103800e (diff)
llvmpipe: add support for nested / overlapping queries
OpenGL doesn't support this but d3d10 does. It is a bit of a pain as it is necessary to keep track of queries still active at the end of a scene, which is also why I cheat a bit and limit the amount of simultaneously active queries to (arbitrary) 16 (simplifies things because don't have to deal with a real list that way). I can't think of a reason why you'd really want large numbers of overlapping/nested queries so it is hopefully fine. (This only affects queries which need to be binned.) v2: don't copy remainder of array when deleting an entry simply replace the deleted entry with the last one (order doesn't matter). Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c54
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_line.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_point.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c2
10 files changed, 45 insertions, 40 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index ab520019f82..9495e42feee 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -97,9 +97,9 @@ struct llvmpipe_context {
struct pipe_query_data_pipeline_statistics pipeline_statistics;
unsigned active_statistics_queries;
- unsigned dirty; /**< Mask of LP_NEW_x flags */
+ unsigned active_occlusion_queries;
- unsigned active_occlusion_query;
+ unsigned dirty; /**< Mask of LP_NEW_x flags */
/** Mapped vertex buffers */
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c
index 38d6b84b8d7..ac6d09d9a0f 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.c
+++ b/src/gallium/drivers/llvmpipe/lp_query.c
@@ -233,7 +233,7 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
break;
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
- llvmpipe->active_occlusion_query++;
+ llvmpipe->active_occlusion_queries++;
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
break;
default:
@@ -288,8 +288,8 @@ llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
break;
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
- assert(llvmpipe->active_occlusion_query);
- llvmpipe->active_occlusion_query--;
+ assert(llvmpipe->active_occlusion_queries);
+ llvmpipe->active_occlusion_queries--;
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
break;
default:
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 50917a7c633..e6e44c58262 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -53,6 +53,8 @@ struct cmd_bin;
/* Rasterizer output size going to jit fs, width/height */
#define LP_RASTER_BLOCK_SIZE 4
+#define LP_MAX_ACTIVE_BINNED_QUERIES 16
+
struct lp_rasterizer_task;
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index 16f69698ed0..59cce7d18f4 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -130,7 +130,7 @@ struct lp_scene {
struct lp_fence *fence;
/* The queries still active at end of scene */
- struct llvmpipe_query *active_queries[3];
+ struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
unsigned num_active_queries;
/* Framebuffer mappings - valid only between begin_rasterization()
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index d2c53255259..49aead2c1fa 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -155,22 +155,9 @@ lp_setup_rasterize_scene( struct lp_setup_context *setup )
struct lp_scene *scene = setup->scene;
struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen);
- scene->num_active_queries = 0;
- if (setup->active_query[PIPE_QUERY_OCCLUSION_COUNTER]) {
- scene->active_queries[scene->num_active_queries] =
- setup->active_query[PIPE_QUERY_OCCLUSION_COUNTER];
- scene->num_active_queries++;
- }
- if (setup->active_query[PIPE_QUERY_OCCLUSION_PREDICATE]) {
- scene->active_queries[scene->num_active_queries] =
- setup->active_query[PIPE_QUERY_OCCLUSION_PREDICATE];
- scene->num_active_queries++;
- }
- if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
- scene->active_queries[scene->num_active_queries] =
- setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS];
- scene->num_active_queries++;
- }
+ scene->num_active_queries = setup->active_binned_queries;
+ memcpy(scene->active_queries, setup->active_queries,
+ scene->num_active_queries * sizeof(scene->active_queries[0]));
lp_scene_end_binning(scene);
@@ -1226,9 +1213,14 @@ lp_setup_begin_query(struct lp_setup_context *setup,
return;
/* init the query to its beginning state */
- assert(setup->active_query[pq->type] == NULL);
-
- setup->active_query[pq->type] = pq;
+ assert(setup->active_binned_queries < LP_MAX_ACTIVE_BINNED_QUERIES);
+ /* exceeding list size so just ignore the query */
+ if (setup->active_binned_queries >= LP_MAX_ACTIVE_BINNED_QUERIES) {
+ return;
+ }
+ assert(setup->active_queries[setup->active_binned_queries] == NULL);
+ setup->active_queries[setup->active_binned_queries] = pq;
+ setup->active_binned_queries++;
assert(setup->scene);
if (setup->scene) {
@@ -1257,12 +1249,6 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
{
set_scene_state(setup, SETUP_ACTIVE, "end_query");
- if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
- pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
- pq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
- assert(setup->active_query[pq->type] == pq);
- }
-
assert(setup->scene);
if (setup->scene) {
/* pq->fence should be the fence of the *last* scene which
@@ -1296,7 +1282,23 @@ fail:
/* Need to do this now not earlier since it still needs to be marked as
* active when binning it would cause a flush.
*/
- setup->active_query[pq->type] = NULL;
+ if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
+ pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
+ pq->type == PIPE_QUERY_PIPELINE_STATISTICS) {
+ unsigned i;
+
+ /* remove from active binned query list */
+ for (i = 0; i < setup->active_binned_queries; i++) {
+ if (setup->active_queries[i] == pq)
+ break;
+ }
+ assert(i < setup->active_binned_queries);
+ if (i == setup->active_binned_queries)
+ return;
+ setup->active_binned_queries--;
+ setup->active_queries[i] = setup->active_queries[setup->active_binned_queries];
+ setup->active_queries[setup->active_binned_queries] = NULL;
+ }
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index cc2b97390c0..89c23bbb3ac 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -89,7 +89,8 @@ struct lp_setup_context
struct lp_scene *scene; /**< current scene being built */
struct lp_fence *last_fence;
- struct llvmpipe_query *active_query[PIPE_QUERY_TYPES];
+ struct llvmpipe_query *active_queries[LP_MAX_ACTIVE_BINNED_QUERIES];
+ unsigned active_binned_queries;
boolean subdivide_large_triangles;
boolean flatshade_first;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c
index 4b59bf38692..bfed59cba0a 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_line.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c
@@ -278,6 +278,7 @@ try_setup_line( struct lp_setup_context *setup,
const float (*v1)[4],
const float (*v2)[4])
{
+ struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
struct lp_scene *scene = setup->scene;
const struct lp_setup_variant_key *key = &setup->setup.variant->key;
struct lp_rast_triangle *line;
@@ -596,8 +597,7 @@ try_setup_line( struct lp_setup_context *setup,
LP_COUNT(nr_tris);
- if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
- struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
+ if (lp_context->active_statistics_queries) {
lp_context->pipeline_statistics.c_primitives++;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index 7fe7bc56d2b..868a9a904b7 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -303,6 +303,7 @@ static boolean
try_setup_point( struct lp_setup_context *setup,
const float (*v0)[4] )
{
+ struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
/* x/y positions in fixed point */
const struct lp_setup_variant_key *key = &setup->setup.variant->key;
const int sizeAttr = setup->psize;
@@ -379,8 +380,7 @@ try_setup_point( struct lp_setup_context *setup,
LP_COUNT(nr_tris);
- if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
- struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
+ if (lp_context->active_statistics_queries) {
lp_context->pipeline_statistics.c_primitives++;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 62df5df555f..6dc136c3aa3 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -252,6 +252,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
const float (*v2)[4],
boolean frontfacing )
{
+ struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
struct lp_scene *scene = setup->scene;
const struct lp_setup_variant_key *key = &setup->setup.variant->key;
struct lp_rast_triangle *tri;
@@ -339,8 +340,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
LP_COUNT(nr_tris);
- if (setup->active_query[PIPE_QUERY_PIPELINE_STATISTICS]) {
- struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
+ if (lp_context->active_statistics_queries) {
lp_context->pipeline_statistics.c_primitives++;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 38e9fc7d736..6afd57a6859 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -2630,7 +2630,7 @@ make_variant_key(struct llvmpipe_context *lp,
/* alpha.ref_value is passed in jit_context */
key->flatshade = lp->rasterizer->flatshade;
- if (lp->active_occlusion_query) {
+ if (lp->active_occlusion_queries) {
key->occlusion_count = TRUE;
}