Mesa (master): freedreno/a3xx: re-emit shaders on variant change

Rob Clark robclark at kemper.freedesktop.org
Mon Sep 29 22:34:04 UTC 2014


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

Author: Rob Clark <robclark at freedesktop.org>
Date:   Mon Sep 29 14:29:04 2014 -0400

freedreno/a3xx: re-emit shaders on variant change

We need to keep track if a state change other than frag/vert shader
state will trigger us to need a different shader variant, and if
necessary mark the appropriate shader state as dirty.  Otherwise we will
forget to re-emit the shader state.

Signed-off-by: Rob Clark <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/a3xx/fd3_context.h |    9 +++++
 src/gallium/drivers/freedreno/a3xx/fd3_draw.c    |   42 +++++++++++++++++++++-
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.h b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
index 48bbb47..2736470 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_context.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
@@ -35,6 +35,9 @@
 
 #include "freedreno_context.h"
 
+#include "ir3_shader.h"
+
+
 struct fd3_context {
 	struct fd_context base;
 
@@ -86,6 +89,12 @@ struct fd3_context {
 	 * shader:
 	 */
 	unsigned fsaturate_s, fsaturate_t, fsaturate_r;
+
+	/* 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()
+	 */
+	struct ir3_shader_key last_key;
 };
 
 static INLINE struct fd3_context *
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index f7a5fca..bd395f6 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -96,10 +96,45 @@ draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
 			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.
+ */
+static void
+fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
+{
+	struct fd3_context *fd3_ctx = fd3_context(ctx);
+	struct ir3_shader_key *last_key = &fd3_ctx->last_key;
+
+	if (memcmp(last_key, key, sizeof(*key))) {
+		ctx->dirty |= FD_DIRTY_PROG;
+
+		if ((last_key->vsaturate_s != key->vsaturate_s) ||
+				(last_key->vsaturate_t != key->vsaturate_t) ||
+				(last_key->vsaturate_r != key->vsaturate_r))
+			ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
+
+		if ((last_key->fsaturate_s != key->fsaturate_s) ||
+				(last_key->fsaturate_t != key->fsaturate_t) ||
+				(last_key->fsaturate_r != key->fsaturate_r))
+			ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
+
+		if (last_key->color_two_side != key->color_two_side)
+			ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
+
+		if (last_key->half_precision != key->half_precision)
+			ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
+
+		if (last_key->alpha != key->alpha)
+			ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
+
+		fd3_ctx->last_key = *key;
+	}
+}
+
 static void
 fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
 {
-	unsigned dirty = ctx->dirty;
 	struct fd3_context *fd3_ctx = fd3_context(ctx);
 	struct ir3_shader_key key = {
 			/* do binning pass first: */
@@ -116,6 +151,11 @@ fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
 			.fsaturate_t = fd3_ctx->fsaturate_t,
 			.fsaturate_r = fd3_ctx->fsaturate_r,
 	};
+	unsigned dirty;
+
+	fixup_shader_state(ctx, &key);
+
+	dirty = ctx->dirty;
 
 	draw_impl(ctx, info, ctx->binning_ring,
 			dirty & ~(FD_DIRTY_BLEND), key);




More information about the mesa-commit mailing list