Mesa (master): freedreno: Deduplicate fixup_shader_state()

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Mar 3 22:22:22 UTC 2021


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

Author: Rob Clark <robdclark at chromium.org>
Date:   Wed Mar  3 10:51:55 2021 -0800

freedreno: Deduplicate fixup_shader_state()

All the ir3 gens had the same thing, time to move it out into a shared
helper.

The keeping the storage in fdN_context is to avoid namespace clashes
between ir3 and ir2.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9394>

---

 src/gallium/drivers/freedreno/a3xx/fd3_context.c  |  2 ++
 src/gallium/drivers/freedreno/a3xx/fd3_context.h  |  5 +---
 src/gallium/drivers/freedreno/a3xx/fd3_draw.c     | 28 +----------------------
 src/gallium/drivers/freedreno/a4xx/fd4_context.c  |  2 ++
 src/gallium/drivers/freedreno/a4xx/fd4_context.h  |  5 +---
 src/gallium/drivers/freedreno/a4xx/fd4_draw.c     | 28 +----------------------
 src/gallium/drivers/freedreno/a5xx/fd5_context.c  |  1 +
 src/gallium/drivers/freedreno/a5xx/fd5_context.h  |  5 +---
 src/gallium/drivers/freedreno/a5xx/fd5_draw.c     | 28 +----------------------
 src/gallium/drivers/freedreno/a6xx/fd6_context.c  |  1 +
 src/gallium/drivers/freedreno/a6xx/fd6_context.h  |  5 +---
 src/gallium/drivers/freedreno/a6xx/fd6_draw.c     | 28 +----------------------
 src/gallium/drivers/freedreno/freedreno_context.h | 11 +++++++++
 src/gallium/drivers/freedreno/ir3/ir3_gallium.c   | 28 +++++++++++++++++++++++
 src/gallium/drivers/freedreno/ir3/ir3_gallium.h   |  4 ++++
 15 files changed, 57 insertions(+), 124 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.c b/src/gallium/drivers/freedreno/a3xx/fd3_context.c
index 56034716163..344c26604c6 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_context.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_context.c
@@ -72,6 +72,7 @@ static const uint8_t primtypes[] = {
 
 struct pipe_context *
 fd3_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
+	in_dt
 {
 	struct fd_screen *screen = fd_screen(pscreen);
 	struct fd3_context *fd3_ctx = CALLOC_STRUCT(fd3_context);
@@ -85,6 +86,7 @@ fd3_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
 
 	fd3_ctx->base.dev = fd_device_ref(screen->dev);
 	fd3_ctx->base.screen = fd_screen(pscreen);
+	fd3_ctx->base.last.key = &fd3_ctx->last_key;
 
 	pctx->destroy = fd3_context_destroy;
 	pctx->create_blend_state = fd3_blend_state_create;
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.h b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
index 9000a64336e..c5c4f4e4194 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_context.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
@@ -47,10 +47,7 @@ struct fd3_context {
 	struct u_upload_mgr *border_color_uploader;
 	struct pipe_resource *border_color_buf;
 
-	/* some state changes require a different shader variant.  Keep
-	 * track of this so we know when we need to re-emit shader state
-	 * due to variant change.  See fixup_shader_state()
-	 */
+	/* storage for ctx->last.key: */
 	struct ir3_shader_key last_key;
 };
 
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index 4f6d03187ca..2b65198dba4 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -88,32 +88,6 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
 			info, emit->draw, index_offset);
 }
 
