Workaround for SNB
authorXiang, Haihao <haihao.xiang@intel.com>
Fri, 6 Sep 2013 08:43:17 +0000 (16:43 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Wed, 13 Nov 2013 07:41:18 +0000 (15:41 +0800)
Backporting from d0184b5 in xf86-video-intel

Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
(cherry picked from commit e622ecedf169bccddc8910b45d92dbec7675441e)

src/intel_batchbuffer.c
src/intel_batchbuffer.h
src/intel_driver.h

index 94d968c..8b35744 100644 (file)
@@ -86,6 +86,16 @@ intel_batchbuffer_new(struct intel_driver_data *intel, int flag, int buffer_size
     batch->intel = intel;
     batch->flag = flag;
     batch->run = drm_intel_bo_mrb_exec;
+
+    if (IS_GEN6(intel->device_id) &&
+        flag == I915_EXEC_RENDER)
+        batch->wa_render_bo = dri_bo_alloc(intel->bufmgr,
+                                           "wa scratch",
+                                           4096,
+                                           4096);
+    else
+        batch->wa_render_bo = NULL;
+
     intel_batchbuffer_reset(batch, buffer_size);
 
     return batch;
@@ -99,6 +109,7 @@ void intel_batchbuffer_free(struct intel_batchbuffer *batch)
     }
 
     dri_bo_unreference(batch->buffer);
+    dri_bo_unreference(batch->wa_render_bo);
     free(batch);
 }
 
@@ -175,23 +186,46 @@ intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
     if (IS_GEN6(intel->device_id) ||
         IS_GEN7(intel->device_id)) {
         if (batch->flag == I915_EXEC_RENDER) {
-            BEGIN_BATCH(batch, 4);
-            OUT_BATCH(batch, CMD_PIPE_CONTROL | 0x2);
-
-            if (IS_GEN6(intel->device_id))
-                OUT_BATCH(batch, 
+            if (IS_GEN6(intel->device_id)) {
+                assert(batch->wa_render_bo);
+
+                BEGIN_BATCH(batch, 4 * 3);
+
+                OUT_BATCH(batch, CMD_PIPE_CONTROL | (4 - 2));
+                OUT_BATCH(batch,
+                          CMD_PIPE_CONTROL_CS_STALL |
+                          CMD_PIPE_CONTROL_STALL_AT_SCOREBOARD);
+                OUT_BATCH(batch, 0); /* address */
+                OUT_BATCH(batch, 0); /* write data */
+
+                OUT_BATCH(batch, CMD_PIPE_CONTROL | (4 - 2));
+                OUT_BATCH(batch, CMD_PIPE_CONTROL_WRITE_QWORD);
+                OUT_RELOC(batch,
+                          batch->wa_render_bo,
+                          I915_GEM_DOMAIN_INSTRUCTION,
+                          I915_GEM_DOMAIN_INSTRUCTION,
+                          0);
+                OUT_BATCH(batch, 0); /* write data */
+
+                /* now finally the _real flush */
+                OUT_BATCH(batch, CMD_PIPE_CONTROL | (4 - 2));
+                OUT_BATCH(batch,
                           CMD_PIPE_CONTROL_WC_FLUSH |
                           CMD_PIPE_CONTROL_TC_FLUSH |
                           CMD_PIPE_CONTROL_NOWRITE);
-            else
+            } else {
+                BEGIN_BATCH(batch, 4);
+                OUT_BATCH(batch, CMD_PIPE_CONTROL | (4 - 2));
+
                 OUT_BATCH(batch, 
                           CMD_PIPE_CONTROL_WC_FLUSH |
                           CMD_PIPE_CONTROL_TC_FLUSH |
                           CMD_PIPE_CONTROL_DC_FLUSH |
                           CMD_PIPE_CONTROL_NOWRITE);
+            }
 
-            OUT_BATCH(batch, 0);
-            OUT_BATCH(batch, 0);
+            OUT_BATCH(batch, 0); /* write address */
+            OUT_BATCH(batch, 0); /* write data */
             ADVANCE_BATCH(batch);
         } else {
             if (batch->flag == I915_EXEC_BLT) {
index 70ceddb..34ff66d 100644 (file)
@@ -24,6 +24,9 @@ struct intel_batchbuffer
     int (*run)(drm_intel_bo *bo, int used,
                drm_clip_rect_t *cliprects, int num_cliprects,
                int DR4, unsigned int ring_flag);
+
+    /* Used for Sandybdrige workaround */
+    dri_bo *wa_render_bo;
 };
 
 struct intel_batchbuffer *intel_batchbuffer_new(struct intel_driver_data *intel, int flag, int buffer_size);
index c36dbbe..8f44274 100644 (file)
@@ -45,6 +45,7 @@
 #define BR13_8888                               (0x3 << 24)
 
 #define CMD_PIPE_CONTROL                        (CMD_3D | (3 << 27) | (2 << 24) | (0 << 16))
+#define CMD_PIPE_CONTROL_CS_STALL               (1 << 20)
 #define CMD_PIPE_CONTROL_NOWRITE                (0 << 14)
 #define CMD_PIPE_CONTROL_WRITE_QWORD            (1 << 14)
 #define CMD_PIPE_CONTROL_WRITE_DEPTH            (2 << 14)
@@ -57,6 +58,7 @@
 #define CMD_PIPE_CONTROL_DC_FLUSH               (1 << 5)
 #define CMD_PIPE_CONTROL_GLOBAL_GTT             (1 << 2)
 #define CMD_PIPE_CONTROL_LOCAL_PGTT             (0 << 2)
+#define CMD_PIPE_CONTROL_STALL_AT_SCOREBOARD    (1 << 1)
 #define CMD_PIPE_CONTROL_DEPTH_CACHE_FLUSH      (1 << 0)