i965/gen10: Ignore push constant packets during context restore.
authorRafael Antognolli <rafael.antognolli@intel.com>
Thu, 25 Jan 2018 00:33:56 +0000 (16:33 -0800)
committerRafael Antognolli <rafael.antognolli@intel.com>
Fri, 26 Jan 2018 18:07:35 +0000 (10:07 -0800)
These packets were causing GPU hangs when the context was restored,
possibly because they were pointing to BO's that were already
unreferenced. So we tell the hardware to ignore such packets after the
batch buffer ends, since we know those BO's are not around anymore.

This change fixes GPU hangs on CNL. The (partial) solution to this
problem so far was to entirely disable push constants on this platform.

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Cc: Kenneth Graunke <kenneth@whitecape.org>
Cc: "18.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/mesa/drivers/dri/i965/brw_pipe_control.c
src/mesa/drivers/dri/i965/brw_pipe_control.h
src/mesa/drivers/dri/i965/intel_batchbuffer.c

index e28be34c8e814f806e82ad54f8755495affdb6a3..eb8ada631294e1edce054b12080666bdc1c4edec 100644 (file)
@@ -317,6 +317,55 @@ gen7_emit_vs_workaround_flush(struct brw_context *brw)
                                brw->workaround_bo, 0, 0);
 }
 
+/**
+ * From the PRM, Volume 2a:
+ *
+ *    "Indirect State Pointers Disable
+ *
+ *    At the completion of the post-sync operation associated with this pipe
+ *    control packet, the indirect state pointers in the hardware are
+ *    considered invalid; the indirect pointers are not saved in the context.
+ *    If any new indirect state commands are executed in the command stream
+ *    while the pipe control is pending, the new indirect state commands are
+ *    preserved.
+ *
+ *    [DevIVB+]: Using Invalidate State Pointer (ISP) only inhibits context
+ *    restoring of Push Constant (3DSTATE_CONSTANT_*) commands. Push Constant
+ *    commands are only considered as Indirect State Pointers. Once ISP is
+ *    issued in a context, SW must initialize by programming push constant
+ *    commands for all the shaders (at least to zero length) before attempting
+ *    any rendering operation for the same context."
+ *
+ * 3DSTATE_CONSTANT_* packets are restored during a context restore,
+ * even though they point to a BO that has been already unreferenced at
+ * the end of the previous batch buffer. This has been fine so far since
+ * we are protected by these scratch page (every address not covered by
+ * a BO should be pointing to the scratch page). But on CNL, it is
+ * causing a GPU hang during context restore at the 3DSTATE_CONSTANT_*
+ * instruction.
+ *
+ * The flag "Indirect State Pointers Disable" in PIPE_CONTROL tells the
+ * hardware to ignore previous 3DSTATE_CONSTANT_* packets during a
+ * context restore, so the mentioned hang doesn't happen. However,
+ * software must program push constant commands for all stages prior to
+ * rendering anything, so we flag them as dirty.
+ */
+void
+gen10_emit_isp_disable(struct brw_context *brw)
+{
+   const struct gen_device_info *devinfo = &brw->screen->devinfo;
+
+   brw_emit_pipe_control_write(brw,
+                               PIPE_CONTROL_ISP_DIS |
+                               PIPE_CONTROL_WRITE_IMMEDIATE,
+                               brw->workaround_bo, 0, 0);
+
+   brw->vs.base.push_constants_dirty = true;
+   brw->tcs.base.push_constants_dirty = true;
+   brw->tes.base.push_constants_dirty = true;
+   brw->gs.base.push_constants_dirty = true;
+   brw->wm.base.push_constants_dirty = true;
+}
 
 /**
  * Emit a PIPE_CONTROL command for gen7 with the CS Stall bit set.
index 6e9a404870d975dd5b6fe49236501b602a450af2..651cd4d3e70e7e2561647d5ff8a21b00446a32e5 100644 (file)
@@ -85,5 +85,6 @@ void brw_emit_post_sync_nonzero_flush(struct brw_context *brw);
 void brw_emit_depth_stall_flushes(struct brw_context *brw);
 void gen7_emit_vs_workaround_flush(struct brw_context *brw);
 void gen7_emit_cs_stall_flush(struct brw_context *brw);
+void gen10_emit_isp_disable(struct brw_context *brw);
 
 #endif
index 02bfd3f333c3e85c21a1ca67f8ae75e8a9f9bc9e..86d88a701f879080e908e3b8fe89d40ea099d978 100644 (file)
@@ -764,6 +764,10 @@ brw_finish_batch(struct brw_context *brw)
          brw_emit_pipe_control_flush(brw, PIPE_CONTROL_RENDER_TARGET_FLUSH |
                                           PIPE_CONTROL_CS_STALL);
       }
+
+      /* Do not restore push constant packets during context restore. */
+      if (devinfo->gen == 10)
+         gen10_emit_isp_disable(brw);
    }
 
    /* Emit MI_BATCH_BUFFER_END to finish our batch.  Note that execbuf2