Mesa (main): panfrost: Split out prepare_rsd into a vtbl

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 7 13:34:29 UTC 2021


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

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Tue Jul  6 17:48:46 2021 -0400

panfrost: Split out prepare_rsd into a vtbl

This needs to be per-gen, but the rest of the caller does not, so let's
split this out. iris makes extensive use of this vtbl pattern for cold
paths like this one.

Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Acked-by: Boris Brezillon <boris.brezillon at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11745>

---

 src/gallium/drivers/panfrost/pan_assemble.c  | 20 +++++---------------
 src/gallium/drivers/panfrost/pan_cmdstream.c | 27 +++++++++++++++++++++++++++
 src/gallium/drivers/panfrost/pan_screen.c    |  2 ++
 src/gallium/drivers/panfrost/pan_screen.h    | 16 ++++++++++++++++
 4 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c
index b4c3dd7490a..1638c9aef0e 100644
--- a/src/gallium/drivers/panfrost/pan_assemble.c
+++ b/src/gallium/drivers/panfrost/pan_assemble.c
@@ -48,6 +48,7 @@ panfrost_shader_compile(struct pipe_screen *pscreen,
                         gl_shader_stage stage,
                         struct panfrost_shader_state *state)
 {
+        struct panfrost_screen *screen = pan_screen(pscreen);
         struct panfrost_device *dev = pan_device(pscreen);
 
         nir_shader *s;
@@ -84,22 +85,11 @@ panfrost_shader_compile(struct pipe_screen *pscreen,
                                 binary.data, binary.size, 128));
         }
 
-        struct mali_renderer_state_packed *out = &state->partial_rsd;
 
-        /* Upload RSDs for non-fragment shaders. Fragment shaders need draw
-         * time finalization based on the renderer state. */
-        if (stage != MESA_SHADER_FRAGMENT) {
-                struct panfrost_ptr ptr =
-                        pan_pool_alloc_desc(&desc_pool->base, RENDERER_STATE);
-
-                state->state = panfrost_pool_take_ref(desc_pool, ptr.gpu);
-                out = ptr.cpu;
-        }
-
-        pan_pack(out, RENDERER_STATE, cfg) {
-                pan_shader_prepare_rsd(dev, &state->info, state->bin.gpu,
-                                       &cfg);
-        }
+        /* Don't upload RSD for fragment shaders since they need draw-time
+         * merging for e.g. depth/stencil/alpha */
+        bool upload = stage != MESA_SHADER_FRAGMENT;
+        screen->vtbl.prepare_rsd(dev, state, desc_pool, upload);
 
         panfrost_analyze_sysvals(state);
 
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index 8ba599d0024..84d1865eb9a 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -3423,6 +3423,33 @@ panfrost_create_sampler_view(
         return (struct pipe_sampler_view *) so;
 }
 
+static void
+prepare_rsd(struct panfrost_device *dev,
+            struct panfrost_shader_state *state,
+            struct panfrost_pool *pool, bool upload)
+{
+        struct mali_renderer_state_packed *out = &state->partial_rsd;
+
+        if (upload) {
+                struct panfrost_ptr ptr =
+                        pan_pool_alloc_desc(&pool->base, RENDERER_STATE);
+
+                state->state = panfrost_pool_take_ref(pool, ptr.gpu);
+                out = ptr.cpu;
+        }
+
+        pan_pack(out, RENDERER_STATE, cfg) {
+                pan_shader_prepare_rsd(dev, &state->info, state->bin.gpu,
+                                       &cfg);
+        }
+}
+
+void
+panfrost_cmdstream_screen_init(struct panfrost_screen *screen)
+{
+        screen->vtbl.prepare_rsd = prepare_rsd;
+}
+
 void
 panfrost_cmdstream_context_init(struct pipe_context *pipe)
 {
diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c
index f908be30a7c..55acd1c600e 100644
--- a/src/gallium/drivers/panfrost/pan_screen.c
+++ b/src/gallium/drivers/panfrost/pan_screen.c
@@ -896,5 +896,7 @@ panfrost_create_screen(int fd, struct renderonly *ro)
         pan_blitter_init(dev, &screen->blitter.bin_pool.base,
                          &screen->blitter.desc_pool.base);
 
+        panfrost_cmdstream_screen_init(screen);
+
         return &screen->base;
 }
diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h
index eb8d25d41a6..cb70de0c541 100644
--- a/src/gallium/drivers/panfrost/pan_screen.h
+++ b/src/gallium/drivers/panfrost/pan_screen.h
@@ -43,6 +43,17 @@
 struct panfrost_batch;
 struct panfrost_context;
 struct panfrost_resource;
+struct panfrost_shader_state;
+
+/* Virtual table of per-generation (GenXML) functions */
+
+struct panfrost_vtable {
+        /* Prepares the renderer state descriptor for a given compiled shader,
+         * and if desired uploads it as well */
+        void (*prepare_rsd)(struct panfrost_device *,
+                            struct panfrost_shader_state *,
+                            struct panfrost_pool *, bool);
+};
 
 struct panfrost_screen {
         struct pipe_screen base;
@@ -54,6 +65,8 @@ struct panfrost_screen {
         struct {
                 struct panfrost_pool bin_pool;
         } indirect_draw;
+
+        struct panfrost_vtable vtbl;
 };
 
 static inline struct panfrost_screen *
@@ -71,4 +84,7 @@ pan_device(struct pipe_screen *p)
 struct pipe_fence_handle *
 panfrost_fence_create(struct panfrost_context *ctx);
 
+void
+panfrost_cmdstream_screen_init(struct panfrost_screen *screen);
+
 #endif /* PAN_SCREEN_H */



More information about the mesa-commit mailing list