-/* fixup dirty shader state in case some "unrelated" (from the state-
- * tracker's perspective) state change causes us to switch to a
- * different variant.
- */
-static void
-fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
-	assert_dt
-{
-	struct fd3_context *fd3_ctx = fd3_context(ctx);
-	struct ir3_shader_key *last_key = &fd3_ctx->last_key;
-
-	if (!ir3_shader_key_equal(last_key, key)) {
-		if (ir3_shader_key_changes_fs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		if (ir3_shader_key_changes_vs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		fd3_ctx->last_key = *key;
-	}
-}
-
 static bool
 fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
              const struct pipe_draw_indirect_info *indirect,
@@ -137,7 +111,7 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
 	if (fd3_needs_manual_clipping(ir3_get_shader(ctx->prog.vs), ctx->rasterizer))
 		emit.key.ucp_enables = ctx->rasterizer->clip_plane_enable;
 
-	fixup_shader_state(ctx, &emit.key);
+	ir3_fixup_shader_state(&ctx->base, &emit.key);
 
 	unsigned dirty = ctx->dirty;
 	const struct ir3_shader_variant *vp = fd3_emit_get_vp(&emit);
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_context.c b/src/gallium/drivers/freedreno/a4xx/fd4_context.c
index ed08f8dfaa9..9bcd63531f4 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_context.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_context.c
@@ -72,6 +72,7 @@ static const uint8_t primtypes[] = {
 
 struct pipe_context *
 fd4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
+	in_dt
 {
 	struct fd_screen *screen = fd_screen(pscreen);
 	struct fd4_context *fd4_ctx = CALLOC_STRUCT(fd4_context);
@@ -85,6 +86,7 @@ fd4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
 
 	fd4_ctx->base.dev = fd_device_ref(screen->dev);
 	fd4_ctx->base.screen = fd_screen(pscreen);
+	fd4_ctx->base.last.key = &fd4_ctx->last_key;
 
 	pctx->destroy = fd4_context_destroy;
 	pctx->create_blend_state = fd4_blend_state_create;
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_context.h b/src/gallium/drivers/freedreno/a4xx/fd4_context.h
index 917e2778b1f..95d0402af8c 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_context.h
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_context.h
@@ -51,10 +51,7 @@ struct fd4_context {
 	/* bitmask of samplers which need astc srgb workaround: */
 	uint16_t vastc_srgb, fastc_srgb;
 
-	/* some state changes require a different shader variant.  Keep
-	 * track of this so we know when we need to re-emit shader state
-	 * due to variant change.  See fixup_shader_state()
-	 */
+	/* storage for ctx->last.key: */
 	struct ir3_shader_key last_key;
 };
 
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
index 91d7beffd1b..9ffdecb973a 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
@@ -72,32 +72,6 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
 			info, emit->indirect, emit->draw, index_offset);
 }
 
-/* fixup dirty shader state in case some "unrelated" (from the state-
- * tracker's perspective) state change causes us to switch to a
- * different variant.
- */
-static void
-fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
-	assert_dt
-{
-	struct fd4_context *fd4_ctx = fd4_context(ctx);
-	struct ir3_shader_key *last_key = &fd4_ctx->last_key;
-
-	if (!ir3_shader_key_equal(last_key, key)) {
-		if (ir3_shader_key_changes_fs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		if (ir3_shader_key_changes_vs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		fd4_ctx->last_key = *key;
-	}
-}
-
 static bool
 fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
              const struct pipe_draw_indirect_info *indirect,
@@ -125,7 +99,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
 		.sprite_coord_mode = ctx->rasterizer->sprite_coord_mode,
 	};
 
-	fixup_shader_state(ctx, &emit.key);
+	ir3_fixup_shader_state(&ctx->base, &emit.key);
 
 	enum fd_dirty_3d_state dirty = ctx->dirty;
 	const struct ir3_shader_variant *vp = fd4_emit_get_vp(&emit);
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_context.c b/src/gallium/drivers/freedreno/a5xx/fd5_context.c
index 8ab28633d42..0bef048ca47 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_context.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_context.c
@@ -85,6 +85,7 @@ fd5_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
 
 	fd5_ctx->base.dev = fd_device_ref(screen->dev);
 	fd5_ctx->base.screen = fd_screen(pscreen);
+	fd5_ctx->base.last.key = &fd5_ctx->last_key;
 
 	pctx->destroy = fd5_context_destroy;
 	pctx->create_blend_state = fd5_blend_state_create;
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_context.h b/src/gallium/drivers/freedreno/a5xx/fd5_context.h
index 4d96bc35873..3da77a6aa44 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_context.h
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_context.h
@@ -54,10 +54,7 @@ struct fd5_context {
 	/* bitmask of samplers which need astc srgb workaround: */
 	uint16_t vastc_srgb, fastc_srgb;
 
-	/* some state changes require a different shader variant.  Keep
-	 * track of this so we know when we need to re-emit shader state
-	 * due to variant change.  See fixup_shader_state()
-	 */
+	/* storage for ctx->last.key: */
 	struct ir3_shader_key last_key;
 
 	/* number of active samples-passed queries: */
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
index 97fd45bd6ba..5d6891646a2 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
@@ -67,32 +67,6 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
 			info, emit->indirect, emit->draw, index_offset);
 }
 
-/* fixup dirty shader state in case some "unrelated" (from the state-
- * tracker's perspective) state change causes us to switch to a
- * different variant.
- */
-static void
-fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
-	assert_dt
-{
-	struct fd5_context *fd5_ctx = fd5_context(ctx);
-	struct ir3_shader_key *last_key = &fd5_ctx->last_key;
-
-	if (!ir3_shader_key_equal(last_key, key)) {
-		if (ir3_shader_key_changes_fs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		if (ir3_shader_key_changes_vs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		fd5_ctx->last_key = *key;
-	}
-}
-
 static bool
 fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
              const struct pipe_draw_indirect_info *indirect,
@@ -120,7 +94,7 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
 		.sprite_coord_mode = ctx->rasterizer->sprite_coord_mode,
 	};
 
-	fixup_shader_state(ctx, &emit.key);
+	ir3_fixup_shader_state(&ctx->base, &emit.key);
 
 	unsigned dirty = ctx->dirty;
 	const struct ir3_shader_variant *vp = fd5_emit_get_vp(&emit);
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.c b/src/gallium/drivers/freedreno/a6xx/fd6_context.c
index 99e2f3a9ab1..4dcaf03b156 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_context.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.c
@@ -142,6 +142,7 @@ fd6_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
 
 	fd6_ctx->base.dev = fd_device_ref(screen->dev);
 	fd6_ctx->base.screen = fd_screen(pscreen);
+	fd6_ctx->base.last.key = &fd6_ctx->last_key;
 
 	pctx->destroy = fd6_context_destroy;
 	pctx->create_blend_state = fd6_blend_state_create;
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.h b/src/gallium/drivers/freedreno/a6xx/fd6_context.h
index d8552f31c55..1a1102f95a8 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_context.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.h
@@ -70,10 +70,7 @@ struct fd6_context {
 	struct u_upload_mgr *border_color_uploader;
 	struct pipe_resource *border_color_buf;
 
-	/* some state changes require a different shader variant.  Keep
-	 * track of this so we know when we need to re-emit shader state
-	 * due to variant change.  See fixup_shader_state()
-	 */
+	/* storage for ctx->last.key: */
 	struct ir3_shader_key last_key;
 
 	/* Is there current VS driver-param state set? */
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c
index 87f9c922bde..3292cc2040a 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c
@@ -128,32 +128,6 @@ draw_emit(struct fd_ringbuffer *ring,
 	}
 }
 
-/* fixup dirty shader state in case some "unrelated" (from the state-
- * tracker's perspective) state change causes us to switch to a
- * different variant.
- */
-static void
-fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
-	assert_dt
-{
-	struct fd6_context *fd6_ctx = fd6_context(ctx);
-	struct ir3_shader_key *last_key = &fd6_ctx->last_key;
-
-	if (!ir3_shader_key_equal(last_key, key)) {
-		if (ir3_shader_key_changes_fs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		if (ir3_shader_key_changes_vs(last_key, key)) {
-			ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
-			ctx->dirty |= FD_DIRTY_PROG;
-		}
-
-		fd6_ctx->last_key = *key;
-	}
-}
-
 static void
 fixup_draw_state(struct fd_context *ctx, struct fd6_emit *emit)
 	assert_dt
@@ -219,7 +193,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
 	if (!(emit.key.hs || emit.key.ds || emit.key.gs || indirect))
 		fd6_vsc_update_sizes(ctx->batch, info, draw);
 
-	fixup_shader_state(ctx, &emit.key.key);
+	ir3_fixup_shader_state(&ctx->base, &emit.key.key);
 
 	if (!(ctx->dirty & FD_DIRTY_PROG)) {
 		emit.prog = fd6_ctx->prog;
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index 418454049cd..717ecedf890 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -176,6 +176,8 @@ enum fd_dirty_shader_state {
 struct fd_hw_sample_provider;
 struct fd_hw_sample;
 
+struct ir3_shader_key;
+
 struct fd_context {
 	struct pipe_context base;
 
@@ -466,6 +468,15 @@ struct fd_context {
 		uint32_t instance_start;
 		uint32_t restart_index;
 		uint32_t streamout_mask;
+
+		/* some state changes require a different shader variant.  Keep
+		 * track of this so we know when we need to re-emit shader state
+		 * due to variant change.  See ir3_fixup_shader_state()
+		 *
+		 * (used for a3xx+, NULL otherwise)
+		 */
+		struct ir3_shader_key *key;
+
 	} last dt;
 };
 
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c
index a01c1cfee7e..23e898cfb93 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c
@@ -443,6 +443,34 @@ ir3_get_shader_info(struct ir3_shader_state *hwcso)
 	return &hwcso->shader->nir->info;
 }
 
+/* fixup dirty shader state in case some "unrelated" (from the state-
+ * tracker's perspective) state change causes us to switch to a
+ * different variant.
+ */
+void
+ir3_fixup_shader_state(struct pipe_context *pctx, struct ir3_shader_key *key)
+{
+	struct fd_context *ctx = fd_context(pctx);
+
+	if (!ir3_shader_key_equal(ctx->last.key, key)) {
+		if (ir3_shader_key_changes_fs(ctx->last.key, key)) {
+			ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
+			ctx->dirty |= FD_DIRTY_PROG;
+		}
+
+		if (ir3_shader_key_changes_vs(ctx->last.key, key)) {
+			ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+			ctx->dirty |= FD_DIRTY_PROG;
+		}
+
+		/* NOTE: currently only a6xx has gs/tess, but needs no
+		 * gs/tess specific lowering.
+		 */
+
+		*ctx->last.key = *key;
+	}
+}
+
 static void
 ir3_screen_finalize_nir(struct pipe_screen *pscreen, void *nir, bool optimize)
 {
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_gallium.h b/src/gallium/drivers/freedreno/ir3/ir3_gallium.h
index 8523895e684..663e8d48676 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_gallium.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_gallium.h
@@ -31,6 +31,8 @@
 #include "pipe/p_screen.h"
 #include "ir3/ir3_shader.h"
 
+#include "freedreno_util.h"
+
 /**
  * The ir3 hwcso type, use ir3_get_shader() to dereference the
  * underlying ir3_shader
@@ -49,6 +51,8 @@ void ir3_shader_state_delete(struct pipe_context *pctx, void *hwcso);
 struct ir3_shader * ir3_get_shader(struct ir3_shader_state *hwcso);
 struct shader_info * ir3_get_shader_info(struct ir3_shader_state *hwcso);
 
+void ir3_fixup_shader_state(struct pipe_context *pctx, struct ir3_shader_key *key) assert_dt;
+
 void ir3_prog_init(struct pipe_context *pctx);
 void ir3_screen_init(struct pipe_screen *pscreen);
 void ir3_screen_fini(struct pipe_screen *pscreen);



More information about the mesa-commit mailing list