Mesa (main): v3d: move queries to pipe queries

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 3 09:46:48 UTC 2021


Module: Mesa
Branch: main
Commit: c59d8a179831fa9fe867c3547839e95f41774b8f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c59d8a179831fa9fe867c3547839e95f41774b8f

Author: Juan A. Suarez Romero <jasuarez at igalia.com>
Date:   Wed Apr 21 14:22:45 2021 +0200

v3d: move queries to pipe queries

All the current queries are pipe-related queries; move them to a
different file to add later performance counter queries.

v3 (Iago):
 - Fix copyright.

Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Signed-off-by: Juan A. Suarez Romero <jasuarez at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10666>

---

 src/gallium/drivers/v3d/meson.build      |   2 +
 src/gallium/drivers/v3d/v3d_query.c      | 138 ++-------------------
 src/gallium/drivers/v3d/v3d_query.h      |  46 +++++++
 src/gallium/drivers/v3d/v3d_query_pipe.c | 200 +++++++++++++++++++++++++++++++
 4 files changed, 255 insertions(+), 131 deletions(-)

diff --git a/src/gallium/drivers/v3d/meson.build b/src/gallium/drivers/v3d/meson.build
index 32c512dbca7..1e92fb62835 100644
--- a/src/gallium/drivers/v3d/meson.build
+++ b/src/gallium/drivers/v3d/meson.build
@@ -31,6 +31,8 @@ files_libv3d = files(
   'v3d_job.c',
   'v3d_program.c',
   'v3d_query.c',
+  'v3d_query.h',
+  'v3d_query_pipe.c',
   'v3d_resource.c',
   'v3d_resource.h',
   'v3d_screen.c',
diff --git a/src/gallium/drivers/v3d/v3d_query.c b/src/gallium/drivers/v3d/v3d_query.c
index 31bd03419f2..ae9993b475a 100644
--- a/src/gallium/drivers/v3d/v3d_query.c
+++ b/src/gallium/drivers/v3d/v3d_query.c
@@ -21,47 +21,21 @@
  * IN THE SOFTWARE.
  */
 
-/**
- * Gallium query object support.
- *
- * 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.
- *
- * For the transform feedback PRIMITIVES_GENERATED/WRITTEN queries, we have to
- * do the calculations in software at draw time.
- */
-
-#include "v3d_context.h"
-#include "broadcom/cle/v3d_packet_v33_pack.h"
-
-struct v3d_query
-{
-        enum pipe_query_type type;
-        struct v3d_bo *bo;
-
-        uint32_t start, end;
-};
+#include "v3d_query.h"
 
 static struct pipe_query *
 v3d_create_query(struct pipe_context *pctx, unsigned query_type, unsigned index)
 {
-        struct v3d_query *q = calloc(1, sizeof(*q));
-
-        q->type = query_type;
-
-        /* Note that struct pipe_query isn't actually defined anywhere. */
-        return (struct pipe_query *)q;
+        return v3d_create_query_pipe(v3d_context(pctx), query_type, index);
 }
 
 static void
 v3d_destroy_query(struct pipe_context *pctx, struct pipe_query *query)
 {
+        struct v3d_context *v3d = v3d_context(pctx);
         struct v3d_query *q = (struct v3d_query *)query;
 
-        v3d_bo_unreference(&q->bo);
-        free(q);
+        q->funcs->destroy_query(v3d, q);
 }
 
 static bool
@@ -70,40 +44,7 @@ v3d_begin_query(struct pipe_context *pctx, struct pipe_query *query)
         struct v3d_context *v3d = v3d_context(pctx);
         struct v3d_query *q = (struct v3d_query *)query;
 
-        switch (q->type) {
-        case PIPE_QUERY_PRIMITIVES_GENERATED:
-                /* If we are using PRIMITIVE_COUNTS_FEEDBACK to retrieve
-                 * primitive counts from the GPU (which we need when a GS
-                 * is present), then we need to update our counters now
-                 * to discard any primitives generated before this.
-                 */
-                if (v3d->prog.gs)
-                        v3d_update_primitive_counters(v3d);
-                q->start = v3d->prims_generated;
-                break;
-        case PIPE_QUERY_PRIMITIVES_EMITTED:
-                /* If we are inside transform feedback we need to update the
-                 * primitive counts to skip primitives recorded before this.
-                 */
-                if (v3d->streamout.num_targets > 0)
-                        v3d_update_primitive_counters(v3d);
-                q->start = v3d->tf_prims_generated;
-                break;
-        case PIPE_QUERY_OCCLUSION_COUNTER:
-        case PIPE_QUERY_OCCLUSION_PREDICATE:
-        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
-                q->bo = v3d_bo_alloc(v3d->screen, 4096, "query");
-                uint32_t *map = v3d_bo_map(q->bo);
-                *map = 0;
-
-                v3d->current_oq = q->bo;
-                v3d->dirty |= V3D_DIRTY_OQ;
-                break;
-        default:
-                unreachable("unsupported query type");
-        }
-
-        return true;
+        return q->funcs->begin_query(v3d, q);
 }
 
 static bool
