diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-10-09 18:43:14 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-10-10 20:45:14 +0200 |
commit | 383448b95531e40026151cc69317f1af4f260ff7 (patch) | |
tree | 8863e5c9dd76a09db347b08b56db8f90b4bfcd30 | |
parent | c5414ec992d935e10156a2b513d5ec2dded2f689 (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.h | 2 | ||||
-rw-r--r-- | src/intel.h | 1 | ||||
-rw-r--r-- | src/intel_batchbuffer.c | 50 | ||||
-rw-r--r-- | src/intel_driver.c | 8 |
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); } |