Mesa (main): panfrost: Implement provoking vertices on Valhall

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jun 20 19:00:15 UTC 2022


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

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Wed Jun 15 16:06:00 2022 -0400

panfrost: Implement provoking vertices on Valhall

Starting with Valhall, the provoking vertex state is specified per-framebuffer
(batch) instead of per-draw. We use the pan_tristate infrastructure to translate
between desktop OpenGL's per-draw semantics to Valhall's per-framebuffer
semantic. This is notably not required for GLES or Vulkan.

If the provoking vertex is unset when the tiler context is generated, it could
be set (incompatibly) later in the batch, and the tiler context's provoking
vertex field would no longer match the framebuffer's. That would violate a
hardware invariant. To ensure that doesn't happen, we make sure to set provoking
vertexes *before* generating the tiler context so it can't change after.

Fixes arb-provoking-vertex-render on Valhall.

Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17068>

---

 src/gallium/drivers/panfrost/pan_cmdstream.c | 12 +++++++++++-
 src/gallium/drivers/panfrost/pan_job.c       |  1 +
 src/gallium/drivers/panfrost/pan_job.h       |  1 +
 src/panfrost/lib/pan_cs.c                    |  5 +++++
 src/panfrost/lib/pan_cs.h                    |  3 ++-
 5 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index c8051b72d7f..c86ee288d96 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -3101,9 +3101,17 @@ panfrost_batch_get_bifrost_tiler(struct panfrost_batch *batch, unsigned vertex_c
 
         mali_ptr heap = t.gpu;
 
+        /* We emit this descriptor after the first draw. The provoking vertex
+         * for the batch should have already been set (on Valhall, where it is a
+         * property of the batch).
+         */
+        if (PAN_ARCH >= 9)
+                assert(pan_tristate_is_defined(batch->first_provoking_vertex));
+
         t = pan_pool_alloc_desc(&batch->pool.base, TILER_CONTEXT);
         GENX(pan_emit_tiler_ctx)(dev, batch->key.width, batch->key.height,
                                  util_framebuffer_get_num_samples(&batch->key),
+                                 pan_tristate_get(batch->first_provoking_vertex),
                                  heap, t.cpu);
 
         batch->tiler_ctx.bifrost = t.gpu;
@@ -3975,8 +3983,10 @@ panfrost_compatible_batch_state(struct panfrost_batch *batch)
         struct pipe_rasterizer_state *rast = &ctx->rasterizer->base;
 
         bool coord = (rast->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT);
+        bool first = rast->flatshade_first;
 
-        return pan_tristate_set(&batch->sprite_coord_origin, coord);
+        return pan_tristate_set(&batch->sprite_coord_origin, coord) &&
+               pan_tristate_set(&batch->first_provoking_vertex, first);
 }
 
 static void
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index 6df87ea7016..71703d6b7e4 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -448,6 +448,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
         fb->nr_samples = util_framebuffer_get_num_samples(&batch->key);
         fb->rt_count = batch->key.nr_cbufs;
         fb->sprite_coord_origin = pan_tristate_get(batch->sprite_coord_origin);
+        fb->first_provoking_vertex = pan_tristate_get(batch->first_provoking_vertex);
 
         static const unsigned char id_swz[] = {
                 PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W,
diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
index 7ca6fe552a6..f79197b2059 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -200,6 +200,7 @@ struct panfrost_batch {
          * per draw.
          */
         struct pan_tristate sprite_coord_origin;
+        struct pan_tristate first_provoking_vertex;
 
         /* Referenced resources */
         struct set *resources;
diff --git a/src/panfrost/lib/pan_cs.c b/src/panfrost/lib/pan_cs.c
index 263f808aa11..377fef670c9 100644
--- a/src/panfrost/lib/pan_cs.c
+++ b/src/panfrost/lib/pan_cs.c
@@ -764,6 +764,7 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
 
 #if PAN_ARCH >= 9
                 cfg.point_sprite_coord_origin_max_y = fb->sprite_coord_origin;
+                cfg.first_provoking_vertex = fb->first_provoking_vertex;
 #endif
         }
 
@@ -937,6 +938,7 @@ void
 GENX(pan_emit_tiler_ctx)(const struct panfrost_device *dev,
                          unsigned fb_width, unsigned fb_height,
                          unsigned nr_samples,
+                         bool first_provoking_vertex,
                          mali_ptr heap,
                          void *out)
 {
@@ -959,6 +961,9 @@ GENX(pan_emit_tiler_ctx)(const struct panfrost_device *dev,
                 tiler.fb_height = fb_height;
                 tiler.heap = heap;
                 tiler.sample_pattern = pan_sample_pattern(nr_samples);
+#if PAN_ARCH >= 9
+                tiler.first_provoking_vertex = first_provoking_vertex;
+#endif
         }
 }
 #endif
diff --git a/src/panfrost/lib/pan_cs.h b/src/panfrost/lib/pan_cs.h
index c2beddcdcee..db4dcbf089a 100644
--- a/src/panfrost/lib/pan_cs.h
+++ b/src/panfrost/lib/pan_cs.h
@@ -120,6 +120,7 @@ struct pan_fb_info {
 
         /* Only used on Valhall */
         bool sprite_coord_origin;
+        bool first_provoking_vertex;
 };
 
 static inline unsigned
@@ -169,7 +170,7 @@ GENX(pan_emit_tiler_heap)(const struct panfrost_device *dev,
 void
 GENX(pan_emit_tiler_ctx)(const struct panfrost_device *dev,
                          unsigned fb_width, unsigned fb_height,
-                         unsigned nr_samples,
+                         unsigned nr_samples, bool first_provoking_vertex,
                          mali_ptr heap,
                          void *out);
 #endif



More information about the mesa-commit mailing list