xf86-video-intel: src/i965_reg.h src/intel.h src/intel_batchbuffer.c src/intel_driver.c
Daniel Vetter
danvet at kemper.freedesktop.org
Tue Oct 11 01:55:43 PDT 2011
src/i965_reg.h | 2 +
src/intel.h | 1
src/intel_batchbuffer.c | 50 ++++++++++++++++++++++++++++++++++++++++--------
src/intel_driver.c | 7 ++++++
4 files changed, 52 insertions(+), 8 deletions(-)
New commits:
commit d0184b59095d5b8fab1a65ceba075d29189130d4
Author: Daniel Vetter <daniel.vetter at ffwll.ch>
Date: Sun Oct 9 18:43:14 2011 +0200
snb: implement PIPE_CONTROL workaround
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.
This (together with the corresponding patch for the kernel) seems to
fix the hangs in cairo-perf-traces I'm seeing on my snb machine.
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 at ffwll.ch>
diff --git a/src/i965_reg.h b/src/i965_reg.h
index 904e506..e7b0d15 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 899d250..2f72830 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;
+ drm_intel_bo *wa_scratch_bo;
/* For Xvideo */
Bool use_overlay;
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index d0a41aa..89a9969 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 7fc1c1a..24696da 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -416,11 +416,18 @@ 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 =
+ drm_intel_bo_alloc(intel->bufmgr, "wa scratch",
+ 4096, 4096);
+ }
+
return TRUE;
}
static void intel_bufmgr_fini(intel_screen_private *intel)
{
+ drm_intel_bo_unreference(intel->wa_scratch_bo);
drm_intel_bufmgr_destroy(intel->bufmgr);
}
More information about the xorg-commit
mailing list