v3d: disable early-Z on odd frame dimensions

The early-Z buffer may load incorrect depth values if the frame has an
od width or height. In this case we need to disable early-Z.

v3:
 - Set job->early_zs_clear only for V3D_VERSION >= 40 (Iago)
 - Check early-Z is disabled if no zsbuf (Iago)

v4:
 - Borrow comments from v3dv around v3d_update_job_ez() (Iago)

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3557
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16166>
This commit is contained in:
Juan A. Suarez Romero
2022-04-19 16:53:20 +02:00
committed by Marge Bot
parent 07cfa2bd96
commit f21e396f4c
3 changed files with 74 additions and 16 deletions
+6
View File
@@ -470,6 +470,12 @@ struct v3d_job {
*/
enum v3d_ez_state first_ez_state;
/**
* If we have already decided if we need to disable early Z/S
* completely for this job.
*/
bool decided_global_ez_enable;
/**
* If this job has been configured to use early Z/S clear.
*/
+43
View File
@@ -852,6 +852,49 @@ v3d_update_primitives_generated_counter(struct v3d_context *v3d,
static void
v3d_update_job_ez(struct v3d_context *v3d, struct v3d_job *job)
{
/* If first_ez_state is V3D_EZ_DISABLED it means that we have already
* determined that we should disable EZ completely for all draw calls
* in this job. This will cause us to disable EZ for the entire job in
* the Tile Rendering Mode RCL packet and when we do that we need to
* make sure we never emit a draw call in the job with EZ enabled in
* the CFG_BITS packet, so ez_state must also be V3D_EZ_DISABLED.
*/
if (job->first_ez_state == V3D_EZ_DISABLED) {
assert(job->ez_state == V3D_EZ_DISABLED);
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).
*/
if (!job->decided_global_ez_enable) {
job->decided_global_ez_enable = true;
if (!job->zsbuf) {
job->first_ez_state = V3D_EZ_DISABLED;
job->ez_state = V3D_EZ_DISABLED;
return;
}
/* 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.
*/
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;
}
}
switch (v3d->zsa->ez_state) {
case V3D_EZ_UNDECIDED:
/* If the Z/S state didn't pick a direction but didn't
+25 -16
View File
@@ -726,6 +726,31 @@ v3dX(emit_rcl)(struct v3d_job *job)
struct v3d_surface *surf = v3d_surface(job->zsbuf);
config.internal_depth_type = surf->internal_type;
}
#endif /* V3D_VERSION >= 40 */
if (job->decided_global_ez_enable) {
switch (job->first_ez_state) {
case V3D_EZ_UNDECIDED:
case V3D_EZ_LT_LE:
config.early_z_disable = false;
config.early_z_test_and_update_direction =
EARLY_Z_DIRECTION_LT_LE;
break;
case V3D_EZ_GT_GE:
config.early_z_disable = false;
config.early_z_test_and_update_direction =
EARLY_Z_DIRECTION_GT_GE;
break;
case V3D_EZ_DISABLED:
config.early_z_disable = true;
}
} else {
assert(job->draw_calls_queued == 0);
config.early_z_disable = true;
}
#if V3D_VERSION >= 40
assert(job->zsbuf || config.early_z_disable);
job->early_zs_clear = (job->clear & PIPE_CLEAR_DEPTHSTENCIL) &&
!(job->load & PIPE_CLEAR_DEPTHSTENCIL) &&
@@ -734,22 +759,6 @@ v3dX(emit_rcl)(struct v3d_job *job)
config.early_depth_stencil_clear = job->early_zs_clear;
#endif /* V3D_VERSION >= 40 */
switch (job->first_ez_state) {
case V3D_EZ_UNDECIDED:
case V3D_EZ_LT_LE:
config.early_z_disable = false;
config.early_z_test_and_update_direction =
EARLY_Z_DIRECTION_LT_LE;
break;
case V3D_EZ_GT_GE:
config.early_z_disable = false;
config.early_z_test_and_update_direction =
EARLY_Z_DIRECTION_GT_GE;
break;
case V3D_EZ_DISABLED:
config.early_z_disable = true;
}
config.image_width_pixels = job->draw_width;
config.image_height_pixels = job->draw_height;