From 9b1008f3bc395c141416b00aa41f758db4b7ee4f Mon Sep 17 00:00:00 2001 From: "Juan A. Suarez Romero" Date: Tue, 27 Feb 2024 13:46:18 +0100 Subject: [PATCH] v3d: disable Early Z for multisampled 16-bit depth buffers Besides disabling early-z when a frame is an odd width or height, we need to disable it if the buffer is 16-bit and multisampled. Note that the ZS state can change after we decided globably the early-Z. In this case, we need to re-evaluate the decision. Reviewed-by: Iago Toral Quiroga Signed-off-by: Juan A. Suarez Romero Part-of: --- src/gallium/drivers/v3d/v3d_context.h | 7 +++++ src/gallium/drivers/v3d/v3dx_draw.c | 40 +++++++++++++++++---------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index ea86df23913..154e8319c56 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -482,6 +482,13 @@ struct v3d_job { */ bool decided_global_ez_enable; + /** + * When we decide if we nee to disable early Z/S gobally, track the + * Z-state we used to make that decision so we can change the decision + * if the state changes. + */ + struct v3d_depth_stencil_alpha_state *global_ez_zsa_decision_state; + /** * If this job has been configured to use early Z/S clear. */ diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index b8029efbde9..8fb99f735ab 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -832,13 +832,15 @@ v3d_update_job_ez(struct v3d_context *v3d, struct v3d_job *job) return; } - /* If this is the first time we update EZ state for this job we first - * check if there is anything that requires disabling it completely - * for the entire job (based on state that is not related to the - * current draw call and pipeline state). + /* When we update the EZ state we first check if there is anything + * that requires disabling it completely for the entire job (based on + * state that is not related to the current draw call and pipeline + * state). */ - if (!job->decided_global_ez_enable) { + if (!job->decided_global_ez_enable || + job->global_ez_zsa_decision_state != v3d->zsa) { job->decided_global_ez_enable = true; + job->global_ez_zsa_decision_state = v3d->zsa; if (!job->zsbuf) { job->first_ez_state = V3D_EZ_DISABLED; @@ -847,19 +849,29 @@ v3d_update_job_ez(struct v3d_context *v3d, struct v3d_job *job) } /* GFXH-1918: the early-Z buffer may load incorrect depth - * values if the frame has odd width or height. Disable early-Z - * in this case. + * values if the frame has odd width or height, or if the + * buffer is 16-bit and multisampled. Disable early-Z in these + * cases. */ bool needs_depth_load = v3d->zsa && job->zsbuf && v3d->zsa->base.depth_enabled && (PIPE_CLEAR_DEPTH & ~job->clear); - if (needs_depth_load && - ((job->draw_width % 2 != 0) || (job->draw_height % 2 != 0))) { - perf_debug("Loading depth buffer for framebuffer with odd width " - "or height disables early-Z tests\n"); - job->first_ez_state = V3D_EZ_DISABLED; - job->ez_state = V3D_EZ_DISABLED; - return; + if (needs_depth_load) { + if (job->zsbuf->texture->format == PIPE_FORMAT_Z16_UNORM && + job->zsbuf->texture->nr_samples > 0) { + perf_debug("Loading 16-bit multisampled depth buffer " + "disables early-Z tests\n"); + job->first_ez_state = V3D_EZ_DISABLED; + job->ez_state = V3D_EZ_DISABLED; + return; + } + if ((job->draw_width % 2 != 0) || (job->draw_height % 2 != 0)) { + perf_debug("Loading depth buffer for framebuffer with " + "odd width or height disables early-Z tests\n"); + job->first_ez_state = V3D_EZ_DISABLED; + job->ez_state = V3D_EZ_DISABLED; + return; + } } }