iris: Some tidying for preemption support
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 24 Apr 2019 23:43:36 +0000 (16:43 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 25 Apr 2019 18:26:24 +0000 (11:26 -0700)
Just enable it during init_render_context on Gen10+, and move the
Gen9 state tracking into iris_genx_state so it only exists on Gen9.

Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
src/gallium/drivers/iris/iris_context.c
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_draw.c
src/gallium/drivers/iris/iris_state.c

index 91cd6a02262bc9f781a74e2957b295cd9d24bf34..a1d11755a24110cfc28ffa18e4ee83e722d66a84 100644 (file)
@@ -218,8 +218,6 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags)
 
    ice->vtbl.init_render_context(screen, &ice->batches[IRIS_BATCH_RENDER],
                                  &ice->vtbl, &ice->dbg);
-   if (screen->devinfo.gen == 10)
-      gen10_iris_enable_obj_preemption(ice, &ice->batches[IRIS_BATCH_RENDER], true);
    ice->vtbl.init_compute_context(screen, &ice->batches[IRIS_BATCH_COMPUTE],
                                   &ice->vtbl, &ice->dbg);
 
index 79e78d0adb70f1b9c839b310c04f649dfc2fb3bd..1153cb84bb93e56db602fb75181963f8ac6af34e 100644 (file)
@@ -542,8 +542,6 @@ struct iris_context {
       /** Bitfield of which vertex buffers are bound (non-null). */
       uint64_t bound_vertex_buffers;
 
-      bool object_preemption; /**< Object level preemption enabled. */
-
       bool primitive_restart;
       unsigned cut_index;
       enum pipe_prim_type prim_mode:8;
@@ -819,6 +817,7 @@ void iris_cache_flush_for_depth(struct iris_batch *batch, struct iris_bo *bo);
 void iris_depth_cache_add_bo(struct iris_batch *batch, struct iris_bo *bo);
 
 /* iris_state.c */
-void gen9_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable);
-void gen10_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable);
+void gen9_toggle_preemption(struct iris_context *ice,
+                            struct iris_batch *batch,
+                            const struct pipe_draw_info *draw);
 #endif
index c859d93c009638b5f2850b86b6b7164e7fe2f1fe..94af728c693f9106cafa486ba63914f423be862a 100644 (file)
 #include "iris_context.h"
 #include "iris_defines.h"
 
-/**
- * Implement workarounds for preemption:
- *    - WaDisableMidObjectPreemptionForGSLineStripAdj
- *    - WaDisableMidObjectPreemptionForTrifanOrPolygon
- *    - WaDisableMidObjectPreemptionForLineLoop
- *    - WA#0798
- */
-static void
-gen9_emit_preempt_wa(struct iris_context *ice, struct iris_batch *batch,
-                     const struct pipe_draw_info *info)
-{
-   bool object_preemption = true;
-   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
-
-   /* Only apply these workarounds for gen9 */
-   assert(screen->devinfo.gen == 9);
-
-   /* WaDisableMidObjectPreemptionForGSLineStripAdj
-    *
-    *    WA: Disable mid-draw preemption when draw-call is a linestrip_adj and
-    *    GS is enabled.
-    */
-   if (ice->state.prim_mode == PIPE_PRIM_LINE_STRIP_ADJACENCY &&
-       ice->shaders.prog[MESA_SHADER_GEOMETRY])
-      object_preemption = false;
-
-   /* WaDisableMidObjectPreemptionForTrifanOrPolygon
-    *
-    *    TriFan miscompare in Execlist Preemption test. Cut index that is on a
-    *    previous context. End the previous, the resume another context with a
-    *    tri-fan or polygon, and the vertex count is corrupted. If we prempt
-    *    again we will cause corruption.
-    *
-    *    WA: Disable mid-draw preemption when draw-call has a tri-fan.
-    */
-   if (ice->state.prim_mode == PIPE_PRIM_TRIANGLE_FAN)
-      object_preemption = false;
-
-   /* WaDisableMidObjectPreemptionForLineLoop
-    *
-    *    VF Stats Counters Missing a vertex when preemption enabled.
-    *
-    *    WA: Disable mid-draw preemption when the draw uses a lineloop
-    *    topology.
-    */
-   if (ice->state.prim_mode == PIPE_PRIM_LINE_LOOP)
-      object_preemption = false;
-
-   /* WA#0798
-    *
-    *    VF is corrupting GAFS data when preempted on an instance boundary and
-    *    replayed with instancing enabled.
-    *
-    *    WA: Disable preemption when using instanceing.
-    */
-   if (info->instance_count > 1)
-      object_preemption = false;
-
-   gen9_iris_enable_obj_preemption(ice, batch, object_preemption);
-}
-
 /**
  * Record the current primitive mode and restart information, flagging
  * related packets as dirty if necessary.
@@ -178,6 +117,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 {
    struct iris_context *ice = (struct iris_context *) ctx;
    struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen;
+   const struct gen_device_info *devinfo = &screen->devinfo;
    struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
 
    if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
@@ -193,8 +133,8 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 
    iris_update_draw_info(ice, info);
 
-   if (screen->devinfo.gen == 9)
-     gen9_emit_preempt_wa(ice, batch, info);
+   if (devinfo->gen == 9)
+      gen9_toggle_preemption(ice, batch, info);
 
    iris_update_compiled_shaders(ice);
 
index 92275b48a4d53607b1a1e11f4decbcbc7c8ded6d..c0c0ed02e71c764e1be4adce72138fa64de4d9bb 100644 (file)
@@ -653,6 +653,24 @@ iris_emit_default_l3_config(struct iris_batch *batch,
    iris_emit_l3_config(batch, cfg, has_slm, wants_dc_cache);
 }
 
+#if GEN_GEN >= 9
+static void
+iris_enable_obj_preemption(struct iris_batch *batch, bool enable)
+{
+   uint32_t reg_val;
+
+   /* A fixed function pipe flush is required before modifying this field */
+   iris_emit_end_of_pipe_sync(batch, PIPE_CONTROL_RENDER_TARGET_FLUSH);
+
+   /* enable object level preemption */
+   iris_pack_state(GENX(CS_CHICKEN1), &reg_val, reg) {
+      reg.ReplayMode = enable;
+      reg.ReplayModeMask = true;
+   }
+   iris_emit_lri(batch, CS_CHICKEN1, reg_val);
+}
+#endif
+
 /**
  * Upload the initial GPU state for a render context.
  *
@@ -775,6 +793,11 @@ iris_init_render_context(struct iris_screen *screen,
          alloc.ConstantBufferSize = i == MESA_SHADER_FRAGMENT ? 8 : 6;
       }
    }
+
+#if GEN_GEN == 10
+   /* Gen11+ is enabled for us by the kernel. */
+   iris_enable_obj_preemption(batch, true);
+#endif
 }
 
 static void
