i965/gen9: Add workarounds for object preemption.
authorRafael Antognolli <rafael.antognolli@intel.com>
Mon, 29 Oct 2018 17:19:54 +0000 (10:19 -0700)
committerRafael Antognolli <rafael.antognolli@intel.com>
Fri, 14 Dec 2018 17:40:27 +0000 (09:40 -0800)
Gen9 hardware requires some workarounds to disable preemption depending
on the type of primitive being emitted.

We implement this by adding a function that checks the primitive type
and number of instances right before the 3DPRIMITIVE.

For now, we just ignore blorp.  The only primitive it emits is
3DPRIM_RECTLIST, and since it's not listed in the workarounds, we can
safely leave preemption enabled when it happens. Or it will be disabled
by a previous 3DPRIMITIVE, which should be fine too.

v3:
 - Apply missing workarounds for instanced rendering and line loop (Ken)
 - Move workaround code to brw_draw_single_prim()

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Cc: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_draw.c

index b818a0d77a369a1f7ca7d08d750c43b9fd162761..ec4fe0b096f1c2f88fdb0bb6bb7f065d1d1c9340 100644 (file)
@@ -872,6 +872,66 @@ brw_finish_drawing(struct gl_context *ctx)
    }
 }
 
    }
 }
 
+/**
+ * Implement workarounds for preemption:
+ *    - WaDisableMidObjectPreemptionForGSLineStripAdj
+ *    - WaDisableMidObjectPreemptionForTrifanOrPolygon
+ *    - WaDisableMidObjectPreemptionForLineLoop
+ *    - WA#0798
+ */
+static void
+gen9_emit_preempt_wa(struct brw_context *brw,
+                     const struct _mesa_prim *prim)
+{
+   bool object_preemption = true;
+   const struct gen_device_info *devinfo = &brw->screen->devinfo;
+
+   /* Only apply these workarounds for gen9 */
+   assert(devinfo->gen == 9);
+
+   /* WaDisableMidObjectPreemptionForGSLineStripAdj
+    *
+    *    WA: Disable mid-draw preemption when draw-call is a linestrip_adj and
+    *    GS is enabled.
+    */
+   if (brw->primitive == _3DPRIM_LINESTRIP_ADJ && brw->gs.enabled)
+      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 (brw->primitive == _3DPRIM_TRIFAN)
+      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 (brw->primitive == _3DPRIM_LINELOOP)
+      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 (prim->num_instances > 1)
+      object_preemption = false;
+
+   brw_enable_obj_preemption(brw, object_preemption);
+}
+
 /* May fail if out of video memory for texture or vbo upload, or on
  * fallback conditions.
  */
 /* May fail if out of video memory for texture or vbo upload, or on
  * fallback conditions.
  */
@@ -987,6 +1047,9 @@ retry:
       brw_upload_render_state(brw);
    }
 
       brw_upload_render_state(brw);
    }
 
+   if (devinfo->gen == 9)
+      gen9_emit_preempt_wa(brw, prim);
+
    brw_emit_prim(brw, prim, brw->primitive, xfb_obj, stream);
 
    brw->batch.no_wrap = false;
    brw_emit_prim(brw, prim, brw->primitive, xfb_obj, stream);
 
    brw->batch.no_wrap = false;