[Mesa-dev] [PATCH 1/9] panfrost: Implement callbacks for PRIMITIVES queries

Alyssa Rosenzweig alyssa.rosenzweig at collabora.com
Fri Aug 9 20:00:44 UTC 2019


We're just going to compute them in the driver but let's get the
structures setup to handle them. Implementation from v3d.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
---
 src/gallium/drivers/panfrost/pan_context.c | 52 ++++++++++++++++------
 src/gallium/drivers/panfrost/pan_context.h | 15 ++++++-
 2 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index ac1d1b9429b..3903a4ca337 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -2365,7 +2365,8 @@ static void
 panfrost_set_active_query_state(struct pipe_context *pipe,
                                 bool enable)
 {
-        //struct panfrost_context *panfrost = pan_context(pipe);
+        struct panfrost_context *ctx = pan_context(pipe);
+        ctx->active_queries = enable;
 }
 
 static void
@@ -2415,17 +2416,24 @@ panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q)
         switch (query->type) {
         case PIPE_QUERY_OCCLUSION_COUNTER:
         case PIPE_QUERY_OCCLUSION_PREDICATE:
-        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: {
+        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
                 /* Allocate a word for the query results to be stored */
                 query->transfer = panfrost_allocate_transient(ctx, sizeof(unsigned));
-
                 ctx->occlusion_query = query;
+                break;
+
+        /* Geometry statistics are computed in the driver. XXX: geom/tess
+         * shaders.. */
 
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+                query->start = ctx->prims_generated;
+                break;
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                query->start = ctx->tf_prims_generated;
                 break;
-        }
 
         default:
-                DBG("Skipping query %d\n", query->type);
+                fprintf(stderr, "Skipping query %d\n", query->type);
                 break;
         }
 
@@ -2436,7 +2444,22 @@ static bool
 panfrost_end_query(struct pipe_context *pipe, struct pipe_query *q)
 {
         struct panfrost_context *ctx = pan_context(pipe);
-        ctx->occlusion_query = NULL;
+        struct panfrost_query *query = (struct panfrost_query *) q;
+
+        switch (query->type) {
+        case PIPE_QUERY_OCCLUSION_COUNTER:
+        case PIPE_QUERY_OCCLUSION_PREDICATE:
+        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+                ctx->occlusion_query = NULL;
+                break;
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+                query->end = ctx->prims_generated;
+                break;
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                query->end = ctx->tf_prims_generated;
+                break;
+        }
+
         return true;
 }
 
@@ -2446,18 +2469,16 @@ panfrost_get_query_result(struct pipe_context *pipe,
                           bool wait,
                           union pipe_query_result *vresult)
 {
-        /* STUB */
         struct panfrost_query *query = (struct panfrost_query *) q;
 
-        /* We need to flush out the jobs to actually run the counter, TODO
-         * check wait, TODO wallpaper after if needed */
-
-        panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
 
         switch (query->type) {
         case PIPE_QUERY_OCCLUSION_COUNTER:
         case PIPE_QUERY_OCCLUSION_PREDICATE:
-        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: {
+        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+                /* Flush first */
+                panfrost_flush(pipe, NULL, PIPE_FLUSH_END_OF_FRAME);
+
                 /* Read back the query results */
                 unsigned *result = (unsigned *) query->transfer.cpu;
                 unsigned passed = *result;
@@ -2469,7 +2490,12 @@ panfrost_get_query_result(struct pipe_context *pipe,
                 }
 
                 break;
-        }
+
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                vresult->u64 = query->end - query->start;
+                break;
+
         default:
                 DBG("Skipped query get %d\n", query->type);
                 break;
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index 542d24d2c27..24c54fe3467 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -79,8 +79,16 @@ struct panfrost_query {
         unsigned type;
         unsigned index;
 
-        /* Memory for the GPU to writeback the value of the query */
-        struct panfrost_transfer transfer;
+        union {
+                /* For computed queries. 64-bit to prevent overflow */
+                struct {
+                        uint64_t start;
+                        uint64_t end;
+                };
+
+                /* Memory for the GPU to writeback the value of the query */
+                struct panfrost_transfer transfer;
+        };
 };
 
 struct panfrost_fence {
@@ -120,6 +128,9 @@ struct panfrost_context {
         struct panfrost_memory tiler_dummy;
         struct panfrost_memory depth_stencil_buffer;
 
+        bool active_queries;
+        uint64_t prims_generated;
+        uint64_t tf_prims_generated;
         struct panfrost_query *occlusion_query;
 
         /* Each draw has corresponding vertex and tiler payloads */
-- 
2.20.1



More information about the mesa-dev mailing list