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

Author: Boris Brezillon <[email protected]>
Date:   Thu Oct  8 14:17:23 2020 +0200

panfrost: Move the blend shader cache at the context level

Blend shaders can be shared among blend states, so let's move the blend
shader one level up so we don't have to re-create/re-compile shaders
when another blend state already asked for it.

Signed-off-by: Boris Brezillon <[email protected]>
Reviewed-by: Alyssa Rosenzweig <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7066>

---

 src/gallium/drivers/panfrost/pan_blend.h         | 29 +++++++++++++++---------
 src/gallium/drivers/panfrost/pan_blend_cso.c     | 27 ++++++++++++++++------
 src/gallium/drivers/panfrost/pan_blend_shaders.c | 20 ++++++++--------
 src/gallium/drivers/panfrost/pan_blend_shaders.h |  3 +--
 src/gallium/drivers/panfrost/pan_context.c       | 20 ++++++++++++----
 src/gallium/drivers/panfrost/pan_context.h       |  1 +
 6 files changed, 64 insertions(+), 36 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_blend.h 
b/src/gallium/drivers/panfrost/pan_blend.h
index 8e30d677d05..901d54a4125 100644
--- a/src/gallium/drivers/panfrost/pan_blend.h
+++ b/src/gallium/drivers/panfrost/pan_blend.h
@@ -33,19 +33,31 @@
 
 struct panfrost_bo;
 
