freedreno: refactor dirty state handling
authorRob Clark <robdclark@gmail.com>
Sat, 15 Apr 2017 14:04:55 +0000 (10:04 -0400)
committerRob Clark <robdclark@gmail.com>
Tue, 18 Apr 2017 20:32:00 +0000 (16:32 -0400)
In particular, move per-shader-stage info out to a seperate array of
enum's indexed by shader stage.  This will make it easier to add more
shader stages as well as new per-stage state (like SSBOs).

Signed-off-by: Rob Clark <robdclark@gmail.com>
19 files changed:
src/gallium/drivers/freedreno/a2xx/fd2_draw.c
src/gallium/drivers/freedreno/a2xx/fd2_emit.c
src/gallium/drivers/freedreno/a2xx/fd2_emit.h
src/gallium/drivers/freedreno/a2xx/fd2_program.c
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/a3xx/fd3_emit.h
src/gallium/drivers/freedreno/a4xx/fd4_draw.c
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/a4xx/fd4_emit.h
src/gallium/drivers/freedreno/a5xx/fd5_draw.c
src/gallium/drivers/freedreno/a5xx/fd5_emit.c
src/gallium/drivers/freedreno/a5xx/fd5_emit.h
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_program.c
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/freedreno/freedreno_state.c
src/gallium/drivers/freedreno/freedreno_texture.c
src/gallium/drivers/freedreno/ir3/ir3_shader.c

index feec59fa5de7aa7041ccb9514421c635ffea6b49..f360ec2f6e2007ceff06d6ca385e75fac7df286d 100644 (file)
@@ -284,9 +284,12 @@ fd2_clear(struct fd_context *ctx, unsigned buffers,
                        FD_DIRTY_RASTERIZER |
                        FD_DIRTY_SAMPLE_MASK |
                        FD_DIRTY_PROG |
-                       FD_DIRTY_CONSTBUF |
+                       FD_DIRTY_CONST |
                        FD_DIRTY_BLEND |
                        FD_DIRTY_FRAMEBUFFER;
+
+       ctx->dirty_shader[PIPE_SHADER_VERTEX]   |= FD_DIRTY_SHADER_PROG;
+       ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG | FD_DIRTY_SHADER_CONST;
 }
 
 void
index fe2750ba10b30d44c51cfad62b67c302c04e0c5a..d745e44b0adbdb02a34ca2789c1261879638dc00 100644 (file)
@@ -182,7 +182,7 @@ fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
 }
 
 void
-fd2_emit_state(struct fd_context *ctx, const uint32_t dirty)
+fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty)
 {
        struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend);
        struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa);
@@ -284,7 +284,7 @@ fd2_emit_state(struct fd_context *ctx, const uint32_t dirty)
                fd2_program_emit(ring, &ctx->prog);
        }
 
-       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONST)) {
                emit_constants(ring,  VS_CONST_BASE * 4,
                                &ctx->constbuf[PIPE_SHADER_VERTEX],
                                (dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
@@ -309,7 +309,7 @@ fd2_emit_state(struct fd_context *ctx, const uint32_t dirty)
                OUT_RING(ring, blend->rb_colormask);
        }
 
-       if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG))
+       if (dirty & (FD_DIRTY_TEX | FD_DIRTY_PROG))
                emit_textures(ring, ctx);
 }
 
index 6a26c85c142b725423ae350af04581923555905a..d908b1135146c562fe93f08e5abd444be2997e36 100644 (file)
@@ -42,7 +42,7 @@ struct fd2_vertex_buf {
 
 void fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val,
                struct fd2_vertex_buf *vbufs, uint32_t n);
-void fd2_emit_state(struct fd_context *ctx, uint32_t dirty);
+void fd2_emit_state(struct fd_context *ctx, enum fd_dirty_3d_state dirty);
 void fd2_emit_restore(struct fd_context *ctx, struct fd_ringbuffer *ring);
 
 void fd2_emit_init(struct pipe_context *pctx);
