Mesa (main): panfrost: Simplify shader key architecture
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon May 2 14:14:35 UTC 2022
Module: Mesa
Branch: main
Commit: 755f30fb185f186c20371adf4d29edb78587c454
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=755f30fb185f186c20371adf4d29edb78587c454
Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date: Tue Apr 26 12:37:59 2022 -0400
panfrost: Simplify shader key architecture
Rather than clever key compare/initialize code, let's make the shader keys plain
old data. This makes it easier both to extend and to optimize the shader keys.
Keys are compared with a simple memcmp(). I considered a hash table but I don't
think we have enough variants (or large enough keys) to justify the overhead.
Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16173>
---
src/gallium/drivers/panfrost/pan_assemble.c | 4 +-
src/gallium/drivers/panfrost/pan_context.c | 60 ++++++++++-------------------
src/gallium/drivers/panfrost/pan_context.h | 21 ++++++++--
3 files changed, 39 insertions(+), 46 deletions(-)
diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c
index af01b3dab1f..6d10b2deb60 100644
--- a/src/gallium/drivers/panfrost/pan_assemble.c
+++ b/src/gallium/drivers/panfrost/pan_assemble.c
@@ -49,7 +49,7 @@ panfrost_shader_compile(struct pipe_screen *pscreen,
/* Lower this early so the backends don't have to worry about it */
if (s->info.stage == MESA_SHADER_FRAGMENT)
- NIR_PASS_V(s, nir_lower_fragcolor, state->nr_cbufs);
+ NIR_PASS_V(s, nir_lower_fragcolor, state->key.fs.nr_cbufs);
/* Call out to Midgard compiler given the above NIR */
struct panfrost_compile_inputs inputs = {
@@ -57,7 +57,7 @@ panfrost_shader_compile(struct pipe_screen *pscreen,
.shaderdb = !!(dev->debug & PAN_DBG_PRECOMPILE),
};
- memcpy(inputs.rt_formats, state->rt_formats, sizeof(inputs.rt_formats));
+ memcpy(inputs.rt_formats, state->key.fs.rt_formats, sizeof(inputs.rt_formats));
struct util_dynarray binary;
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index f4e2249e5e0..0ede262299e 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -360,18 +360,22 @@ panfrost_bind_sampler_states(
memcpy(ctx->samplers[shader], sampler, num_sampler * sizeof (void *));
}
-static bool
-panfrost_variant_matches(
- struct panfrost_context *ctx,
- struct panfrost_shader_state *variant,
- enum pipe_shader_type type)
+static void
+panfrost_build_key(struct panfrost_context *ctx,
+ struct panfrost_shader_key *key,
+ nir_shader *nir)
{
- if (variant->info.stage == MESA_SHADER_FRAGMENT &&
- variant->info.fs.outputs_read) {
- struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer;
+ /* We don't currently have vertex shader variants */
+ if (nir->info.stage != MESA_SHADER_FRAGMENT)
+ return;
+
+ struct panfrost_device *dev = pan_device(ctx->base.screen);
+ struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer;
+
+ key->fs.nr_cbufs = fb->nr_cbufs;
- unsigned i;
- BITSET_FOREACH_SET(i, &variant->info.fs.outputs_read, 8) {
+ if (dev->arch <= 5) {
+ u_foreach_bit(i, (nir->info.outputs_read >> FRAG_RESULT_DATA0)) {
enum pipe_format fmt = PIPE_FORMAT_R8G8B8A8_UNORM;
if ((fb->nr_cbufs > i) && fb->cbufs[i])
@@ -380,17 +384,9 @@ panfrost_variant_matches(
if (panfrost_blendable_formats_v6[fmt].internal)
fmt = PIPE_FORMAT_NONE;
- if (variant->rt_formats[i] != fmt)
- return false;
+ key->fs.rt_formats[i] = fmt;
}
}
-
- if (variant->info.stage == MESA_SHADER_FRAGMENT &&
- variant->nr_cbufs != ctx->pipe_framebuffer.nr_cbufs)
- return false;
-
- /* Otherwise, we're good to go */
- return true;
}
/**
@@ -453,8 +449,11 @@ panfrost_bind_shader_state(
simple_mtx_lock(&variants->lock);
+ struct panfrost_shader_key key = { 0 };
+ panfrost_build_key(ctx, &key, variants->nir);
+
for (unsigned i = 0; i < variants->variant_count; ++i) {
- if (panfrost_variant_matches(ctx, &variants->variants[i], type)) {
+ if (memcmp(&key, &variants->variants[i].key, sizeof(key)) == 0) {
variant = i;
break;
}
@@ -483,32 +482,13 @@ panfrost_bind_shader_state(
(variants->variant_space - old_space) * msize);
}
- struct panfrost_shader_state *v =
- &variants->variants[variant];
-
- if (type == PIPE_SHADER_FRAGMENT) {
- struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer;
- v->nr_cbufs = fb->nr_cbufs;
-
- for (unsigned i = 0; i < fb->nr_cbufs; ++i) {
- enum pipe_format fmt = PIPE_FORMAT_R8G8B8A8_UNORM;
-
- if ((fb->nr_cbufs > i) && fb->cbufs[i])
- fmt = fb->cbufs[i]->format;
-
- if (panfrost_blendable_formats_v6[fmt].internal)
- fmt = PIPE_FORMAT_NONE;
-
- v->rt_formats[i] = fmt;
- }
- }
+ variants->variants[variant].key = key;
}
/* Select this variant */
variants->active_variant = variant;
struct panfrost_shader_state *shader_state = &variants->variants[variant];
- assert(panfrost_variant_matches(ctx, shader_state, type));
/* We finally have a variant, so compile it */
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index 15b5cd59996..b4ad06dbd14 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -252,7 +252,22 @@ struct pan_linkage {
#define RSD_WORDS 16
/* Variants bundle together to form the backing CSO, bundling multiple
- * shaders with varying emulated features baked in */
+ * shaders with varying emulated features baked in
+ */
+struct panfrost_fs_key {
+ /* Number of colour buffers */
+ unsigned nr_cbufs;
+
+ /* Midgard shaders that read the tilebuffer must be keyed for
+ * non-blendable formats
+ */
+ enum pipe_format rt_formats[8];
+};
+
+struct panfrost_shader_key {
+ /* If we need vertex shader keys, union it in */
+ struct panfrost_fs_key fs;
+};
/* A shader state corresponds to the actual, current variant of the shader */
struct panfrost_shader_state {
@@ -273,9 +288,7 @@ struct panfrost_shader_state {
struct pipe_stream_output_info stream_output;
uint64_t so_mask;
- /* Variants */
- enum pipe_format rt_formats[8];
- unsigned nr_cbufs;
+ struct panfrost_shader_key key;
/* Mask of state that dirties the sysvals */
unsigned dirty_3d, dirty_shader;
More information about the mesa-commit
mailing list