@@ -112,36 +53,7 @@ v3d_end_query(struct pipe_context *pctx, struct pipe_query *query)
         struct v3d_context *v3d = v3d_context(pctx);
         struct v3d_query *q = (struct v3d_query *)query;
 
-        switch (q->type) {
-        case PIPE_QUERY_PRIMITIVES_GENERATED:
-                /* If we are using PRIMITIVE_COUNTS_FEEDBACK to retrieve
-                 * primitive counts from the GPU (which we need when a GS
-                 * is present), then we need to update our counters now.
-                 */
-                if (v3d->prog.gs)
-                        v3d_update_primitive_counters(v3d);
-                q->end = v3d->prims_generated;
-                break;
-        case PIPE_QUERY_PRIMITIVES_EMITTED:
-                /* If transform feedback has ended, then we have already
-                 * updated the primitive counts at glEndTransformFeedback()
-                 * time. Otherwise, we have to do it now.
-                 */
-                if (v3d->streamout.num_targets > 0)
-                        v3d_update_primitive_counters(v3d);
-                q->end = v3d->tf_prims_generated;
-                break;
-        case PIPE_QUERY_OCCLUSION_COUNTER:
-        case PIPE_QUERY_OCCLUSION_PREDICATE:
-        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
-                v3d->current_oq = NULL;
-                v3d->dirty |= V3D_DIRTY_OQ;
-                break;
-        default:
-                unreachable("unsupported query type");
-        }
-
-        return true;
+        return q->funcs->end_query(v3d, q);
 }
 
 static bool
@@ -150,43 +62,8 @@ v3d_get_query_result(struct pipe_context *pctx, struct pipe_query *query,
 {
         struct v3d_context *v3d = v3d_context(pctx);
         struct v3d_query *q = (struct v3d_query *)query;
-        uint32_t result = 0;
-
-        if (q->bo) {
-                v3d_flush_jobs_using_bo(v3d, q->bo);
-
-                if (wait) {
-                        if (!v3d_bo_wait(q->bo, ~0ull, "query"))
-                                return false;
-                } else {
-                        if (!v3d_bo_wait(q->bo, 0, "query"))
-                                return false;
-                }
 
-                /* XXX: Sum up per-core values. */
-                uint32_t *map = v3d_bo_map(q->bo);
-                result = *map;
-
-                v3d_bo_unreference(&q->bo);
-        }
-
-        switch (q->type) {
-        case PIPE_QUERY_OCCLUSION_COUNTER:
-                vresult->u64 = result;
-                break;
-        case PIPE_QUERY_OCCLUSION_PREDICATE:
-        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");
-        }
-
-        return true;
+        return q->funcs->get_query_result(v3d, q, wait, vresult);
 }
 
 static void
@@ -209,4 +86,3 @@ v3d_query_init(struct pipe_context *pctx)
         pctx->get_query_result = v3d_get_query_result;
         pctx->set_active_query_state = v3d_set_active_query_state;
 }
