[Mesa-dev] [PATCH 1/2] llvmpipe: add support for nested / overlapping queries

sroland at vmware.com sroland at vmware.com
Tue Jun 25 16:34:58 PDT 2013


From: Roland Scheidegger <sroland at vmware.com>

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.)
---
 src/gallium/drivers/llvmpipe/lp_context.h       |    4 +-
 src/gallium/drivers/llvmpipe/lp_query.c         |    6 +--
 src/gallium/drivers/llvmpipe/lp_rast.h          |    2 +
 src/gallium/drivers/llvmpipe/lp_scene.h         |    2 +-
 src/gallium/drivers/llvmpipe/lp_setup.c         |   58 +++++++++++++----------
 src/gallium/drivers/llvmpipe/lp_setup_context.h |    3 +-
 src/gallium/drivers/llvmpipe/lp_setup_line.c    |    4 +-
 src/gallium/drivers/llvmpipe/lp_setup_point.c   |    4 +-
 src/gallium/drivers/llvmpipe/lp_setup_tri.c     |    4 +-
 src/gallium/drivers/llvmpipe/lp_state_fs.c      |    2 +-
 10 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index ab52001..9495e42 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 38d6b84..ac6d09d 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 50917a7..e6e44c5 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 16f6969..59cce7d 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 d2c5325..bb3a5c0 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,27 @@ 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 < LP_MAX_ACTIVE_BINNED_QUERIES);
+      if (i == LP_MAX_ACTIVE_BINNED_QUERIES)
+         return;
+
+      if (i != setup->active_binned_queries) {
+         memmove(&setup->active_queries[i], &setup->active_queries[i+1],
+                 (setup->active_binned_queries - i) * sizeof(setup->active_queries[0]));
+      }
+      setup->active_queries[setup->active_binned_queries] = NULL;
+      setup->active_binned_queries--;
+   }
 }
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index cc2b973..89c23bb 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 4b59bf3..bfed59c 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 7fe7bc5..868a9a9 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 62df5df..6dc136c 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 fc2ba5e..d8591d3 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -2622,7 +2622,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;
    }
 
-- 
1.7.9.5


More information about the mesa-dev mailing list