Mesa (main): v3dv: don't be too aggressive disabling early Z
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jun 1 06:46:51 UTC 2022
Module: Mesa
Branch: main
Commit: 0f65838933bfee7c189ffbd17fa1d04a005db8c3
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0f65838933bfee7c189ffbd17fa1d04a005db8c3
Author: Iago Toral Quiroga <itoral at igalia.com>
Date: Mon May 30 11:28:50 2022 +0200
v3dv: don't be too aggressive disabling early Z
When we have a draw call that is incompatible with EZ we should only
disable EZ for the remaining of the job in the case that both of the
following conditions are met:
1. The cause for the incompatibility is an incompatible depth test
direction.
2. The pipeline does Z writes.
Otherwise it is enough to disable EZ temporarily only for draw calls
with the incompatible pipeline.
Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16794>
---
src/broadcom/vulkan/v3dv_pipeline.c | 13 ++++++-
src/broadcom/vulkan/v3dv_private.h | 5 +++
src/broadcom/vulkan/v3dvx_cmd_buffer.c | 64 ++++++++++++++++++++--------------
3 files changed, 55 insertions(+), 27 deletions(-)
diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c
index 63a8efe984d..0a18d095051 100644
--- a/src/broadcom/vulkan/v3dv_pipeline.c
+++ b/src/broadcom/vulkan/v3dv_pipeline.c
@@ -2882,6 +2882,7 @@ pipeline_set_ez_state(struct v3dv_pipeline *pipeline,
break;
default:
pipeline->ez_state = V3D_EZ_DISABLED;
+ pipeline->incompatible_ez_test = true;
break;
}
@@ -2891,6 +2892,14 @@ pipeline_set_ez_state(struct v3dv_pipeline *pipeline,
!stencil_op_is_no_op(&ds_info->back))) {
pipeline->ez_state = V3D_EZ_DISABLED;
}
+
+ /* If the FS writes Z, then it may update against the chosen EZ direction */
+ struct v3dv_shader_variant *fs_variant =
+ pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT];
+ if (fs_variant && fs_variant->prog_data.fs->writes_z &&
+ !fs_variant->prog_data.fs->writes_z_from_fep) {
+ pipeline->ez_state = V3D_EZ_DISABLED;
+ }
}
static bool
@@ -3047,7 +3056,6 @@ pipeline_init(struct v3dv_pipeline *pipeline,
rs_info, pv_info, ls_info,
ms_info);
- pipeline_set_ez_state(pipeline, ds_info);
enable_depth_bias(pipeline, rs_info);
pipeline_set_sample_mask(pipeline, ms_info);
pipeline_set_sample_rate_shading(pipeline, ms_info);
@@ -3082,6 +3090,9 @@ pipeline_init(struct v3dv_pipeline *pipeline,
pipeline->default_attribute_values = NULL;
}
+ /* This must be done after the pipeline has been compiled */
+ pipeline_set_ez_state(pipeline, ds_info);
+
return result;
}
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index a191e9ed19c..3656db97ac5 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -1913,6 +1913,11 @@ struct v3dv_pipeline {
enum v3dv_ez_state ez_state;
+ /* If ez_state is V3D_EZ_DISABLED, if the reason for disabling is that the
+ * pipeline selects an incompatible depth test function.
+ */
+ bool incompatible_ez_test;
+
bool msaa;
bool sample_rate_shading;
uint32_t sample_mask;
diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
index 21bf3c4cf9b..ad3e9ba35a9 100644
--- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
@@ -1400,7 +1400,10 @@ v3dX(cmd_buffer_emit_varyings_state)(struct v3dv_cmd_buffer *cmd_buffer)
}
}
-static void
+/* Updates job early Z state tracking. Returns False if EZ must be disabled
+ * for the current draw call.
+ */
+static bool
job_update_ez_state(struct v3dv_job *job,
struct v3dv_pipeline *pipeline,
struct v3dv_cmd_buffer *cmd_buffer)
@@ -1414,9 +1417,15 @@ job_update_ez_state(struct v3dv_job *job,
*/
if (job->first_ez_state == V3D_EZ_DISABLED) {
assert(job->ez_state == V3D_EZ_DISABLED);
- return;
+ return false;
}
+ /* If ez_state is V3D_EZ_DISABLED it means that we have already decided
+ * that EZ must be disabled for the remaining of the frame.
+ */
+ if (job->ez_state == V3D_EZ_DISABLED)
+ return false;
+
/* This is part of the pre draw call handling, so we should be inside a
* render pass.
*/
@@ -1436,7 +1445,7 @@ job_update_ez_state(struct v3dv_job *job,
if (subpass->ds_attachment.attachment == VK_ATTACHMENT_UNUSED) {
job->first_ez_state = V3D_EZ_DISABLED;
job->ez_state = V3D_EZ_DISABLED;
- return;
+ return false;
}
/* GFXH-1918: the early-z buffer may load incorrect depth values
@@ -1465,7 +1474,7 @@ job_update_ez_state(struct v3dv_job *job,
"without framebuffer info disables early-z tests.\n");
job->first_ez_state = V3D_EZ_DISABLED;
job->ez_state = V3D_EZ_DISABLED;
- return;
+ return false;
}
if (((fb->width % 2) != 0 || (fb->height % 2) != 0)) {
@@ -1473,7 +1482,7 @@ job_update_ez_state(struct v3dv_job *job,
"or height disables early-Z tests.\n");
job->first_ez_state = V3D_EZ_DISABLED;
job->ez_state = V3D_EZ_DISABLED;
- return;
+ return false;
}
}
}
@@ -1481,16 +1490,8 @@ job_update_ez_state(struct v3dv_job *job,
/* Otherwise, we can decide to selectively enable or disable EZ for draw
* calls using the CFG_BITS packet based on the bound pipeline state.
*/
-
- /* If the FS writes Z, then it may update against the chosen EZ direction */
- struct v3dv_shader_variant *fs_variant =
- pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT];
- if (fs_variant->prog_data.fs->writes_z &&
- !fs_variant->prog_data.fs->writes_z_from_fep) {
- job->ez_state = V3D_EZ_DISABLED;
- return;
- }
-
+ bool disable_ez = false;
+ bool incompatible_test = false;
switch (pipeline->ez_state) {
case V3D_EZ_UNDECIDED:
/* If the pipeline didn't pick a direction but didn't disable, then go
@@ -1504,24 +1505,35 @@ job_update_ez_state(struct v3dv_job *job,
/* If the pipeline picked a direction, then it needs to match the current
* direction if we've decided on one.
*/
- if (job->ez_state == V3D_EZ_UNDECIDED)
+ if (job->ez_state == V3D_EZ_UNDECIDED) {
job->ez_state = pipeline->ez_state;
- else if (job->ez_state != pipeline->ez_state)
- job->ez_state = V3D_EZ_DISABLED;
+ } else if (job->ez_state != pipeline->ez_state) {
+ disable_ez = true;
+ incompatible_test = true;
+ }
break;
case V3D_EZ_DISABLED:
- /* If the pipeline disables EZ because of a bad Z func or stencil
- * operation, then we can't do any more EZ in this frame.
- */
- job->ez_state = V3D_EZ_DISABLED;
+ disable_ez = true;
+ incompatible_test = pipeline->incompatible_ez_test;
break;
}
- if (job->first_ez_state == V3D_EZ_UNDECIDED &&
- job->ez_state != V3D_EZ_DISABLED) {
+ if (job->first_ez_state == V3D_EZ_UNDECIDED && !disable_ez) {
+ assert(job->ez_state != V3D_EZ_DISABLED);
job->first_ez_state = job->ez_state;
}
+
+ /* If we had to disable EZ because of an incompatible test direction and
+ * and the pipeline writes depth then we need to disable EZ for the rest of
+ * the frame.
+ */
+ if (incompatible_test && pipeline->z_updates_enable) {
+ assert(disable_ez);
+ job->ez_state = V3D_EZ_DISABLED;
+ }
+
+ return !disable_ez;
}
void
@@ -1533,13 +1545,13 @@ v3dX(cmd_buffer_emit_configuration_bits)(struct v3dv_cmd_buffer *cmd_buffer)
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
assert(pipeline);
- job_update_ez_state(job, pipeline, cmd_buffer);
+ bool enable_ez = job_update_ez_state(job, pipeline, cmd_buffer);
v3dv_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(CFG_BITS));
v3dv_return_if_oom(cmd_buffer, NULL);
cl_emit_with_prepacked(&job->bcl, CFG_BITS, pipeline->cfg_bits, config) {
- config.early_z_enable = job->ez_state != V3D_EZ_DISABLED;
+ config.early_z_enable = enable_ez;
config.early_z_updates_enable = config.early_z_enable &&
pipeline->z_updates_enable;
}
More information about the mesa-commit
mailing list