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 commit7fe91c9f66
)
This commit is contained in:
@@ -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"
|
||||
},
|
||||
|
@@ -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) |
|
||||
|
Reference in New Issue
Block a user