intel: Apply Geminilake "Barrier Mode" workaround.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 2 Jan 2018 22:26:41 +0000 (14:26 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 9 Jan 2018 18:13:33 +0000 (10:13 -0800)
Apparently, Geminilake requires you to whack a chicken bit to select
either compute or tessellation mode for barriers.  The recommendation
is to switch between them at PIPELINE_SELECT time.

We may not need to do this all the time, but I don't know that it hurts
either.  PIPELINE_SELECT is already a pretty giant stall.

This appears to fix hangs in tessellation control shaders with barriers
on Geminilake.  Note that this requires a corresponding kernel change,

    drm/i915: Whitelist SLICE_COMMON_ECO_CHICKEN1 on Geminilake.

in order for the register write to actually happen.  Without an updated
kernel, this register write will be noop'd and the fix will not work.

Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
src/intel/genxml/gen9.xml
src/intel/vulkan/genX_cmd_buffer.c
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_misc_state.c

index 1422463693dca387567c9c0a3199de8f91538348..f07ed748ac76123d7530e03df86e11beb8216a6c 100644 (file)
     <field name="Color Compression Disable Mask" start="31" end="31" type="bool"/>
   </register>
 
+  <register name="SLICE_COMMON_ECO_CHICKEN1" length="1" num="0x731c">
+    <field name="GLK Barrier Mode" start="7" end="7" type="uint">
+      <value name="GLK_BARRIER_MODE_GPGPU" value="0"/>
+      <value name="GLK_BARRIER_MODE_3D_HULL" value="1"/>
+    </field>
+    <field name="GLK Barrier Mode Mask" start="23" end="23" type="bool"/>
+  </register>
+
   <register name="GFX_ARB_ERROR_RPT" length="1" num="0x40a0">
     <field name="TLB Page Fault Error" start="0" end="0" type="bool"/>
     <field name="RSTRM PAVP Read Invalid" start="1" end="1" type="bool"/>
index b7253d5251321af6fe33e91f8f1df621821686f0..ac95f3ad05a05531913e3723c95d65d041cf841d 100644 (file)
@@ -2734,6 +2734,8 @@ static void
 genX(flush_pipeline_select)(struct anv_cmd_buffer *cmd_buffer,
                             uint32_t pipeline)
 {
+   UNUSED const struct gen_device_info *devinfo = &cmd_buffer->device->info;
+
    if (cmd_buffer->state.current_pipeline == pipeline)
       return;
 
@@ -2784,6 +2786,25 @@ genX(flush_pipeline_select)(struct anv_cmd_buffer *cmd_buffer,
       ps.PipelineSelection = pipeline;
    }
 
+#if GEN_GEN == 9
+   if (devinfo->is_geminilake) {
+      /* Project: DevGLK
+       *
+       * "This chicken bit works around a hardware issue with barrier logic
+       *  encountered when switching between GPGPU and 3D pipelines.  To
+       *  workaround the issue, this mode bit should be set after a pipeline
+       *  is selected."
+       */
+      uint32_t scec;
+      anv_pack_struct(&scec, GENX(SLICE_COMMON_ECO_CHICKEN1),
+                      .GLKBarrierMode =
+                          pipeline == GPGPU ? GLK_BARRIER_MODE_GPGPU
+                                            : GLK_BARRIER_MODE_3D_HULL,
+                      .GLKBarrierModeMask = 1);
+      emit_lri(&cmd_buffer->batch, GENX(SLICE_COMMON_ECO_CHICKEN1_num), scec);
+   }
+#endif
+
    cmd_buffer->state.current_pipeline = pipeline;
 }
 
index 99d41cf1a562e22f5e26db345d11833cbbe54d5d..8bf6f68b67c88ece887c29dbfce3759508eb1bcc 100644 (file)
@@ -1656,4 +1656,9 @@ enum brw_pixel_shader_coverage_mask_mode {
 #define CS_DEBUG_MODE2                     0x20d8 /* Gen9+ */
 # define CSDBG2_CONSTANT_BUFFER_ADDRESS_OFFSET_DISABLE (1 << 4)
 
+#define SLICE_COMMON_ECO_CHICKEN1          0x731c /* Gen9+ */
+# define GLK_SCEC_BARRIER_MODE_GPGPU       (0 << 7)
+# define GLK_SCEC_BARRIER_MODE_3D_HULL     (1 << 7)
+# define GLK_SCEC_BARRIER_MODE_MASK        REG_MASK(1 << 7)
+
 #endif
index a1ac0abe285ed76e9955dc398de3563178ca14d0..c4ef6812bff9b7b7fded0414863b747340f53916 100644 (file)
@@ -516,6 +516,21 @@ brw_emit_select_pipeline(struct brw_context *brw, enum brw_pipeline pipeline)
       OUT_BATCH(0);
       ADVANCE_BATCH();
    }
+
+   if (devinfo->is_geminilake) {
+      /* Project: DevGLK
+       *
+       * "This chicken bit works around a hardware issue with barrier logic
+       *  encountered when switching between GPGPU and 3D pipelines.  To
+       *  workaround the issue, this mode bit should be set after a pipeline
+       *  is selected."
+       */
+      const unsigned barrier_mode =
+         pipeline == BRW_RENDER_PIPELINE ? GLK_SCEC_BARRIER_MODE_3D_HULL
+                                         : GLK_SCEC_BARRIER_MODE_GPGPU;
+      brw_load_register_imm32(brw, SLICE_COMMON_ECO_CHICKEN1,
+                              barrier_mode | GLK_SCEC_BARRIER_MODE_MASK);
+   }
 }
 
 /**