diff options
author | Rob Clark <[email protected]> | 2014-09-29 14:29:04 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2014-09-29 18:30:43 -0400 |
commit | dce96f6da2d8ec4c17403db57326731dcf9d6051 (patch) | |
tree | f67c855ab414c09186241410f37c224de910d911 /src/gallium/drivers/freedreno/a3xx | |
parent | 3aaab87563e40bdd8fb98494d7e3eb844521476c (diff) |
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 <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_context.h | 9 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_draw.c | 42 |
2 files changed, 50 insertions, 1 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.h b/src/gallium/drivers/freedreno/a3xx/fd3_context.h index 48bbb47e9ca..2736470b93a 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 f7a5fcafd9a..bd395f602b0 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); |