index 8dcbb979383d504971b909049ab7d2139e3c56d2..9a774572514abc8b19971a01f56a4e166091f619 100644 (file)
@@ -241,16 +241,18 @@ void
 fd2_program_validate(struct fd_context *ctx)
 {
        struct fd_program_stateobj *prog = &ctx->prog;
+       bool dirty_fp = !!(ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_PROG);
+       bool dirty_vp = !!(ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_PROG);
 
        /* if vertex or frag shader is dirty, we may need to recompile. Compile
         * frag shader first, as that assigns the register slots for exports
         * from the vertex shader.  And therefore if frag shader has changed we
         * need to recompile both vert and frag shader.
         */
-       if (ctx->dirty & FD_SHADER_DIRTY_FP)
+       if (dirty_fp)
                compile(prog, prog->fp);
 
-       if (ctx->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP))
+       if (dirty_fp || dirty_vp)
                compile(prog, prog->vp);
 
        /* if necessary, fix up vertex fetch instructions: */
index c36e507166039afb572ce6df639e1400368ae00c..b3e42f37a2a32a2ba79e71e48766ac426ef9c8b5 100644 (file)
@@ -101,11 +101,13 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
 
        if (!ir3_shader_key_equal(last_key, key)) {
                if (ir3_shader_key_changes_fs(last_key, key)) {
-                       ctx->dirty |= FD_SHADER_DIRTY_FP;
+                       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 |= FD_SHADER_DIRTY_VP;
+                       ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+                       ctx->dirty |= FD_DIRTY_PROG;
                }
 
                fd3_ctx->last_key = *key;
index 04e3300efdef199335aa0e9d77ae57928159830a..ca97a08d544c4fd298d64af7c091feb2fcbffcb1 100644 (file)
@@ -490,7 +490,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 {
        const struct ir3_shader_variant *vp = fd3_emit_get_vp(emit);
        const struct ir3_shader_variant *fp = fd3_emit_get_fp(emit);
-       const uint32_t dirty = emit->dirty;
+       const enum fd_dirty_3d_state dirty = emit->dirty;
 
        emit_marker(ring, 5);
 
@@ -783,13 +783,13 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                A3XX_RB_BLEND_ALPHA_FLOAT(bcolor->color[3]));
        }
 
-       if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX))
+       if (dirty & FD_DIRTY_TEX)
                fd_wfi(ctx->batch, ring);
 
-       if (dirty & FD_DIRTY_VERTTEX)
+       if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX)
                emit_textures(ctx, ring, SB_VERT_TEX, &ctx->tex[PIPE_SHADER_VERTEX]);
 
-       if (dirty & FD_DIRTY_FRAGTEX)
+       if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX)
                emit_textures(ctx, ring, SB_FRAG_TEX, &ctx->tex[PIPE_SHADER_FRAGMENT]);
 }
 
index 6e7dee25daad92dd2eb3bf25aabe0278a973ac82..5e574da199debe2a986050ad40b39e4d9008d11a 100644 (file)
@@ -48,7 +48,7 @@ struct fd3_emit {
        const struct fd_program_stateobj *prog;
        const struct pipe_draw_info *info;
        struct ir3_shader_key key;
-       uint32_t dirty;
+       enum fd_dirty_3d_state dirty;
 
        uint32_t sprite_coord_enable;
        bool sprite_coord_mode;
index 869c69b25b34f5b948bf10890a1ea9f526c3e6cc..a76f9e8c4347d1570f2cca5d98028c19b51d093a 100644 (file)
@@ -85,11 +85,13 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
 
        if (!ir3_shader_key_equal(last_key, key)) {
                if (ir3_shader_key_changes_fs(last_key, key)) {
-                       ctx->dirty |= FD_SHADER_DIRTY_FP;
+                       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 |= FD_SHADER_DIRTY_VP;
+                       ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+                       ctx->dirty |= FD_DIRTY_PROG;
                }
 
                fd4_ctx->last_key = *key;
@@ -131,7 +133,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
 
        fixup_shader_state(ctx, &emit.key);
 
-       unsigned dirty = ctx->dirty;
+       enum fd_dirty_3d_state dirty = ctx->dirty;
 
        /* do regular pass first, since that is more likely to fail compiling: */
 
index 4c79a67ba5909c42cb4beeab12a33be3f28c5bc4..f0a1fdea0df9a279e78bd3b3512cbe9dd48b8fd3 100644 (file)
@@ -499,7 +499,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 {
        const struct ir3_shader_variant *vp = fd4_emit_get_vp(emit);
        const struct ir3_shader_variant *fp = fd4_emit_get_fp(emit);
-       const uint32_t dirty = emit->dirty;
+       const enum fd_dirty_3d_state dirty = emit->dirty;
 
        emit_marker(ring, 5);
 
@@ -740,10 +740,10 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_RING(ring, A4XX_RB_BLEND_ALPHA_F32(bcolor->color[3]));
        }
 
-       if (dirty & FD_DIRTY_VERTTEX)
+       if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX)
                emit_textures(ctx, ring, SB4_VS_TEX, &ctx->tex[PIPE_SHADER_VERTEX], vp);
 
-       if (dirty & FD_DIRTY_FRAGTEX)
+       if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX)
                emit_textures(ctx, ring, SB4_FS_TEX, &ctx->tex[PIPE_SHADER_FRAGMENT], fp);
 }
 
