panfrost: Implement callbacks for PRIMITIVES queries
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 8 Aug 2019 14:01:12 +0000 (07:01 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 13 Aug 2019 16:42:48 +0000 (09:42 -0700)
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@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/panfrost/pan_context.h

index 7b80da2795ab83da3dfb1027dd92e99ee3ca6ff6..0b9360c0f63e0c494e962d6f2f1f90cc9d9ec470 100644 (file)
@@ -2475,7 +2475,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
@@ -2525,17 +2526,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;
         }
 
@@ -2546,7 +2554,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;
 }
 
@@ -2556,18 +2579,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;
@@ -2579,7 +2600,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;
index 1277629382aee3d31c6e20ec36af369cf28c0576..3eac35023ce5fe9dd4c00351ba488447090546e4 100644 (file)
@@ -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 {
@@ -123,6 +131,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 */