-
diff --git a/src/gallium/drivers/v3d/v3d_query.h b/src/gallium/drivers/v3d/v3d_query.h
new file mode 100644
index 00000000000..12026b28805
--- /dev/null
+++ b/src/gallium/drivers/v3d/v3d_query.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2021 Raspberry Pi
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef V3D_QUERY_H
+#define V3D_QUERY_H
+
+#include "v3d_context.h"
+
+struct v3d_query;
+
+struct v3d_query_funcs {
+        void (*destroy_query)(struct v3d_context *v3d, struct v3d_query *query);
+        bool (*begin_query)(struct v3d_context *v3d, struct v3d_query *query);
+        bool (*end_query)(struct v3d_context *v3d, struct v3d_query *query);
+        bool (*get_query_result)(struct v3d_context *v3d, struct v3d_query *query,
+                                 bool wait, union pipe_query_result *result);
+};
+
+struct v3d_query
+{
+        const struct v3d_query_funcs *funcs;
+};
+
+struct pipe_query *v3d_create_query_pipe(struct v3d_context *v3d, unsigned query_type, unsigned index);
+
+#endif /* V3D_QUERY_H */
diff --git a/src/gallium/drivers/v3d/v3d_query_pipe.c b/src/gallium/drivers/v3d/v3d_query_pipe.c
new file mode 100644
index 00000000000..eafb7ec6106
--- /dev/null
+++ b/src/gallium/drivers/v3d/v3d_query_pipe.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * Gallium query object support.
+ *
+ * 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.
+ *
+ * For the transform feedback PRIMITIVES_GENERATED/WRITTEN queries, we have to
+ * do the calculations in software at draw time.
+ */
+
+#include "v3d_query.h"
+
+struct v3d_query_pipe
+{
+        struct v3d_query base;
+
+        enum pipe_query_type type;
+        struct v3d_bo *bo;
+
+        uint32_t start, end;
+};
+
+static void
+v3d_destroy_query_pipe(struct v3d_context *v3d, struct v3d_query *query)
+{
+        struct v3d_query_pipe *pquery = (struct v3d_query_pipe *)query;
+
+        v3d_bo_unreference(&pquery->bo);
+        free(pquery);
+}
+
+static bool
+v3d_begin_query_pipe(struct v3d_context *v3d, struct v3d_query *query)
+{
+        struct v3d_query_pipe *pquery = (struct v3d_query_pipe *)query;
+
+        switch (pquery->type) {
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+                /* If we are using PRIMITIVE_COUNTS_FEEDBACK to retrieve
+                 * primitive counts from the GPU (which we need when a GS
+                 * is present), then we need to update our counters now
+                 * to discard any primitives generated before this.
+                 */
+                if (v3d->prog.gs)
+                        v3d_update_primitive_counters(v3d);
+                pquery->start = v3d->prims_generated;
+                break;
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                /* If we are inside transform feedback we need to update the
+                 * primitive counts to skip primitives recorded before this.
+                 */
+                if (v3d->streamout.num_targets > 0)
+                        v3d_update_primitive_counters(v3d);
+                pquery->start = v3d->tf_prims_generated;
+                break;
+        case PIPE_QUERY_OCCLUSION_COUNTER:
+        case PIPE_QUERY_OCCLUSION_PREDICATE:
+        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+                pquery->bo = v3d_bo_alloc(v3d->screen, 4096, "query");
+                uint32_t *map = v3d_bo_map(pquery->bo);
+                *map = 0;
+
+                v3d->current_oq = pquery->bo;
+                v3d->dirty |= V3D_DIRTY_OQ;
+                break;
+        default:
+                unreachable("unsupported query type");
+        }
+
+        return true;
+}
+
+static bool
+v3d_end_query_pipe(struct v3d_context *v3d, struct v3d_query *query)
+{
+        struct v3d_query_pipe *pquery = (struct v3d_query_pipe *)query;
+
+        switch (pquery->type) {
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+                /* If we are using PRIMITIVE_COUNTS_FEEDBACK to retrieve
+                 * primitive counts from the GPU (which we need when a GS
+                 * is present), then we need to update our counters now.
+                 */
+                if (v3d->prog.gs)
+                        v3d_update_primitive_counters(v3d);
+                pquery->end = v3d->prims_generated;
+                break;
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                /* If transform feedback has ended, then we have already
+                 * updated the primitive counts at glEndTransformFeedback()
+                 * time. Otherwise, we have to do it now.
+                 */
+                if (v3d->streamout.num_targets > 0)
+                        v3d_update_primitive_counters(v3d);
+                pquery->end = v3d->tf_prims_generated;
+                break;
+        case PIPE_QUERY_OCCLUSION_COUNTER:
+        case PIPE_QUERY_OCCLUSION_PREDICATE:
+        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+                v3d->current_oq = NULL;
+                v3d->dirty |= V3D_DIRTY_OQ;
+                break;
+        default:
+                unreachable("unsupported query type");
+        }
+
+        return true;
+}
+
+static bool
+v3d_get_query_result_pipe(struct v3d_context *v3d, struct v3d_query *query,
+                          bool wait, union pipe_query_result *vresult)
+{
+        struct v3d_query_pipe *pquery = (struct v3d_query_pipe *)query;
+        uint32_t result = 0;
+
+        if (pquery->bo) {
+                v3d_flush_jobs_using_bo(v3d, pquery->bo);
+
+                if (wait) {
+                        if (!v3d_bo_wait(pquery->bo, ~0ull, "query"))
+                                return false;
+                } else {
+                        if (!v3d_bo_wait(pquery->bo, 0, "query"))
+                                return false;
+                }
+
+                /* XXX: Sum up per-core values. */
+                uint32_t *map = v3d_bo_map(pquery->bo);
+                result = *map;
+
+                v3d_bo_unreference(&pquery->bo);
+        }
+
+        switch (pquery->type) {
+        case PIPE_QUERY_OCCLUSION_COUNTER:
+                vresult->u64 = result;
+                break;
+        case PIPE_QUERY_OCCLUSION_PREDICATE:
+        case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+                vresult->b = result != 0;
+                break;
+        case PIPE_QUERY_PRIMITIVES_GENERATED:
+        case PIPE_QUERY_PRIMITIVES_EMITTED:
+                vresult->u64 = pquery->end - pquery->start;
+                break;
+        default:
+                unreachable("unsupported query type");
+        }
+
+        return true;
+}
+
+static const struct v3d_query_funcs pipe_query_funcs = {
+        .destroy_query = v3d_destroy_query_pipe,
+        .begin_query = v3d_begin_query_pipe,
+        .end_query = v3d_end_query_pipe,
+        .get_query_result = v3d_get_query_result_pipe,
+};
+
+struct pipe_query *
+v3d_create_query_pipe(struct v3d_context *v3d, unsigned query_type, unsigned index)
+{
+        if (query_type >= PIPE_QUERY_DRIVER_SPECIFIC)
+                return NULL;
+
+        struct v3d_query_pipe *pquery = calloc(1, sizeof(*pquery));
+        struct v3d_query *query = &pquery->base;
+
+        pquery->type = query_type;
+        query->funcs = &pipe_query_funcs;
+
+        /* Note that struct pipe_query isn't actually defined anywhere. */
+        return (struct pipe_query *)query;
+}



More information about the mesa-commit mailing list