index 00f92faaf352d18b7699c4a9447921cc4ade19c2..a724caedc2980bed56bb099bcabb30c0ea09d704 100644 (file)
@@ -48,7 +48,7 @@ struct fd4_emit {
        const struct fd_program_stateobj *prog;
        const struct pipe_draw_info *info;
        struct ir3_shader_key key;
-       uint32_t dirty;
+       enum fd_dirty_3d_state dirty;
 
        uint32_t sprite_coord_enable;  /* bitmask */
        bool sprite_coord_mode;
index 147f7070039433b19814145b88b50b303dee2604..4ef0c7303d2373f2ed353932349a4cf0adb91384 100644 (file)
@@ -78,11 +78,13 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
 
        if (!ir3_shader_key_equal(last_key, key)) {
                if (ir3_shader_key_changes_fs(last_key, key)) {
-                       ctx->dirty |= FD_SHADER_DIRTY_FP;
+                       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 |= FD_SHADER_DIRTY_VP;
+                       ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+                       ctx->dirty |= FD_DIRTY_PROG;
                }
 
                fd5_ctx->last_key = *key;
index 1e5b6dbc292381fc302d006b19ee02345a532bbe..f2c9a6b85d5c2c78fdff3c9e05511cce48011abb 100644 (file)
@@ -398,7 +398,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 {
        const struct ir3_shader_variant *vp = fd5_emit_get_vp(emit);
        const struct ir3_shader_variant *fp = fd5_emit_get_fp(emit);
-       const uint32_t dirty = emit->dirty;
+       const enum fd_dirty_3d_state dirty = emit->dirty;
        bool needs_border = false;
 
        emit_marker5(ring, 5);
@@ -647,14 +647,14 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_RING(ring, A5XX_RB_BLEND_ALPHA_F32(bcolor->color[3]));
        }
 
-       if (dirty & FD_DIRTY_VERTTEX) {
+       if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX) {
                needs_border |= emit_textures(ctx, ring, SB4_VS_TEX,
                                &ctx->tex[PIPE_SHADER_VERTEX]);
                OUT_PKT4(ring, REG_A5XX_TPL1_VS_TEX_COUNT, 1);
                OUT_RING(ring, ctx->tex[PIPE_SHADER_VERTEX].num_textures);
        }
 
-       if (dirty & FD_DIRTY_FRAGTEX) {
+       if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX) {
                needs_border |= emit_textures(ctx, ring, SB4_FS_TEX,
                                &ctx->tex[PIPE_SHADER_FRAGMENT]);
                OUT_PKT4(ring, REG_A5XX_TPL1_FS_TEX_COUNT, 1);
index 0525b3e7326e6f10271c770e67e6085b591eded3..b18c0a8cb66d949c89a0af3aa562908949ac64ea 100644 (file)
@@ -44,7 +44,7 @@ struct fd5_emit {
        const struct fd_program_stateobj *prog;
        const struct pipe_draw_info *info;
        struct ir3_shader_key key;
-       uint32_t dirty;
+       enum fd_dirty_3d_state dirty;
 
        uint32_t sprite_coord_enable;  /* bitmask */
        bool sprite_coord_mode;
index 7f47eaf2a710ddbda6f0d22c684487d43373af67..733c64b18070be22ada8b0d46e35f0ea8954a854 100644 (file)
@@ -107,6 +107,42 @@ struct fd_vertex_state {
        struct fd_vertexbuf_stateobj vertexbuf;
 };
 
+/* global 3d pipeline dirty state: */
+enum fd_dirty_3d_state {
+       FD_DIRTY_BLEND       = BIT(0),
+       FD_DIRTY_RASTERIZER  = BIT(1),
+       FD_DIRTY_ZSA         = BIT(2),
+       FD_DIRTY_BLEND_COLOR = BIT(3),
+       FD_DIRTY_STENCIL_REF = BIT(4),
+       FD_DIRTY_SAMPLE_MASK = BIT(5),
+       FD_DIRTY_FRAMEBUFFER = BIT(6),
+       FD_DIRTY_STIPPLE     = BIT(7),
+       FD_DIRTY_VIEWPORT    = BIT(8),
+       FD_DIRTY_VTXSTATE    = BIT(9),
+       FD_DIRTY_VTXBUF      = BIT(10),
+       FD_DIRTY_INDEXBUF    = BIT(11),
+       FD_DIRTY_SCISSOR     = BIT(12),
+       FD_DIRTY_STREAMOUT   = BIT(13),
+       FD_DIRTY_UCP         = BIT(14),
+       FD_DIRTY_BLEND_DUAL  = BIT(15),
+
+       /* These are a bit redundent with fd_dirty_shader_state, and possibly
+        * should be removed.  (But OTOH kinda convenient in some places)
+        */
+       FD_DIRTY_PROG        = BIT(16),
+       FD_DIRTY_CONST       = BIT(17),
+       FD_DIRTY_TEX         = BIT(18),
+
+       /* only used by a2xx.. possibly can be removed.. */
+       FD_DIRTY_TEXSTATE    = BIT(19),
+};
+
+/* per shader-stage dirty state: */
+enum fd_dirty_shader_state {
+       FD_DIRTY_SHADER_PROG  = BIT(0),
+       FD_DIRTY_SHADER_CONST = BIT(1),
+       FD_DIRTY_SHADER_TEX   = BIT(2),
+};
 
 struct fd_context {
        struct pipe_context base;
@@ -196,34 +232,10 @@ struct fd_context {
        struct fd_tile          tile[512];
 
        /* which state objects need to be re-emit'd: */
-       enum {
-               FD_DIRTY_BLEND       = (1 <<  0),
-               FD_DIRTY_RASTERIZER  = (1 <<  1),
-               FD_DIRTY_ZSA         = (1 <<  2),
-               FD_DIRTY_FRAGTEX     = (1 <<  3),
-               FD_DIRTY_VERTTEX     = (1 <<  4),
-               FD_DIRTY_TEXSTATE    = (1 <<  5),
-
-               FD_SHADER_DIRTY_VP   = (1 <<  6),
-               FD_SHADER_DIRTY_FP   = (1 <<  7),
-               /* skip geom/tcs/tes/compute */
-               FD_DIRTY_PROG        = FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP,
-
-               FD_DIRTY_BLEND_COLOR = (1 << 12),
-               FD_DIRTY_STENCIL_REF = (1 << 13),
-               FD_DIRTY_SAMPLE_MASK = (1 << 14),
-               FD_DIRTY_FRAMEBUFFER = (1 << 15),
-               FD_DIRTY_STIPPLE     = (1 << 16),
-               FD_DIRTY_VIEWPORT    = (1 << 17),
-               FD_DIRTY_CONSTBUF    = (1 << 18),
-               FD_DIRTY_VTXSTATE    = (1 << 19),
-               FD_DIRTY_VTXBUF      = (1 << 20),
-               FD_DIRTY_INDEXBUF    = (1 << 21),
-               FD_DIRTY_SCISSOR     = (1 << 22),
-               FD_DIRTY_STREAMOUT   = (1 << 23),
-               FD_DIRTY_UCP         = (1 << 24),
-               FD_DIRTY_BLEND_DUAL  = (1 << 25),
-       } dirty;
+       enum fd_dirty_3d_state dirty;
+
+       /* per shader-stage dirty status: */
+       enum fd_dirty_shader_state dirty_shader[PIPE_SHADER_TYPES];
 
        struct pipe_blend_state *blend;
        struct pipe_rasterizer_state *rasterizer;
@@ -330,12 +342,16 @@ static inline void
 fd_context_all_dirty(struct fd_context *ctx)
 {
        ctx->dirty = ~0;
+       for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++)
+               ctx->dirty_shader[i] = ~0;
 }
 
 static inline void
 fd_context_all_clean(struct fd_context *ctx)
 {
        ctx->dirty = 0;
+       for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++)
+               ctx->dirty_shader[i] = 0;
 }
 
 static inline struct pipe_scissor_state *
index db6b258e21c0be31a025925309f7c30887cdb1af..0bb5d68752c95fcc2c731337f3c4bb703abf2b6e 100644 (file)
@@ -37,7 +37,8 @@ fd_fp_state_bind(struct pipe_context *pctx, void *hwcso)
 {
        struct fd_context *ctx = fd_context(pctx);
        ctx->prog.fp = hwcso;
-       ctx->dirty |= FD_SHADER_DIRTY_FP;
+       ctx->dirty_shader[PIPE_SHADER_FRAGMENT] |= FD_DIRTY_SHADER_PROG;
+       ctx->dirty |= FD_DIRTY_PROG;
 }
 
 static void
@@ -45,7 +46,8 @@ fd_vp_state_bind(struct pipe_context *pctx, void *hwcso)
 {
        struct fd_context *ctx = fd_context(pctx);
        ctx->prog.vp = hwcso;
-       ctx->dirty |= FD_SHADER_DIRTY_VP;
+       ctx->dirty_shader[PIPE_SHADER_VERTEX] |= FD_DIRTY_SHADER_PROG;
+       ctx->dirty |= FD_DIRTY_PROG;
 }
 
 static const char *solid_fp =
index 427ada8b667cbf4ea55d9d80b2245c9520a7a58b..3b067095523538bfd81dfd7c98f84055c66ee486 100644 (file)
 static void
 fd_invalidate_resource(struct fd_context *ctx, struct pipe_resource *prsc)
 {
-       int i;
-
        /* Go through the entire state and see if the resource is bound
         * anywhere. If it is, mark the relevant state as dirty. This is called on
         * realloc_bo.
         */
 
-       /* Constbufs */
-       for (i = 1; i < PIPE_MAX_CONSTANT_BUFFERS && !(ctx->dirty & FD_DIRTY_CONSTBUF); i++) {
-               if (ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer == prsc)
-                       ctx->dirty |= FD_DIRTY_CONSTBUF;
-               if (ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer == prsc)
-                       ctx->dirty |= FD_DIRTY_CONSTBUF;
-       }
-
        /* VBOs */
-       for (i = 0; i < ctx->vtx.vertexbuf.count && !(ctx->dirty & FD_DIRTY_VTXBUF); i++) {
+       for (unsigned i = 0; i < ctx->vtx.vertexbuf.count && !(ctx->dirty & FD_DIRTY_VTXBUF); i++) {
                if (ctx->vtx.vertexbuf.vb[i].buffer == prsc)
                        ctx->dirty |= FD_DIRTY_VTXBUF;
        }
@@ -76,14 +66,26 @@ fd_invalidate_resource(struct fd_context *ctx, struct pipe_resource *prsc)
        if (ctx->indexbuf.buffer == prsc)
                ctx->dirty |= FD_DIRTY_INDEXBUF;
 
-       /* Textures */
-       for (i = 0; i < ctx->tex[PIPE_SHADER_VERTEX].num_textures && !(ctx->dirty & FD_DIRTY_VERTTEX); i++) {
-               if (ctx->tex[PIPE_SHADER_VERTEX].textures[i] && (ctx->tex[PIPE_SHADER_VERTEX].textures[i]->texture == prsc))
-                       ctx->dirty |= FD_DIRTY_VERTTEX;
-       }
-       for (i = 0; i < ctx->tex[PIPE_SHADER_FRAGMENT].num_textures && !(ctx->dirty & FD_DIRTY_FRAGTEX); i++) {
-               if (ctx->tex[PIPE_SHADER_FRAGMENT].textures[i] && (ctx->tex[PIPE_SHADER_FRAGMENT].textures[i]->texture == prsc))
-                       ctx->dirty |= FD_DIRTY_FRAGTEX;
+       /* per-shader-stage resources: */
+       for (unsigned stage = 0; stage < PIPE_SHADER_TYPES; stage++) {
+               /* Constbufs.. note that constbuf[0] is normal uniforms emitted in
+                * cmdstream rather than by pointer..
+                */
+               const unsigned num_ubos = util_last_bit(ctx->constbuf[stage].enabled_mask);
+               for (unsigned i = 1; i < num_ubos; i++) {
+                       if (ctx->dirty_shader[stage] & FD_DIRTY_SHADER_CONST)
+                               break;
+                       if (ctx->constbuf[stage].cb[i].buffer == prsc)
+                               ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_CONST;
+               }
+
+               /* Textures */
+               for (unsigned i = 0; i < ctx->tex[stage].num_textures; i++) {
+                       if (ctx->dirty_shader[stage] & FD_DIRTY_SHADER_TEX)
+                               break;
+                       if (ctx->tex[stage].textures[i] && (ctx->tex[stage].textures[i]->texture == prsc))
+                               ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_TEX;
+               }
        }
 }
 
index 06dfd228dcc63d5b55d8f1b8152a7545d93406e3..3b02e630646ea6f9a8c3434818838d06164a8fa6 100644 (file)
@@ -109,7 +109,8 @@ fd_set_constant_buffer(struct pipe_context *pctx,
 
        so->enabled_mask |= 1 << index;
        so->dirty_mask |= 1 << index;
-       ctx->dirty |= FD_DIRTY_CONSTBUF;
+       ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_CONST;
+       ctx->dirty |= FD_DIRTY_CONST;
 }
 
 static void
index e9d90aa3a77ea2c7e952be306156eabfa67c5326..1487f7441c924d2ee001ef6490f7a22428d3dbde 100644 (file)
@@ -92,13 +92,8 @@ fd_sampler_states_bind(struct pipe_context *pctx,
        struct fd_context *ctx = fd_context(pctx);
 
        bind_sampler_states(&ctx->tex[shader], start, nr, hwcso);
-
-       if (shader == PIPE_SHADER_FRAGMENT) {
-               ctx->dirty |= FD_DIRTY_FRAGTEX;
-       }
-       else if (shader == PIPE_SHADER_VERTEX) {
-               ctx->dirty |= FD_DIRTY_VERTTEX;
-       }
+       ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX;
+       ctx->dirty |= FD_DIRTY_TEX;
 }
 
 void
@@ -109,17 +104,8 @@ fd_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader,
        struct fd_context *ctx = fd_context(pctx);
 
        set_sampler_views(&ctx->tex[shader], start, nr, views);
-
-       switch (shader) {
-       case PIPE_SHADER_FRAGMENT:
-               ctx->dirty |= FD_DIRTY_FRAGTEX;
-               break;
-       case PIPE_SHADER_VERTEX:
-               ctx->dirty |= FD_DIRTY_VERTTEX;
-               break;
-       default:
-               break;
-       }
+       ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX;
+       ctx->dirty |= FD_DIRTY_TEX;
 }
 
 void
index 402d12a205cbd2e5965329022a5dca5c0b62814f..1d54d5330ad762af6d29479bcaeb8343747240cb 100644 (file)
@@ -658,16 +658,16 @@ void
 ir3_emit_vs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
                struct fd_context *ctx, const struct pipe_draw_info *info)
 {
-       uint32_t dirty = ctx->dirty;
+       enum fd_dirty_shader_state dirty = ctx->dirty_shader[PIPE_SHADER_VERTEX];
 
        debug_assert(v->type == SHADER_VERTEX);
 
-       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+       if (dirty & (FD_DIRTY_SHADER_PROG | FD_DIRTY_SHADER_CONST)) {
                struct fd_constbuf_stateobj *constbuf;
                bool shader_dirty;
 
                constbuf = &ctx->constbuf[PIPE_SHADER_VERTEX];
-               shader_dirty = !!(dirty & FD_SHADER_DIRTY_VP);
+               shader_dirty = !!(dirty & FD_DIRTY_SHADER_PROG);
 
                emit_user_consts(ctx, v, ring, constbuf);
                emit_ubos(ctx, v, ring, constbuf);
@@ -718,16 +718,16 @@ void
 ir3_emit_fs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
                struct fd_context *ctx)
 {
-       uint32_t dirty = ctx->dirty;
+       enum fd_dirty_shader_state dirty = ctx->dirty_shader[PIPE_SHADER_FRAGMENT];
 
        debug_assert(v->type == SHADER_FRAGMENT);
 
-       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) {
+       if (dirty & (FD_DIRTY_SHADER_PROG | FD_DIRTY_SHADER_CONST)) {
                struct fd_constbuf_stateobj *constbuf;
                bool shader_dirty;
 
                constbuf = &ctx->constbuf[PIPE_SHADER_FRAGMENT];
-               shader_dirty = !!(dirty & FD_SHADER_DIRTY_FP);
+               shader_dirty = !!(dirty & FD_DIRTY_SHADER_PROG);
 
                emit_user_consts(ctx, v, ring, constbuf);
                emit_ubos(ctx, v, ring, constbuf);