+struct panfrost_blend_shader_key {
+        /* RT format */
+        enum pipe_format format;
+
+        /* Render target */
+        unsigned rt : 3;
+
+        /* Blend shader uses blend constants */
+        unsigned has_constants : 1;
+
+        /* Logic Op info */
+        unsigned logicop_enable : 1;
+        unsigned logicop_func:4;
+
+        struct pipe_rt_blend_state equation;
+};
+
 /* An internal blend shader descriptor, from the compiler */
 
 struct panfrost_blend_shader {
+        struct panfrost_blend_shader_key key;
         struct panfrost_context *ctx;
 
         nir_shader *nir;
 
-        /* Render target */
-        unsigned rt;
-
-        /* RT format */
-        enum pipe_format format;
-
         /* Blend constants */
         float constants[4];
 
@@ -92,11 +104,6 @@ struct panfrost_blend_rt {
 
         /* Properties of the blend mode */
         bool opaque, load_dest, no_colour;
-
-        /* Regardless of fixed-function blending, this is a map of pipe_format
-         * to panfrost_blend_shader */
-
-        struct hash_table_u64 *shaders;
 };
 
 struct panfrost_blend_state {
diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.c 
b/src/gallium/drivers/panfrost/pan_blend_cso.c
index e1f279d2dfc..15308d2eb08 100644
--- a/src/gallium/drivers/panfrost/pan_blend_cso.c
+++ b/src/gallium/drivers/panfrost/pan_blend_cso.c
@@ -77,16 +77,30 @@ panfrost_get_blend_shader(struct panfrost_context *ctx,
         assert(fmt != 0);
 
         /* Check the cache. Key by the RT and format */
-        struct hash_table_u64 *shaders = blend->rt[rt].shaders;
-        unsigned key = (fmt << 4) | ((constants != NULL) << 3) | rt;
+        struct hash_table *shaders = ctx->blend_shaders;
+        struct panfrost_blend_shader_key key = {
+                .rt = rt,
+                .format = fmt,
+                .has_constants = constants != NULL,
+                .logicop_enable = blend->base.logicop_enable,
+        };
 
-        struct panfrost_blend_shader *shader =
-                _mesa_hash_table_u64_search(shaders, key);
+        if (blend->base.logicop_enable) {
+                key.logicop_func = blend->base.logicop_func;
+        } else {
+                unsigned idx = blend->base.independent_blend_enable ? rt : 0;
+
+                if (blend->base.rt[idx].blend_enable)
+                        key.equation = blend->base.rt[idx];
+        }
+
+        struct hash_entry *he = _mesa_hash_table_search(shaders, &key);
+        struct panfrost_blend_shader *shader = he ? he->data : NULL;
 
         if (!shader) {
                 /* Cache miss. Build one instead, cache it, and go */
-                shader = panfrost_create_blend_shader(ctx, blend, fmt, rt);
-                _mesa_hash_table_u64_insert(shaders, key, shader);
+                shader = panfrost_create_blend_shader(ctx, blend, &key);
+                _mesa_hash_table_insert(shaders, &shader->key, shader);
         }
 
         panfrost_compile_blend_shader(shader, constants);
@@ -114,7 +128,6 @@ panfrost_create_blend_state(struct pipe_context *pipe,
                 struct pipe_rt_blend_state pipe = blend->rt[g];
 
                 struct panfrost_blend_rt *rt = &so->rt[c];
-                rt->shaders = _mesa_hash_table_u64_create(so);
 
                 /* Logic ops are always shader */
                 if (blend->logicop_enable) {
diff --git a/src/gallium/drivers/panfrost/pan_blend_shaders.c 
b/src/gallium/drivers/panfrost/pan_blend_shaders.c
index b0c6d2738e2..fee3bbe24ca 100644
--- a/src/gallium/drivers/panfrost/pan_blend_shaders.c
+++ b/src/gallium/drivers/panfrost/pan_blend_shaders.c
@@ -132,23 +132,21 @@ nir_iclamp(nir_builder *b, nir_ssa_def *v, int32_t lo, 
int32_t hi)
 struct panfrost_blend_shader *
 panfrost_create_blend_shader(struct panfrost_context *ctx,
                              struct panfrost_blend_state *state,
-                             enum pipe_format format,
-                             unsigned rt)
+                             const struct panfrost_blend_shader_key *key)
 {
-        struct panfrost_blend_shader *res = rzalloc(state, struct 
panfrost_blend_shader);
+        struct panfrost_blend_shader *res = rzalloc(ctx, struct 
panfrost_blend_shader);
 
         res->ctx = ctx;
-        res->rt = rt;
-        res->format = format;
+        res->key = *key;
 
         /* Build the shader */
 
-        nir_shader *shader = nir_shader_create(state, MESA_SHADER_FRAGMENT, 
&midgard_nir_options, NULL);
+        nir_shader *shader = nir_shader_create(ctx, MESA_SHADER_FRAGMENT, 
&midgard_nir_options, NULL);
         nir_function *fn = nir_function_create(shader, "main");
         nir_function_impl *impl = nir_function_impl_create(fn);
 
         const struct util_format_description *format_desc =
-                util_format_description(format);
+                util_format_description(key->format);
 
         nir_alu_type T = pan_unpacked_type_for_format(format_desc);
         enum glsl_base_type g =
@@ -201,8 +199,8 @@ panfrost_create_blend_shader(struct panfrost_context *ctx,
         /* Build a trivial blend shader */
         nir_store_var(b, c_out, s_src[0], 0xFF);
 
-        nir_lower_blend_options options = nir_make_options(&state->base, rt);
-        options.format = format;
+        nir_lower_blend_options options = nir_make_options(&state->base, 
key->rt);
+        options.format = key->format;
         options.src1 = s_src[1];
 
         if (T == nir_type_float16)
@@ -235,8 +233,8 @@ panfrost_compile_blend_shader(struct panfrost_blend_shader 
*shader,
         struct panfrost_compile_inputs inputs = {
                 .gpu_id = dev->gpu_id,
                 .is_blend = true,
-                .blend.rt = shader->rt,
-                .rt_formats = {shader->format},
+                .blend.rt = shader->key.rt,
+                .rt_formats = {shader->key.format},
         };
 
         if (constants)
diff --git a/src/gallium/drivers/panfrost/pan_blend_shaders.h 
b/src/gallium/drivers/panfrost/pan_blend_shaders.h
index 92004896898..3c47f0b04fa 100644
--- a/src/gallium/drivers/panfrost/pan_blend_shaders.h
+++ b/src/gallium/drivers/panfrost/pan_blend_shaders.h
@@ -34,8 +34,7 @@
 struct panfrost_blend_shader *
 panfrost_create_blend_shader(struct panfrost_context *ctx,
                              struct panfrost_blend_state *state,
-                             enum pipe_format format,
-                             unsigned rt);
+                             const struct panfrost_blend_shader_key *key);
 
 void
 panfrost_compile_blend_shader(struct panfrost_blend_shader *shader,
diff --git a/src/gallium/drivers/panfrost/pan_context.c 
b/src/gallium/drivers/panfrost/pan_context.c
index 06afce010fa..adc0cd8a431 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -1504,6 +1504,16 @@ panfrost_set_stream_output_targets(struct pipe_context 
*pctx,
         so->num_targets = num_targets;
 }
 
+static uint32_t panfrost_shader_key_hash(const void *key)
+{
+        return _mesa_hash_data(key, sizeof(struct panfrost_blend_shader_key));
+}
+
+static bool panfrost_shader_key_equal(const void *a, const void *b)
+{
+        return !memcmp(a, b, sizeof(struct panfrost_blend_shader_key));
+}
+
 struct pipe_context *
 panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
 {
@@ -1607,11 +1617,11 @@ panfrost_create_context(struct pipe_screen *screen, 
void *priv, unsigned flags)
 
         panfrost_batch_init(ctx);
 
-        if (!(dev->quirks & IS_BIFROST)) {
-                ctx->blit_blend = rzalloc(ctx, struct panfrost_blend_state);
-                for (unsigned c = 0; c < PIPE_MAX_COLOR_BUFS; ++c)
-                        ctx->blit_blend->rt[c].shaders = 
_mesa_hash_table_u64_create(ctx);
-        }
+        ctx->blit_blend = rzalloc(ctx, struct panfrost_blend_state);
+        ctx->blend_shaders =
+                _mesa_hash_table_create(ctx,
+                                        panfrost_shader_key_hash,
+                                        panfrost_shader_key_equal);
 
         /* By default mask everything on */
         ctx->sample_mask = ~0;
diff --git a/src/gallium/drivers/panfrost/pan_context.h 
b/src/gallium/drivers/panfrost/pan_context.h
index 130989f50a0..f7251136abb 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -179,6 +179,7 @@ struct panfrost_context {
         unsigned min_samples;
 
         struct panfrost_blend_state *blit_blend;
+        struct hash_table *blend_shaders;
 };
 
 /* Corresponds to the CSO */

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to