From da12da77fc27d2b53bd99c397ec2991560bfdf85 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 11 Nov 2022 17:20:41 +0100 Subject: [PATCH] etnaviv: switch to late Z when linear PE is used In linear PE mode the early and late depth stage do not only disagree about the cache layout, but they seem to fundamentally disagree about the buffer layout. When Z was written via the late stage, early tests always show spurious zfails, even if they are not in the same draw call. Cache flushing and pipe stalls don't help in that case. The only option to get reliable Z tests with linear render targets is to move all Z handling into the PE stage. Even when early Z writes are possible, we don't know if any other draw to the same surface needs late Z handling, so we must never use the early stage. Fixes: 53445284a427 ("etnaviv: add linear PE support") Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Part-of: (cherry picked from commit 7fe91c9f660f3b76e2c08c0824d226417231c822) --- .pick_status.json | 2 +- src/gallium/drivers/etnaviv/etnaviv_state.c | 32 ++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index e647ec10829..c806c6f0520 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -598,7 +598,7 @@ "description": "etnaviv: switch to late Z when linear PE is used", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "53445284a427f79e94607dc4ca2f8bd8ac293356" }, diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index 947486c65d2..df922d89819 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -714,12 +714,26 @@ etna_update_zsa(struct etna_context *ctx) struct etna_zsa_state *zsa = etna_zsa_state(zsa_state); struct etna_screen *screen = ctx->screen; uint32_t new_pe_depth, new_ra_depth; + bool early_z_allowed = !VIV_FEATURE(screen, chipFeatures, NO_EARLY_Z); bool late_z_write = false, early_z_write = false, late_z_test = false, early_z_test = false; + /* Linear PE breaks the combination of early test with late write, as it + * seems RA and PE disagree about the buffer layout in this mode. Fall back + * to late Z always even though early Z write might be possible, as we don't + * know if any other draws to the same surface require late Z write. + */ + if (ctx->framebuffer_s.nr_cbufs > 0) { + struct etna_surface *cbuf = etna_surface(ctx->framebuffer_s.cbufs[0]); + struct etna_resource *res = etna_resource(cbuf->base.texture); + + if (res->layout == ETNA_LAYOUT_LINEAR) + early_z_allowed = false; + } + if (zsa->z_write_enabled) { if (VIV_FEATURE(screen, chipMinorFeatures5, RA_WRITE_DEPTH) && - !VIV_FEATURE(screen, chipFeatures, NO_EARLY_Z) && + early_z_allowed && !zsa->stencil_enabled && !zsa_state->alpha_enabled && !shader_state->writes_z && @@ -730,7 +744,7 @@ etna_update_zsa(struct etna_context *ctx) } if (zsa->z_test_enabled) { - if (!VIV_FEATURE(screen, chipFeatures, NO_EARLY_Z) && + if (early_z_allowed && !zsa->stencil_modified && !shader_state->writes_z) early_z_test = true; @@ -738,20 +752,6 @@ etna_update_zsa(struct etna_context *ctx) late_z_test = true; } - /* Linear PE breaks the combination of early test with late write, as it - * seems RA and PE disagree about the cache layout in this mode. Switch to - * late test to work around this issue. - */ - if (ctx->framebuffer_s.nr_cbufs > 0) { - struct etna_surface *cbuf = etna_surface(ctx->framebuffer_s.cbufs[0]); - struct etna_resource *res = etna_resource(cbuf->base.texture); - - if (res->layout == ETNA_LAYOUT_LINEAR && early_z_test && late_z_write) { - early_z_test = false; - late_z_test = true; - } - } - new_pe_depth = VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC(zsa->z_test_enabled ? /* compare funcs have 1 to 1 mapping */ zsa_state->depth_func : PIPE_FUNC_ALWAYS) |