From 0cb88ddca295bc99f47fa0572b7142d119a43b60 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tapani=20P=C3=A4lli?= Date: Tue, 5 Apr 2022 09:57:46 +0300 Subject: [PATCH] iris: implement required PSS sync for Wa_18019816803 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit According to WA description, we need to track DS write state and emit a PSS_STALL_SYNC whenever that state changes. Signed-off-by: Tapani Pälli Reviewed-by: Lionel Landwerlin Part-of: --- src/gallium/drivers/iris/iris_blorp.c | 10 ++++++ src/gallium/drivers/iris/iris_context.h | 4 +++ src/gallium/drivers/iris/iris_state.c | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/gallium/drivers/iris/iris_blorp.c b/src/gallium/drivers/iris/iris_blorp.c index deb7856..e3dd862 100644 --- a/src/gallium/drivers/iris/iris_blorp.c +++ b/src/gallium/drivers/iris/iris_blorp.c @@ -301,6 +301,16 @@ iris_blorp_exec_render(struct blorp_batch *blorp_batch, PIPE_CONTROL_STALL_AT_SCOREBOARD); #endif + /* Check if blorp ds state matches ours. */ + if (intel_needs_workaround(batch->screen->devinfo, 18019816803)) { + const bool blorp_ds_state = + params->depth.enabled || params->stencil.enabled; + if (ice->state.ds_write_state != blorp_ds_state) { + blorp_batch->flags |= BLORP_BATCH_NEED_PSS_STALL_SYNC; + ice->state.ds_write_state = blorp_ds_state; + } + } + if (params->depth.enabled && !(blorp_batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL)) genX(emit_depth_state_workarounds)(ice, batch, ¶ms->depth.surf); diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 6736e8b..ad71aaa 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -118,6 +118,7 @@ enum { #define IRIS_DIRTY_RENDER_MISC_BUFFER_FLUSHES (1ull << 33) #define IRIS_DIRTY_COMPUTE_MISC_BUFFER_FLUSHES (1ull << 34) #define IRIS_DIRTY_VFG (1ull << 35) +#define IRIS_DIRTY_DS_WRITE_ENABLE (1ull << 36) #define IRIS_ALL_DIRTY_FOR_COMPUTE (IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES | \ IRIS_DIRTY_COMPUTE_MISC_BUFFER_FLUSHES) @@ -821,6 +822,9 @@ struct iris_context { /** Are stencil writes enabled? (Stencil buffer may or may not exist.) */ bool stencil_writes_enabled; + /** Current/upcoming ds_write_state for Wa_18019816803. */ + bool ds_write_state; + /** Do we have integer RT in current framebuffer state? */ bool has_integer_rt; diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index a00fc6d..7748d88 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -1682,6 +1682,9 @@ struct iris_depth_stencil_alpha_state { /** Outbound to Gfx8-9 PMA stall equations */ bool depth_test_enabled; + + /** Tracking state of DS writes for Wa_18019816803. */ + bool ds_write_state; }; /** @@ -1699,6 +1702,46 @@ iris_create_zsa_state(struct pipe_context *ctx, bool two_sided_stencil = state->stencil[1].enabled; + bool depth_write_enabled = false; + bool stencil_write_enabled = false; + + /* Depth writes enabled? */ + if (state->depth_writemask && + ((!state->depth_enabled) || + ((state->depth_func != PIPE_FUNC_NEVER) && + (state->depth_func != PIPE_FUNC_EQUAL)))) + depth_write_enabled = true; + + bool stencil_all_keep = + state->stencil[0].fail_op == PIPE_STENCIL_OP_KEEP && + state->stencil[0].zfail_op == PIPE_STENCIL_OP_KEEP && + state->stencil[0].zpass_op == PIPE_STENCIL_OP_KEEP && + (!two_sided_stencil || + (state->stencil[1].fail_op == PIPE_STENCIL_OP_KEEP && + state->stencil[1].zfail_op == PIPE_STENCIL_OP_KEEP && + state->stencil[1].zpass_op == PIPE_STENCIL_OP_KEEP)); + + bool stencil_mask_zero = + state->stencil[0].writemask == 0 || + (!two_sided_stencil || state->stencil[1].writemask == 0); + + bool stencil_func_never = + state->stencil[0].func == PIPE_FUNC_NEVER && + state->stencil[0].fail_op == PIPE_STENCIL_OP_KEEP && + (!two_sided_stencil || + (state->stencil[1].func == PIPE_FUNC_NEVER && + state->stencil[1].fail_op == PIPE_STENCIL_OP_KEEP)); + + /* Stencil writes enabled? */ + if (state->stencil[0].writemask != 0 || + ((two_sided_stencil && state->stencil[1].writemask != 0) && + (!stencil_all_keep && + !stencil_mask_zero && + !stencil_func_never))) + stencil_write_enabled = true; + + cso->ds_write_state = depth_write_enabled || stencil_write_enabled; + cso->alpha_enabled = state->alpha_enabled; cso->alpha_func = state->alpha_func; cso->alpha_ref_value = state->alpha_ref_value; @@ -1781,6 +1824,12 @@ iris_bind_zsa_state(struct pipe_context *ctx, void *state) ice->state.depth_writes_enabled = new_cso->depth_writes_enabled; ice->state.stencil_writes_enabled = new_cso->stencil_writes_enabled; + /* State ds_write_enable changed, need to flag dirty DS. */ + if (!old_cso || (ice->state.ds_write_state != new_cso->ds_write_state)) { + ice->state.dirty |= IRIS_DIRTY_DS_WRITE_ENABLE; + ice->state.ds_write_state = new_cso->ds_write_state; + } + #if GFX_VER >= 12 if (cso_changed(depth_bounds)) ice->state.dirty |= IRIS_DIRTY_DEPTH_BOUNDS; @@ -7085,6 +7134,14 @@ iris_upload_dirty_render_state(struct iris_context *ice, iris_batch_emit(batch, cso->wmds, sizeof(cso->wmds)); #endif + /* Depth or stencil write changed in cso. */ + if (intel_needs_workaround(batch->screen->devinfo, 18019816803) && + (dirty & IRIS_DIRTY_DS_WRITE_ENABLE)) { + iris_emit_pipe_control_flush( + batch, "workaround: PSS stall after DS write enable change", + PIPE_CONTROL_PSS_STALL_SYNC); + } + #if GFX_VER >= 12 iris_batch_emit(batch, cso->depth_bounds, sizeof(cso->depth_bounds)); #endif -- 2.7.4