Module: Mesa
Branch: master
Commit: 9ccb6621be2f40a74f75efe30d83b7813e3c3f56
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=9ccb6621be2f40a74f75efe30d83b7813e3c3f56

Author: Eric Anholt <e...@anholt.net>
Date:   Mon Nov  6 16:59:05 2017 -0800

broadcom/vc5: Add partial transform feedback query support.

We have to compute the queries in software, so we're counting the
primitives by hand.  We still need to make sure to not increment the
PRIMITIVES_EMITTED if we overflowed, but leave that for later.

---

 src/gallium/drivers/vc5/vc5_context.h |  3 ++
 src/gallium/drivers/vc5/vc5_draw.c    | 21 +++++++++++++
 src/gallium/drivers/vc5/vc5_query.c   | 57 ++++++++++++++++++++++++-----------
 3 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/vc5/vc5_context.h 
b/src/gallium/drivers/vc5/vc5_context.h
index 2fec7a77da..4917153fd4 100644
--- a/src/gallium/drivers/vc5/vc5_context.h
+++ b/src/gallium/drivers/vc5/vc5_context.h
@@ -363,6 +363,9 @@ struct vc5_context {
 
         bool active_queries;
 
+        uint32_t tf_prims_generated;
+        uint32_t prims_generated;
+
         struct pipe_poly_stipple stipple;
         struct pipe_clip_state clip;
         struct pipe_viewport_state viewport;
diff --git a/src/gallium/drivers/vc5/vc5_draw.c 
b/src/gallium/drivers/vc5/vc5_draw.c
index 8020e26802..55a2e49b98 100644
--- a/src/gallium/drivers/vc5/vc5_draw.c
+++ b/src/gallium/drivers/vc5/vc5_draw.c
@@ -270,6 +270,25 @@ vc5_emit_gl_shader_state(struct vc5_context *vc5,
         job->shader_rec_count++;
 }
 
+/**
+ * Computes the various transform feedback statistics, since they can't be
+ * recorded by CL packets.
+ */
+static void
+vc5_tf_statistics_record(struct vc5_context *vc5,
+                         const struct pipe_draw_info *info,
+                         bool prim_tf)
+{
+        uint32_t prims = u_prims_for_vertices(info->mode, info->count);
+
+        vc5->prims_generated += prims;
+
+        if (prim_tf) {
+                /* XXX: Only count if we didn't overflow. */
+                vc5->tf_prims_generated += prims;
+        }
+}
+
 static void
 vc5_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 {
@@ -363,6 +382,8 @@ vc5_draw_vbo(struct pipe_context *pctx, const struct 
pipe_draw_info *info)
         if (vc5->prog.bind_vs->num_tf_outputs)
                 prim_tf_enable = (V3D_PRIM_POINTS_TF - V3D_PRIM_POINTS);
 
+        vc5_tf_statistics_record(vc5, info, prim_tf_enable);
+
         /* Note that the primitive type fields match with OpenGL/gallium
          * definitions, up to but not including QUADS.
          */
diff --git a/src/gallium/drivers/vc5/vc5_query.c 
b/src/gallium/drivers/vc5/vc5_query.c
index a412b38408..5ec9be2e35 100644
--- a/src/gallium/drivers/vc5/vc5_query.c
+++ b/src/gallium/drivers/vc5/vc5_query.c
@@ -24,12 +24,13 @@
 /**
  * Gallium query object support.
  *
- * So far we just support occlusion queries.  The HW has native support for
- * them, with the query result being loaded and stored by the TLB unit.
+ * The HW has native support for occlusion queries, with the query result
+ * being loaded and stored by the TLB unit. From a SW perspective, we have to
+ * be careful to make sure that the jobs that need to be tracking queries are
+ * bracketed by the start and end of counting, even across FBO transitions.
  *
- * From a SW perspective, we have to be careful to make sure that the jobs
- * that need to be tracking queries are bracketed by the start and end of
- * counting, even across FBO transitions.
+ * For the transform feedback PRIMITIVES_GENERATED/WRITTEN queries, we have to
+ * do the calculations in software at draw time.
  */
 
 #include "vc5_context.h"
@@ -39,6 +40,8 @@ struct vc5_query
 {
         enum pipe_query_type type;
         struct vc5_bo *bo;
+
+        uint32_t start, end;
 };
 
 static struct pipe_query *
@@ -46,10 +49,6 @@ vc5_create_query(struct pipe_context *pctx, unsigned 
query_type, unsigned index)
 {
         struct vc5_query *q = calloc(1, sizeof(*q));
 
-        assert(query_type == PIPE_QUERY_OCCLUSION_COUNTER ||
-               query_type == PIPE_QUERY_OCCLUSION_PREDICATE ||
-               query_type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE);
-
         q->type = query_type;
 
         /* Note that struct pipe_query isn't actually defined anywhere. */
@@ -71,13 +70,22 @@ vc5_begin_query(struct pipe_context *pctx, struct 
pipe_query *query)
         struct vc5_context *vc5 = vc5_context(pctx);
         struct vc5_query *q = (struct vc5_query *)query;
 
-        q->bo = vc5_bo_alloc(vc5->screen, 4096, "query");
-
-        uint32_t *map = vc5_bo_map(q->bo);
-        *map = 0;
+        switch (q->type) {
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+                q->start = vc5->prims_generated;
+                break;
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                q->start = vc5->tf_prims_generated;
+                break;
+        default:
+                q->bo = vc5_bo_alloc(vc5->screen, 4096, "query");
 
-        vc5->current_oq = q->bo;
-        vc5->dirty |= VC5_DIRTY_OQ;
+                uint32_t *map = vc5_bo_map(q->bo);
+                *map = 0;
+                vc5->current_oq = q->bo;
+                vc5->dirty |= VC5_DIRTY_OQ;
+                break;
+        }
 
         return true;
 }
@@ -86,9 +94,20 @@ static bool
 vc5_end_query(struct pipe_context *pctx, struct pipe_query *query)
 {
         struct vc5_context *vc5 = vc5_context(pctx);
+        struct vc5_query *q = (struct vc5_query *)query;
 
-        vc5->current_oq = NULL;
-        vc5->dirty |= VC5_DIRTY_OQ;
+        switch (q->type) {
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+                q->end = vc5->prims_generated;
+                break;
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                q->end = vc5->tf_prims_generated;
+                break;
+        default:
+                vc5->current_oq = NULL;
+                vc5->dirty |= VC5_DIRTY_OQ;
+                break;
+        }
 
         return true;
 }
@@ -127,6 +146,10 @@ vc5_get_query_result(struct pipe_context *pctx, struct 
pipe_query *query,
         case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
                 vresult->b = result != 0;
                 break;
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                vresult->u64 = q->end - q->start;
+                break;
         default:
                 unreachable("unsupported query type");
         }

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to