@@ -826,6 +849,11 @@ struct iris_genx_state {
 
    uint32_t so_buffers[4 * GENX(3DSTATE_SO_BUFFER_length)];
 
+#if GEN_GEN == 9
+   /* Is object level preemption enabled? */
+   bool object_preemption;
+#endif
+
    struct {
 #if GEN_GEN == 8
       struct brw_image_param image_param[PIPE_MAX_SHADER_IMAGES];
@@ -6180,6 +6208,74 @@ genX(emit_urb_setup)(struct iris_context *ice,
    }
 }
 
+#if GEN_GEN == 9
+/**
+ * Preemption on Gen9 has to be enabled or disabled in various cases.
+ *
+ * See these workarounds for preemption:
+ *  - WaDisableMidObjectPreemptionForGSLineStripAdj
+ *  - WaDisableMidObjectPreemptionForTrifanOrPolygon
+ *  - WaDisableMidObjectPreemptionForLineLoop
+ *  - WA#0798
+ *
+ * We don't put this in the vtable because it's only used on Gen9.
+ */
+void
+gen9_toggle_preemption(struct iris_context *ice,
+                       struct iris_batch *batch,
+                       const struct pipe_draw_info *draw)
+{
+   struct iris_genx_state *genx = ice->state.genx;
+   bool object_preemption = true;
+
+   /* WaDisableMidObjectPreemptionForGSLineStripAdj
+    *
+    *    "WA: Disable mid-draw preemption when draw-call is a linestrip_adj
+    *     and GS is enabled."
+    */
+   if (draw->mode == PIPE_PRIM_LINE_STRIP_ADJACENCY &&
+       ice->shaders.prog[MESA_SHADER_GEOMETRY])
+      object_preemption = false;
+
+   /* WaDisableMidObjectPreemptionForTrifanOrPolygon
+    *
+    *    "TriFan miscompare in Execlist Preemption test. Cut index that is
+    *     on a previous context. End the previous, the resume another context
+    *     with a tri-fan or polygon, and the vertex count is corrupted. If we
+    *     prempt again we will cause corruption.
+    *
+    *     WA: Disable mid-draw preemption when draw-call has a tri-fan."
+    */
+   if (draw->mode == PIPE_PRIM_TRIANGLE_FAN)
+      object_preemption = false;
+
+   /* WaDisableMidObjectPreemptionForLineLoop
+    *
+    *    "VF Stats Counters Missing a vertex when preemption enabled.
+    *
+    *     WA: Disable mid-draw preemption when the draw uses a lineloop
+    *     topology."
+    */
+   if (draw->mode == PIPE_PRIM_LINE_LOOP)
+      object_preemption = false;
+
+   /* WA#0798
+    *
+    *    "VF is corrupting GAFS data when preempted on an instance boundary
+    *     and replayed with instancing enabled.
+    *
+    *     WA: Disable preemption when using instanceing."
+    */
+   if (draw->instance_count > 1)
+      object_preemption = false;
+
+   if (genx->object_preemption != object_preemption) {
+      iris_enable_obj_preemption(batch, object_preemption);
+      genx->object_preemption = object_preemption;
+   }
+}
+#endif
+
 void
 genX(init_state)(struct iris_context *ice)
 {
@@ -6278,32 +6374,3 @@ genX(init_state)(struct iris_context *ice)
       };
    }
 }
-
-#if GEN_GEN >= 9
-/* not called externally */
-void gen11_iris_enable_obj_preemption(struct iris_context *ice, struct iris_batch *batch, bool enable);
-
-void
-genX(iris_enable_obj_preemption)(struct iris_context *ice, struct iris_batch *batch, bool enable)
-{
-   uint32_t reg_val;
-   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
-
-   assert(screen->devinfo.gen >= 9);
-
-   if (enable == ice->state.object_preemption)
-      return;
-   ice->state.object_preemption = enable;
-
-   /* A fixed function pipe flush is required before modifying this field */
-   iris_emit_end_of_pipe_sync(batch,
-                              PIPE_CONTROL_RENDER_TARGET_FLUSH);
-
-   /* enable object level preemption */
-   iris_pack_state(GENX(CS_CHICKEN1), &reg_val, reg) {
-      reg.ReplayMode = enable;
-      reg.ReplayModeMask = true;
-   }
-   iris_emit_lri(batch, CS_CHICKEN1, reg_val);
-}
-#endif