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:
committed by
Marge Bot
parent
07cfa2bd96
commit
f21e396f4c
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user