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