Mesa (main): v3d: Update prim_counts when prims generated query in flight without TF

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Nov 11 08:23:26 UTC 2021


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

Author: Neil Roberts <nroberts at igalia.com>
Date:   Fri Oct 29 17:56:39 2021 +0200

v3d: Update prim_counts when prims generated query in flight without TF

In order to implement GL_PRIMITIVES_GENERATED, v3d allocates a small
resource and adds a command to the job to store the prim counts to it.
However it was only doing this when TF was enabled which meant that if
the query was used with a geometry shader but no TF then the query would
always be zero. This patch makes the driver keep track of how many
PRIMITIVES_GENERATED queries are in flight and then enable writing the
prim count if its more than zero.

Fix dEQP-GLES31.functional.geometry_shading.query.primitives_generated_*

v2: Update CI expectations and references to fixed tests in commit log.
v3: - Add comment that GL_PRIMITIVES_GENERATED query is included because
      OES_geometry_shader, but it is not part of OpenGL ES 3.1. (Iago)
    - Update Fixes to commit introducing geometry shaders. (Iago)

Fixes: a1b7c084 ("v3d: fix primitive queries for geometry shaders")
Signed-off-by: Neil Roberts <nroberts at igalia.com>
Signed-off-by: Jose Maria Casanova Crespo <jmcasanova at igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13712>

---

 src/broadcom/ci/v3d-rpi4-fails.txt       |  5 -----
 src/gallium/drivers/v3d/v3d_context.c    | 14 ++++++++++++++
 src/gallium/drivers/v3d/v3d_context.h    |  6 ++++++
 src/gallium/drivers/v3d/v3d_job.c        | 22 ++++++++++++++++++----
 src/gallium/drivers/v3d/v3d_query_pipe.c |  2 ++
 src/gallium/drivers/v3d/v3dx_job.c       |  2 +-
 src/gallium/drivers/v3d/v3dx_state.c     | 10 ++--------
 7 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/src/broadcom/ci/v3d-rpi4-fails.txt b/src/broadcom/ci/v3d-rpi4-fails.txt
index 4c1db5ba04b..7fcef91d4e2 100644
--- a/src/broadcom/ci/v3d-rpi4-fails.txt
+++ b/src/broadcom/ci/v3d-rpi4-fails.txt
@@ -1,8 +1,3 @@
-dEQP-GLES31.functional.geometry_shading.query.primitives_generated_amplification,Fail
-dEQP-GLES31.functional.geometry_shading.query.primitives_generated_instanced,Fail
-dEQP-GLES31.functional.geometry_shading.query.primitives_generated_no_amplification,Fail
-dEQP-GLES31.functional.geometry_shading.query.primitives_generated_partial_primitives,Fail
-
 glx at glx-make-current,Crash
 glx at glx-multi-window-single-context,Fail
 glx at glx-multithread-buffer,Fail
diff --git a/src/gallium/drivers/v3d/v3d_context.c b/src/gallium/drivers/v3d/v3d_context.c
index 50a0e602e34..dd7928ace15 100644
--- a/src/gallium/drivers/v3d/v3d_context.c
+++ b/src/gallium/drivers/v3d/v3d_context.c
@@ -193,6 +193,20 @@ v3d_get_real_line_width(struct v3d_context *v3d)
         return width;
 }
 
+void
+v3d_ensure_prim_counts_allocated(struct v3d_context *ctx)
+{
+        if (ctx->prim_counts)
+                return;
+
+        /* Init all 7 counters and 1 padding to 0 */
+        uint32_t zeroes[8] = { 0 };
+        u_upload_data(ctx->uploader,
+                      0, sizeof(zeroes), 32, zeroes,
+                      &ctx->prim_counts_offset,
+                      &ctx->prim_counts);
+}
+
 void
 v3d_flag_dirty_sampler_state(struct v3d_context *v3d,
                              enum pipe_shader_type shader)
diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h
index 964289c015b..7b3daf4df54 100644
--- a/src/gallium/drivers/v3d/v3d_context.h
+++ b/src/gallium/drivers/v3d/v3d_context.h
@@ -447,6 +447,8 @@ struct v3d_job {
          */
         bool tf_enabled;
 
+        bool needs_primitives_generated;
+
         /**
          * Current EZ state for drawing. Updated at the start of draw after
          * we've decided on the shader being rendered.
@@ -574,6 +576,8 @@ struct v3d_context {
         uint32_t tf_prims_generated;
         uint32_t prims_generated;
 
+        uint32_t n_primitives_generated_queries_in_flight;
+
         struct pipe_poly_stipple stipple;
         struct pipe_clip_state clip;
         struct pipe_viewport_state viewport;
@@ -764,6 +768,8 @@ bool v3d_line_smoothing_enabled(struct v3d_context *v3d);
 
 float v3d_get_real_line_width(struct v3d_context *v3d);
 
+void v3d_ensure_prim_counts_allocated(struct v3d_context *ctx);
+
 void v3d_flag_dirty_sampler_state(struct v3d_context *v3d,
                                   enum pipe_shader_type shader);
 
diff --git a/src/gallium/drivers/v3d/v3d_job.c b/src/gallium/drivers/v3d/v3d_job.c
index 0e646241652..8e62130f96c 100644
--- a/src/gallium/drivers/v3d/v3d_job.c
+++ b/src/gallium/drivers/v3d/v3d_job.c
@@ -482,6 +482,16 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
         if (!job->needs_flush)
                 goto done;
 
+        /* The GL_PRIMITIVES_GENERATED query is included with
+         * OES_geometry_shader.
+         */
+        job->needs_primitives_generated =
+                v3d->n_primitives_generated_queries_in_flight > 0 &&
+                v3d->prog.gs;
+
+        if (job->needs_primitives_generated)
+                v3d_ensure_prim_counts_allocated(v3d);
+
         if (screen->devinfo.ver >= 41)
                 v3d41_emit_rcl(job);
         else
@@ -553,9 +563,11 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
                 }
 
                 /* If we are submitting a job in the middle of transform
-                 * feedback we need to read the primitive counts and accumulate
-                 * them, otherwise they will be reset at the start of the next
-                 * draw when we emit the Tile Binning Mode Configuration packet.
+                 * feedback or there is a primitives generated query with a
+                 * geometry shader then we need to read the primitive counts
+                 * and accumulate them, otherwise they will be reset at the
+                 * start of the next draw when we emit the Tile Binning Mode
+                 * Configuration packet.
                  *
                  * If the job doesn't have any TF draw calls, then we know
                  * the primitive count must be zero and we can skip stalling
@@ -565,7 +577,9 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
                  * to us reading an obsolete (possibly non-zero) value from
                  * the GPU counters.
                  */
-                if (v3d->streamout.num_targets && job->tf_draw_calls_queued > 0)
+                if (job->needs_primitives_generated ||
+                    (v3d->streamout.num_targets &&
+                     job->tf_draw_calls_queued > 0))
                         v3d_read_and_accumulate_primitive_counters(v3d);
         }
 
diff --git a/src/gallium/drivers/v3d/v3d_query_pipe.c b/src/gallium/drivers/v3d/v3d_query_pipe.c
index eafb7ec6106..7fdc7ac6680 100644
--- a/src/gallium/drivers/v3d/v3d_query_pipe.c
+++ b/src/gallium/drivers/v3d/v3d_query_pipe.c
@@ -69,6 +69,7 @@ v3d_begin_query_pipe(struct v3d_context *v3d, struct v3d_query *query)
                 if (v3d->prog.gs)
                         v3d_update_primitive_counters(v3d);
                 pquery->start = v3d->prims_generated;
+                v3d->n_primitives_generated_queries_in_flight++;
                 break;
         case PIPE_QUERY_PRIMITIVES_EMITTED:
                 /* If we are inside transform feedback we need to update the
@@ -109,6 +110,7 @@ v3d_end_query_pipe(struct v3d_context *v3d, struct v3d_query *query)
                 if (v3d->prog.gs)
                         v3d_update_primitive_counters(v3d);
                 pquery->end = v3d->prims_generated;
+                v3d->n_primitives_generated_queries_in_flight--;
                 break;
         case PIPE_QUERY_PRIMITIVES_EMITTED:
                 /* If transform feedback has ended, then we have already
diff --git a/src/gallium/drivers/v3d/v3dx_job.c b/src/gallium/drivers/v3d/v3dx_job.c
index 40d6f16a4e2..d48c97f99ff 100644
--- a/src/gallium/drivers/v3d/v3dx_job.c
+++ b/src/gallium/drivers/v3d/v3dx_job.c
@@ -39,7 +39,7 @@ void v3dX(bcl_epilogue)(struct v3d_context *v3d, struct v3d_job *job)
 #endif
                                                 cl_packet_length(FLUSH));
 
-                if (job->tf_enabled) {
+                if (job->tf_enabled || job->needs_primitives_generated) {
                         /* Write primitive counts to memory. */
                         assert(v3d->prim_counts);
                         struct v3d_resource *rsc =
diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c
index 3315421b9b5..e266588a2a0 100644
--- a/src/gallium/drivers/v3d/v3dx_state.c
+++ b/src/gallium/drivers/v3d/v3dx_state.c
@@ -1243,14 +1243,8 @@ v3d_set_stream_output_targets(struct pipe_context *pctx,
         so->num_targets = num_targets;
 
         /* Create primitive counters BO if needed */
-        if (num_targets > 0 && !ctx->prim_counts) {
-                /* Init all 7 counters and 1 padding to 0 */
-                uint32_t zeroes[8] = { 0 };
-                u_upload_data(ctx->uploader,
-                              0, sizeof(zeroes), 32, zeroes,
-                              &ctx->prim_counts_offset,
-                              &ctx->prim_counts);
-        }
+        if (num_targets > 0)
+                v3d_ensure_prim_counts_allocated(ctx);
 
         ctx->dirty |= V3D_DIRTY_STREAMOUT;
 }



More information about the mesa-commit mailing list