Mesa (main): v3d: disable early-Z on odd frame dimensions
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed May 4 08:05:21 UTC 2022
Module: Mesa
Branch: main
Commit: f21e396f4c0bb41b4cbaec92b4d81bca69f8299e
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f21e396f4c0bb41b4cbaec92b4d81bca69f8299e
Author: Juan A. Suarez Romero <jasuarez at igalia.com>
Date: Tue Apr 19 16:53:20 2022 +0200
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 at igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16166>
---
src/gallium/drivers/v3d/v3d_context.h | 6 +++++
src/gallium/drivers/v3d/v3dx_draw.c | 43 +++++++++++++++++++++++++++++++++++
src/gallium/drivers/v3d/v3dx_rcl.c | 41 ++++++++++++++++++++-------------
3 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h
index 5bfe53ee6fc..5ba8727add3 100644
--- a/src/gallium/drivers/v3d/v3d_context.h
+++ b/src/gallium/drivers/v3d/v3d_context.h
@@ -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.
*/
diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c
index 80842b4066b..a3bc11907d7 100644
--- a/src/gallium/drivers/v3d/v3dx_draw.c
+++ b/src/gallium/drivers/v3d/v3dx_draw.c
@@ -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
diff --git a/src/gallium/drivers/v3d/v3dx_rcl.c b/src/gallium/drivers/v3d/v3dx_rcl.c
index 7c85525bc60..6147d6aef5a 100644
--- a/src/gallium/drivers/v3d/v3dx_rcl.c
+++ b/src/gallium/drivers/v3d/v3dx_rcl.c
@@ -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;
More information about the mesa-commit
mailing list