diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c index 2c95464455e..9e741ac3bf2 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c @@ -532,7 +532,8 @@ etna_emit_state(struct etna_context *ctx) } if (unlikely(dirty & (ETNA_DIRTY_STENCIL_REF | ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_ZSA))) { uint32_t val = etna_zsa_state(ctx->zsa)->PE_STENCIL_CONFIG_EXT; - if (!ctx->zsa->stencil[1].enabled && ctx->zsa->stencil[0].valuemask) + if (!ctx->zsa->stencil[1].enabled && + (screen->specs.correct_stencil_valuemask || ctx->zsa->stencil[0].valuemask)) val |= ctx->stencil_ref.PE_STENCIL_CONFIG_EXT[!ccw]; else val |= ctx->stencil_ref.PE_STENCIL_CONFIG_EXT[ccw]; diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h index da92eea73e2..9e86a893fcc 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h @@ -89,6 +89,8 @@ struct etna_specs { unsigned tex_astc : 1; /* has BLT engine instead of RS */ unsigned use_blt : 1; + /* has correct stencil 0 valuemask */ + unsigned correct_stencil_valuemask : 1; /* number of bits per TS tile */ unsigned bits_per_tile; /* clear value for TS (dependent on bits_per_tile) */ diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index 48aaaad2f3d..88c03e1b2d8 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -829,6 +829,9 @@ etna_get_specs(struct etna_screen *screen) screen->specs.v4_compression = VIV_FEATURE(screen, ETNA_FEATURE_V4_COMPRESSION); + /* XXX: The feature bit gating the bugfix is an educated guess */ + screen->specs.correct_stencil_valuemask = VIV_FEATURE(screen, ETNA_FEATURE_PE_DITHER_FIX); + if (screen->info->halti >= 5) { /* GC7000 - this core must load shaders from memory. */ screen->specs.vs_offset = 0; diff --git a/src/gallium/drivers/etnaviv/etnaviv_zsa.c b/src/gallium/drivers/etnaviv/etnaviv_zsa.c index 2d3c99f1541..98c7db1411e 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_zsa.c +++ b/src/gallium/drivers/etnaviv/etnaviv_zsa.c @@ -100,8 +100,16 @@ etna_zsa_state_create(struct pipe_context *pctx, VIVS_PE_ALPHA_OP_ALPHA_REF(float_to_ubyte(so->alpha_ref_value)); for (unsigned i = 0; i < 2; i++) { - const struct pipe_stencil_state *stencil_front = (so->stencil[1].enabled && so->stencil[1].valuemask) ? &so->stencil[i] : &so->stencil[0]; - const struct pipe_stencil_state *stencil_back = (so->stencil[1].enabled && so->stencil[1].valuemask) ? &so->stencil[!i] : &so->stencil[0]; + const struct pipe_stencil_state *stencil_front, *stencil_back; + + if (so->stencil[1].enabled && + (screen->specs.correct_stencil_valuemask || so->stencil[1].valuemask)) { + stencil_front = &so->stencil[i]; + stencil_back = &so->stencil[!i]; + } else { + stencil_front = stencil_back = &so->stencil[0]; + } + cs->PE_STENCIL_OP[i] = VIVS_PE_STENCIL_OP_FUNC_FRONT(stencil_front->func) | VIVS_PE_STENCIL_OP_FUNC_BACK(stencil_back->func) |