From: Rob Clark Date: Tue, 3 May 2016 20:54:21 +0000 (-0400) Subject: freedreno: move shader-stage dirty bits to global dirty flag X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=291ac872a445f3edebd668b27e910a79e1de5a00;p=mesa.git freedreno: move shader-stage dirty bits to global dirty flag This was always a bit overly complicated, and had some issues (like ctx->prog.dirty not getting reset at the end of the batch). It also required some special hacks to avoid resetting dirty state on binning pass. So just move it all into ctx->dirty (leaving some free bits for future shader stages), and make FD_DIRTY_PROG just be the union of all FD_SHADER_DIRTY_*. Signed-off-by: Rob Clark --- diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_program.c b/src/gallium/drivers/freedreno/a2xx/fd2_program.c index 5ccfd58bfe1..4f317721db0 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_program.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_program.c @@ -247,15 +247,12 @@ fd2_program_validate(struct fd_context *ctx) * from the vertex shader. And therefore if frag shader has changed we * need to recompile both vert and frag shader. */ - if (prog->dirty & FD_SHADER_DIRTY_FP) + if (ctx->dirty & FD_SHADER_DIRTY_FP) compile(prog, prog->fp); - if (prog->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP)) + if (ctx->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP)) compile(prog, prog->vp); - if (prog->dirty) - ctx->dirty |= FD_DIRTY_PROG; - /* if necessary, fix up vertex fetch instructions: */ if (ctx->dirty & (FD_DIRTY_VTXSTATE | FD_DIRTY_PROG)) patch_vtx_fetches(ctx, prog->vp, ctx->vtx.vtx); @@ -292,8 +289,6 @@ fd2_program_emit(struct fd_ringbuffer *ring, A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(vs_export) | A2XX_SQ_PROGRAM_CNTL_PS_REGS(fs_gprs) | A2XX_SQ_PROGRAM_CNTL_VS_REGS(vs_gprs)); - - prog->dirty = 0; } /* Creates shader: diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c index b6c3ea674e6..dc4558e9644 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c @@ -104,31 +104,29 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key) struct ir3_shader_key *last_key = &fd3_ctx->last_key; if (!ir3_shader_key_equal(last_key, key)) { - ctx->dirty |= FD_DIRTY_PROG; - if (last_key->has_per_samp || key->has_per_samp) { 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; + ctx->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; + ctx->dirty |= FD_SHADER_DIRTY_FP; } if (last_key->vclamp_color != key->vclamp_color) - ctx->prog.dirty |= FD_SHADER_DIRTY_VP; + ctx->dirty |= FD_SHADER_DIRTY_VP; if (last_key->fclamp_color != key->fclamp_color) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; if (last_key->color_two_side != key->color_two_side) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; if (last_key->half_precision != key->half_precision) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; fd3_ctx->last_key = *key; } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index e1d0a4fee84..4a5242aedb0 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -659,11 +659,6 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, ir3_emit_consts(vp, ring, ctx, emit->info, dirty); if (!emit->key.binning_pass) ir3_emit_consts(fp, ring, ctx, emit->info, dirty); - /* mark clean after emitting consts.. a bit ugly, but since binning - * pass is emitted first, we want to do this only for main draw: - */ - if (!emit->key.binning_pass) - ctx->prog.dirty = 0; } if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_FRAMEBUFFER)) { diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c index d49c529aab4..af02d31fb91 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c @@ -88,36 +88,34 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key) struct ir3_shader_key *last_key = &fd4_ctx->last_key; if (!ir3_shader_key_equal(last_key, key)) { - ctx->dirty |= FD_DIRTY_PROG; - if (last_key->has_per_samp || key->has_per_samp) { if ((last_key->vsaturate_s != key->vsaturate_s) || (last_key->vsaturate_t != key->vsaturate_t) || (last_key->vsaturate_r != key->vsaturate_r) || (last_key->vastc_srgb != key->vastc_srgb)) - ctx->prog.dirty |= FD_SHADER_DIRTY_VP; + ctx->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) || (last_key->fastc_srgb != key->fastc_srgb)) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; } if (last_key->vclamp_color != key->vclamp_color) - ctx->prog.dirty |= FD_SHADER_DIRTY_VP; + ctx->dirty |= FD_SHADER_DIRTY_VP; if (last_key->fclamp_color != key->fclamp_color) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; if (last_key->color_two_side != key->color_two_side) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; if (last_key->half_precision != key->half_precision) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; if (last_key->rasterflat != key->rasterflat) - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; + ctx->dirty |= FD_SHADER_DIRTY_FP; fd4_ctx->last_key = *key; } diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 459494c0903..00e985d27e5 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -649,11 +649,6 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, ir3_emit_consts(vp, ring, ctx, emit->info, dirty); if (!emit->key.binning_pass) ir3_emit_consts(fp, ring, ctx, emit->info, dirty); - /* mark clean after emitting consts.. a bit ugly, but since binning - * pass is emitted first, we want to do this only for main draw: - */ - if (!emit->key.binning_pass) - ctx->prog.dirty = 0; } if ((dirty & FD_DIRTY_BLEND)) { diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index e65688e6c58..80c638a7e38 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -54,10 +54,8 @@ struct fd_texture_stateobj { struct fd_program_stateobj { void *vp, *fp; - enum { - FD_SHADER_DIRTY_VP = (1 << 0), - FD_SHADER_DIRTY_FP = (1 << 1), - } dirty; + + /* rest only used by fd2.. split out: */ uint8_t num_exports; /* Indexed by semantic name or TGSI_SEMANTIC_COUNT + semantic index * for TGSI_SEMANTIC_GENERIC. Special vs exports (position and point- @@ -327,21 +325,26 @@ struct fd_context { FD_DIRTY_FRAGTEX = (1 << 3), FD_DIRTY_VERTTEX = (1 << 4), FD_DIRTY_TEXSTATE = (1 << 5), - FD_DIRTY_PROG = (1 << 6), - FD_DIRTY_BLEND_COLOR = (1 << 7), - FD_DIRTY_STENCIL_REF = (1 << 8), - FD_DIRTY_SAMPLE_MASK = (1 << 9), - FD_DIRTY_FRAMEBUFFER = (1 << 10), - FD_DIRTY_STIPPLE = (1 << 11), - FD_DIRTY_VIEWPORT = (1 << 12), - FD_DIRTY_CONSTBUF = (1 << 13), - FD_DIRTY_VTXSTATE = (1 << 14), - FD_DIRTY_VTXBUF = (1 << 15), - FD_DIRTY_INDEXBUF = (1 << 16), - FD_DIRTY_SCISSOR = (1 << 17), - FD_DIRTY_STREAMOUT = (1 << 18), - FD_DIRTY_UCP = (1 << 19), - FD_DIRTY_BLEND_DUAL = (1 << 20), + + 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; struct pipe_blend_state *blend; diff --git a/src/gallium/drivers/freedreno/freedreno_program.c b/src/gallium/drivers/freedreno/freedreno_program.c index 9c51119d371..ae6c65831bb 100644 --- a/src/gallium/drivers/freedreno/freedreno_program.c +++ b/src/gallium/drivers/freedreno/freedreno_program.c @@ -37,8 +37,7 @@ fd_fp_state_bind(struct pipe_context *pctx, void *hwcso) { struct fd_context *ctx = fd_context(pctx); ctx->prog.fp = hwcso; - ctx->prog.dirty |= FD_SHADER_DIRTY_FP; - ctx->dirty |= FD_DIRTY_PROG; + ctx->dirty |= FD_SHADER_DIRTY_FP; } static void @@ -46,8 +45,7 @@ fd_vp_state_bind(struct pipe_context *pctx, void *hwcso) { struct fd_context *ctx = fd_context(pctx); ctx->prog.vp = hwcso; - ctx->prog.dirty |= FD_SHADER_DIRTY_VP; - ctx->dirty |= FD_DIRTY_PROG; + ctx->dirty |= FD_SHADER_DIRTY_VP; } static const char *solid_fp = diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index 8019a1286c0..4062ca989f0 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -647,10 +647,10 @@ ir3_emit_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring, if (v->type == SHADER_VERTEX) { constbuf = &ctx->constbuf[PIPE_SHADER_VERTEX]; - shader_dirty = !!(ctx->prog.dirty & FD_SHADER_DIRTY_VP); + shader_dirty = !!(dirty & FD_SHADER_DIRTY_VP); } else if (v->type == SHADER_FRAGMENT) { constbuf = &ctx->constbuf[PIPE_SHADER_FRAGMENT]; - shader_dirty = !!(ctx->prog.dirty & FD_SHADER_DIRTY_FP); + shader_dirty = !!(dirty & FD_SHADER_DIRTY_FP); } else { unreachable("bad shader type"); return;