summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2011-10-09 18:43:14 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2011-10-10 20:45:14 +0200
commit383448b95531e40026151cc69317f1af4f260ff7 (patch)
tree8863e5c9dd76a09db347b08b56db8f90b4bfcd30
parentc5414ec992d935e10156a2b513d5ec2dded2f689 (diff)
snb: implement PIPE_CONTROL workaroundgen6_pc
Sandybdrige requires an elaborate dance to flush caches without hanging the gpu. See public docs Vol2Part1 1.7.4.1 PIPE_CONTROL or the corrensponding code in mesa/kernel. v2: Incorporate review from Chris Wilson. For paranoia keep all three PIPE_CONTROL cmds in the same batchbuffer to avoid upsetting the gpu. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--src/i965_reg.h2
-rw-r--r--src/intel.h1
-rw-r--r--src/intel_batchbuffer.c50
-rw-r--r--src/intel_driver.c8
4 files changed, 53 insertions, 8 deletions
diff --git a/src/i965_reg.h b/src/i965_reg.h
index 904e506f..e7b0d15d 100644
--- a/src/i965_reg.h
+++ b/src/i965_reg.h
@@ -294,6 +294,7 @@
#define BRW_CLIP_ENABLE 1
/* for BRW_PIPE_CONTROL */
+#define BRW_PIPE_CONTROL_CS_STALL (1 << 20)
#define BRW_PIPE_CONTROL_NOWRITE (0 << 14)
#define BRW_PIPE_CONTROL_WRITE_QWORD (1 << 14)
#define BRW_PIPE_CONTROL_WRITE_DEPTH (2 << 14)
@@ -305,6 +306,7 @@
#define BRW_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8)
#define BRW_PIPE_CONTROL_GLOBAL_GTT (1 << 2)
#define BRW_PIPE_CONTROL_LOCAL_PGTT (0 << 2)
+#define BRW_PIPE_CONTROL_STALL_AT_SCOREBOARD (1 << 1)
#define BRW_PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0)
/* VERTEX_BUFFER_STATE Structure */
diff --git a/src/intel.h b/src/intel.h
index 899d2502..2338e65c 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -283,6 +283,7 @@ typedef struct intel_screen_private {
struct list batch_pixmaps;
struct list flush_pixmaps;
struct list in_flight;
+ dri_bo *wa_scratch_bo;
/* For Xvideo */
Bool use_overlay;
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index d0a41aa3..89a99692 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -137,6 +137,35 @@ void intel_batch_do_flush(ScrnInfoPtr scrn)
list_del(intel->flush_pixmaps.next);
}
+static void intel_emit_post_sync_nonzero_flush(ScrnInfoPtr scrn)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+
+ /* keep this entire sequence of 3 PIPE_CONTROL cmds in one batch to
+ * avoid upsetting the gpu. */
+ BEGIN_BATCH(3*4);
+ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2));
+ OUT_BATCH(BRW_PIPE_CONTROL_CS_STALL |
+ BRW_PIPE_CONTROL_STALL_AT_SCOREBOARD);
+ OUT_BATCH(0); /* address */
+ OUT_BATCH(0); /* write data */
+
+ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2));
+ OUT_BATCH(BRW_PIPE_CONTROL_WRITE_QWORD);
+ OUT_RELOC(intel->wa_scratch_bo,
+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 0);
+ OUT_BATCH(0); /* write data */
+
+ /* now finally the _real flush */
+ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2));
+ OUT_BATCH(BRW_PIPE_CONTROL_WC_FLUSH |
+ BRW_PIPE_CONTROL_TC_FLUSH |
+ BRW_PIPE_CONTROL_NOWRITE);
+ OUT_BATCH(0); /* write address */
+ OUT_BATCH(0); /* write data */
+ ADVANCE_BATCH();
+}
+
void intel_batch_emit_flush(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -154,14 +183,19 @@ void intel_batch_emit_flush(ScrnInfoPtr scrn)
OUT_BATCH(0);
ADVANCE_BATCH();
} else {
- BEGIN_BATCH(4);
- OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2));
- OUT_BATCH(BRW_PIPE_CONTROL_WC_FLUSH |
- BRW_PIPE_CONTROL_TC_FLUSH |
- BRW_PIPE_CONTROL_NOWRITE);
- OUT_BATCH(0); /* write address */
- OUT_BATCH(0); /* write data */
- ADVANCE_BATCH();
+ if ((INTEL_INFO(intel)->gen == 60)) {
+ /* HW-Workaround for Sandybdrige */
+ intel_emit_post_sync_nonzero_flush(scrn);
+ } else {
+ BEGIN_BATCH(4);
+ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2));
+ OUT_BATCH(BRW_PIPE_CONTROL_WC_FLUSH |
+ BRW_PIPE_CONTROL_TC_FLUSH |
+ BRW_PIPE_CONTROL_NOWRITE);
+ OUT_BATCH(0); /* write address */
+ OUT_BATCH(0); /* write data */
+ ADVANCE_BATCH();
+ }
}
} else {
flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 7fc1c1a3..dcb02de9 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -416,11 +416,19 @@ static int intel_init_bufmgr(intel_screen_private *intel)
list_init(&intel->flush_pixmaps);
list_init(&intel->in_flight);
+ if ((INTEL_INFO(intel)->gen == 60)) {
+ intel->wa_scratch_bo =
+ dri_bo_alloc(intel->bufmgr, "wa scratch", 4096, 4096);
+ }
+
return TRUE;
}
static void intel_bufmgr_fini(intel_screen_private *intel)
{
+ if (intel->wa_scratch_bo)
+ dri_bo_unreference(intel->wa_scratch_bo);
+
drm_intel_bufmgr_destroy(intel->bufmgr);
}