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: 53445284a4 ("etnaviv: add linear PE support")
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19686>
(cherry picked from commit 7fe91c9f660f3b76e2c08c0824d226417231c822)
This commit is contained in:
Lucas Stach 2022-11-11 17:20:41 +01:00 committed by Dylan Baker
parent 7b1b097dd0
commit da12da77fc
2 changed files with 17 additions and 17 deletions

View File

@ -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"
},

View File

@ -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) |