From 07cfa2bd96e58e059a35ac2a4e03f7e093144bf4 Mon Sep 17 00:00:00 2001 From: "Juan A. Suarez Romero" Date: Tue, 19 Apr 2022 16:52:44 +0200 Subject: [PATCH] v3d: enable early Z/S clears This performance optimization can be enabled if we are clearing Z/S buffer, and not storing or loading it. v2: - Add assertion on depth/stencil job loads (Iago) Signed-off-by: Juan A. Suarez Romero Reviewed-by: Iago Toral Quiroga Part-of: --- src/gallium/drivers/v3d/v3d_context.h | 5 +++++ src/gallium/drivers/v3d/v3dx_rcl.c | 14 ++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index d8c2191074e..5bfe53ee6fc 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -470,6 +470,11 @@ struct v3d_job { */ enum v3d_ez_state first_ez_state; + /** + * If this job has been configured to use early Z/S clear. + */ + bool early_zs_clear; + /** * Number of draw calls (not counting full buffer clears) queued in * the current job. diff --git a/src/gallium/drivers/v3d/v3dx_rcl.c b/src/gallium/drivers/v3d/v3dx_rcl.c index 088d454e95a..7c85525bc60 100644 --- a/src/gallium/drivers/v3d/v3dx_rcl.c +++ b/src/gallium/drivers/v3d/v3dx_rcl.c @@ -245,6 +245,7 @@ v3d_rcl_emit_loads(struct v3d_job *job, struct v3d_cl *cl, int layer) if ((loads_pending & PIPE_CLEAR_DEPTHSTENCIL) && (V3D_VERSION >= 40 || (job->zsbuf && job->zsbuf->texture->nr_samples > 1))) { + assert(!job->early_zs_clear); struct pipe_surface *src = job->bbuf ? job->bbuf : job->zsbuf; struct v3d_resource *rsc = v3d_resource(src->texture); @@ -345,6 +346,7 @@ v3d_rcl_emit_stores(struct v3d_job *job, struct v3d_cl *cl, int layer) if (job->store & PIPE_CLEAR_DEPTHSTENCIL && job->zsbuf && !(V3D_VERSION < 40 && job->zsbuf->texture->nr_samples <= 1)) { + assert(!job->early_zs_clear); struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture); if (rsc->separate_stencil) { if (job->store & PIPE_CLEAR_DEPTH) { @@ -418,7 +420,7 @@ v3d_rcl_emit_stores(struct v3d_job *job, struct v3d_cl *cl, int layer) */ if (job->clear) { cl_emit(cl, CLEAR_TILE_BUFFERS, clear) { - clear.clear_z_stencil_buffer = true; + clear.clear_z_stencil_buffer = !job->early_zs_clear; clear.clear_all_render_targets = true; } } @@ -657,7 +659,7 @@ emit_render_layer(struct v3d_job *job, uint32_t layer) } if (i == 0 || do_double_initial_tile_clear(job)) { cl_emit(&job->rcl, CLEAR_TILE_BUFFERS, clear) { - clear.clear_z_stencil_buffer = true; + clear.clear_z_stencil_buffer = !job->early_zs_clear; clear.clear_all_render_targets = true; } } @@ -724,9 +726,13 @@ 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 */ - /* XXX: Early D/S clear */ + job->early_zs_clear = (job->clear & PIPE_CLEAR_DEPTHSTENCIL) && + !(job->load & PIPE_CLEAR_DEPTHSTENCIL) && + !(job->store & PIPE_CLEAR_DEPTHSTENCIL); + + config.early_depth_stencil_clear = job->early_zs_clear; +#endif /* V3D_VERSION >= 40 */ switch (job->first_ez_state) { case V3D_EZ_UNDECIDED: