iris: do PIPELINE_SELECT for render engine, add flushes, GLK hacks
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 19 Oct 2018 09:00:13 +0000 (02:00 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:09 +0000 (10:26 -0800)
src/gallium/drivers/iris/iris_state.c

index b30d4b7b27f476b9a4914825d5db9ffc5847c34f..9af89efd764adb7ed57ce54a916cc9726f40377a 100644 (file)
@@ -485,6 +485,74 @@ _iris_emit_lri(struct iris_batch *batch, uint32_t reg, uint32_t val)
 }
 #define iris_emit_lri(b, r, v) _iris_emit_lri(b, GENX(r##_num), v)
 
+static void
+emit_pipeline_select(struct iris_batch *batch, uint32_t pipeline)
+{
+#if GEN_GEN >= 8 && GEN_GEN < 10
+   /* From the Broadwell PRM, Volume 2a: Instructions, PIPELINE_SELECT:
+    *
+    *   Software must clear the COLOR_CALC_STATE Valid field in
+    *   3DSTATE_CC_STATE_POINTERS command prior to send a PIPELINE_SELECT
+    *   with Pipeline Select set to GPGPU.
+    *
+    * The internal hardware docs recommend the same workaround for Gen9
+    * hardware too.
+    */
+   if (pipeline == GPGPU)
+      iris_emit_cmd(batch, GENX(3DSTATE_CC_STATE_POINTERS), t);
+#endif
+
+
+   /* From "BXML » GT » MI » vol1a GPU Overview » [Instruction]
+    * PIPELINE_SELECT [DevBWR+]":
+    *
+    *    "Project: DEVSNB+
+    *
+    *     Software must ensure all the write caches are flushed through a
+    *     stalling PIPE_CONTROL command followed by another PIPE_CONTROL
+    *     command to invalidate read only caches prior to programming
+    *     MI_PIPELINE_SELECT command to change the Pipeline Select Mode."
+    */
+    iris_emit_pipe_control_flush(batch,
+                                 PIPE_CONTROL_RENDER_TARGET_FLUSH |
+                                 PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+                                 PIPE_CONTROL_DATA_CACHE_FLUSH |
+                                 PIPE_CONTROL_CS_STALL);
+
+    iris_emit_pipe_control_flush(batch,
+                                 PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
+                                 PIPE_CONTROL_CONST_CACHE_INVALIDATE |
+                                 PIPE_CONTROL_STATE_CACHE_INVALIDATE |
+                                 PIPE_CONTROL_INSTRUCTION_INVALIDATE);
+
+   iris_emit_cmd(batch, GENX(PIPELINE_SELECT), sel) {
+#if GEN_GEN >= 9
+      sel.MaskBits = 3;
+#endif
+      sel.PipelineSelection = pipeline;
+   }
+}
+
+UNUSED static void
+init_glk_barrier_mode(struct iris_batch *batch, uint32_t value)
+{
+#if GEN_GEN == 9
+   /* 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 reg_val;
+   iris_pack_state(GENX(SLICE_COMMON_ECO_CHICKEN1), &reg_val, reg) {
+      reg.GLKBarrierMode = value;
+      reg.GLKBarrierModeMask = 1;
+   }
+   iris_emit_lri(batch, SLICE_COMMON_ECO_CHICKEN1, reg_val);
+#endif
+}
+
 /**
  * Upload the initial GPU state for a render context.
  *
@@ -497,10 +565,13 @@ iris_init_render_context(struct iris_screen *screen,
                          struct iris_vtable *vtbl,
                          struct pipe_debug_callback *dbg)
 {
+   UNUSED const struct gen_device_info *devinfo = &screen->devinfo;
    uint32_t reg_val;
 
    iris_init_batch(batch, screen, vtbl, dbg, I915_EXEC_RENDER);
 
+   emit_pipeline_select(batch, _3D);
+
    flush_for_state_base_change(batch);
 
    /* We program most base addresses once at context initialization time.
@@ -555,6 +626,9 @@ iris_init_render_context(struct iris_screen *screen,
       reg.PartialResolveDisableInVCMask = true;
    }
    iris_emit_lri(batch, CACHE_MODE_1, reg_val);
+
+   if (devinfo->is_geminilake)
+      init_glk_barrier_mode(batch, GLK_BARRIER_MODE_3D_HULL);
 #endif
 
 #if GEN_GEN == 11
@@ -616,16 +690,16 @@ iris_init_compute_context(struct iris_screen *screen,
                           struct iris_vtable *vtbl,
                           struct pipe_debug_callback *dbg)
 {
+   UNUSED const struct gen_device_info *devinfo = &screen->devinfo;
+
    iris_init_batch(batch, screen, vtbl, dbg, I915_EXEC_RENDER);
 
-   /* XXX: PIPE_CONTROLs */
+   emit_pipeline_select(batch, GPGPU);
 
-   iris_emit_cmd(batch, GENX(PIPELINE_SELECT), sel) {
-#if GEN_GEN >= 9
-      sel.MaskBits = 3;
+#if GEN_GEN == 9
+   if (devinfo->is_geminilake)
+      init_glk_barrier_mode(batch, GLK_BARRIER_MODE_GPGPU);
 #endif
-      sel.PipelineSelection = GPGPU;
-   }
 
    iris_emit_cmd(batch, GENX(STATE_BASE_ADDRESS), sba) {
    #if 0