iris: implement required PSS sync for Wa_18019816803
authorTapani Pälli <tapani.palli@intel.com>
Tue, 5 Apr 2022 06:57:46 +0000 (09:57 +0300)
committerMarge Bot <emma+marge@anholt.net>
Fri, 11 Aug 2023 07:15:49 +0000 (07:15 +0000)
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 <tapani.palli@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18411>

src/gallium/drivers/iris/iris_blorp.c
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_state.c

index deb7856..e3dd862 100644 (file)
@@ -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, &params->depth.surf);
index 6736e8b..ad71aaa 100644 (file)
@@ -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;
 
index a00fc6d..7748d88 100644 (file)
@@ -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