diff mbox

enable blt acceleration on gen6

Message ID 1288162052-9318-1-git-send-email-nanhai.zou@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zou, Nanhai Oct. 27, 2010, 6:47 a.m. UTC
None
diff mbox

Patch

diff --git a/src/i830_reg.h b/src/i830_reg.h
index 4080896..93d03cf 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -32,6 +32,8 @@ 
 
 /* Flush */
 #define MI_FLUSH			(0x04<<23)
+#define MI_FLUSH_DW			(0x26<<23)
+
 #define MI_WRITE_DIRTY_STATE		(1<<4)
 #define MI_END_SCENE			(1<<3)
 #define MI_GLOBAL_SNAPSHOT_COUNT_RESET	(1<<3)
diff --git a/src/intel.h b/src/intel.h
index 7604eee..89a5545 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -289,6 +289,10 @@  typedef struct intel_screen_private {
 	unsigned char *MMIOBase;
 	int cpp;
 
+#define RENDER_BATCH			0
+#define BLT_BATCH			1	
+	unsigned int current_batch;
+
 	unsigned int bufferOffset;	/* for I830SelectBuffer */
 
 	/* These are set in PreInit and never changed. */
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index e7ca69d..2d269d3 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -147,14 +147,22 @@  void intel_batch_emit_flush(ScrnInfoPtr scrn)
 	assert (!intel->in_batch_atomic);
 
 	/* Big hammer, look to the pipelined flushes in future. */
-	flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
-	if (INTEL_INFO(intel)->gen >= 40)
-		flags = 0;
-
-	BEGIN_BATCH(1);
-	OUT_BATCH(MI_FLUSH | flags);
-	ADVANCE_BATCH();
-
+	if (intel->current_batch == BLT_BATCH) {
+		BEGIN_BATCH_BLT(4);
+		OUT_BATCH(MI_FLUSH_DW | 2);
+		OUT_BATCH(0);
+		OUT_BATCH(0);
+		OUT_BATCH(0);
+		ADVANCE_BATCH();
+	} else {
+		flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
+		if (INTEL_INFO(intel)->gen >= 40)
+			flags = 0;
+
+		BEGIN_BATCH(1);
+		OUT_BATCH(MI_FLUSH | flags);
+		ADVANCE_BATCH();
+	}
 	intel_batch_do_flush(scrn);
 }
 
@@ -190,9 +198,16 @@  void intel_batch_submit(ScrnInfoPtr scrn, int flush)
 	}
 
 	ret = dri_bo_subdata(intel->batch_bo, 0, intel->batch_used*4, intel->batch_ptr);
-	if (ret == 0)
-		ret = dri_bo_exec(intel->batch_bo, intel->batch_used*4,
-				  NULL, 0, 0xffffffff);
+	if (ret == 0) {
+		if (intel->current_batch == RENDER_BATCH)
+			ret = dri_bo_exec(intel->batch_bo, intel->batch_used*4,
+					NULL, 0, 0xffffffff);
+		else
+			ret = drm_intel_bo_mrb_exec(intel->batch_bo, 
+					intel->batch_used*4,
+					NULL, 0, 0xffffffff, I915_EXEC_BLIT);
+	}
+
 	if (ret != 0) {
 		if (ret == -EIO) {
 			static int once;
diff --git a/src/intel_batchbuffer.h b/src/intel_batchbuffer.h
index bf7a5d9..607fb9b 100644
--- a/src/intel_batchbuffer.h
+++ b/src/intel_batchbuffer.h
@@ -63,7 +63,9 @@  static inline void intel_batch_start_atomic(ScrnInfoPtr scrn, unsigned int sz)
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 
 	assert(!intel->in_batch_atomic);
+
 	intel_batch_require_space(scrn, intel, sz * 4);
+	intel->current_batch = RENDER_BATCH;				\
 
 	intel->in_batch_atomic = TRUE;
 	intel->batch_atomic_limit = intel->batch_used + sz;
@@ -173,17 +175,23 @@  union intfloat {
 	OUT_BATCH(tmp.ui);			\
 } while(0)
 
-#define BEGIN_BATCH(n)							\
+#define __BEGIN_BATCH(n,batch_idx)					\
 do {									\
 	if (intel->batch_emitting != 0)					\
 		FatalError("%s: BEGIN_BATCH called without closing "	\
 			   "ADVANCE_BATCH\n", __FUNCTION__);		\
 	assert(!intel->in_batch_atomic);				\
+	if (intel->current_batch != batch_idx)				\
+		intel_batch_submit(scrn, TRUE);				\
 	intel_batch_require_space(scrn, intel, (n) * 4);		\
+	intel->current_batch = batch_idx;				\
 	intel->batch_emitting = (n);					\
 	intel->batch_emit_start = intel->batch_used;			\
 } while (0)
 
+#define BEGIN_BATCH(n) 	__BEGIN_BATCH(n,RENDER_BATCH)
+#define BEGIN_BATCH_BLT(n) 	__BEGIN_BATCH(n,BLT_BATCH)
+
 #define ADVANCE_BATCH() do {						\
 	if (intel->batch_emitting == 0)					\
 		FatalError("%s: ADVANCE_BATCH called with no matching "	\
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 7e4a4a4..01c8c1b 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -575,8 +575,6 @@  static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 	}
 
 	intel->use_shadow = FALSE;
-	if (IS_GEN6(intel))
-		intel->use_shadow = TRUE;
 
 	if (xf86IsOptionSet(intel->Options, OPTION_SHADOW)) {
 		intel->use_shadow =
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 14c47a0..48391ca 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -85,6 +85,19 @@  int uxa_pixmap_index;
 #endif
 
 static void
+snb_blt_workaround(ScrnInfoPtr scrn)
+{
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	int i;
+	if (IS_GEN6(intel)) {
+		BEGIN_BATCH_BLT(32);
+		for (i = 0; i < 32; i++)
+			OUT_BATCH(MI_NOOP);
+		ADVANCE_BATCH();
+	}
+}
+
+static void
 ironlake_blt_workaround(ScrnInfoPtr scrn)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -208,16 +221,9 @@  intel_uxa_pixmap_compute_size(PixmapPtr pixmap,
 }
 
 static Bool
-i830_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
+intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
 {
 	ScrnInfoPtr scrn = xf86Screens[drawable->pScreen->myNum];
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-
-	if (IS_GEN6(intel)) {
-		intel_debug_fallback(scrn,
-				     "Sandybridge BLT engine not supported\n");
-		return FALSE;
-	}
 
 	if (!UXA_PM_IS_SOLID(drawable, planemask)) {
 		intel_debug_fallback(scrn, "planemask is not solid\n");
@@ -240,7 +246,7 @@  i830_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
  * Sets up hardware state for a series of solid fills.
  */
 static Bool
-i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
+intel_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
 {
 	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
 	intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -273,7 +279,7 @@  i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
 	return TRUE;
 }
 
-static void i830_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2)
+static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2)
 {
 	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
 	intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -295,7 +301,10 @@  static void i830_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2)
 	pitch = intel_pixmap_pitch(pixmap);
 
 	{
-		BEGIN_BATCH(6);
+		if (IS_GEN6(intel))
+			BEGIN_BATCH_BLT(6);
+		else
+			BEGIN_BATCH(6);
 
 		cmd = XY_COLOR_BLT_CMD;
 
@@ -323,11 +332,12 @@  static void i830_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2)
 	ironlake_blt_workaround(scrn);
 }
 
-static void i830_uxa_done_solid(PixmapPtr pixmap)
+static void intel_uxa_done_solid(PixmapPtr pixmap)
 {
 	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
 
 	intel_debug_flush(scrn);
+	snb_blt_workaround(scrn);
 }
 
 /**
@@ -335,17 +345,10 @@  static void i830_uxa_done_solid(PixmapPtr pixmap)
  *   - support planemask using FULL_BLT_CMD?
  */
 static Bool
-i830_uxa_check_copy(PixmapPtr source, PixmapPtr dest,
+intel_uxa_check_copy(PixmapPtr source, PixmapPtr dest,
 		    int alu, Pixel planemask)
 {
 	ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-
-	if (IS_GEN6(intel)) {
-		intel_debug_fallback(scrn,
-				     "Sandybridge BLT engine not supported\n");
-		return FALSE;
-	}
 
 	if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) {
 		intel_debug_fallback(scrn, "planemask is not solid");
@@ -374,7 +377,7 @@  i830_uxa_check_copy(PixmapPtr source, PixmapPtr dest,
 }
 
 static Bool
-i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir,
+intel_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir,
 		      int ydir, int alu, Pixel planemask)
 {
 	ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
@@ -406,7 +409,7 @@  i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir,
 }
 
 static void
-i830_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1,
+intel_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1,
 	      int dst_y1, int w, int h)
 {
 	ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
@@ -449,7 +452,10 @@  i830_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1,
 	src_pitch = intel_pixmap_pitch(intel->render_source);
 
 	{
-		BEGIN_BATCH(8);
+		if (IS_GEN6(intel))
+			BEGIN_BATCH_BLT(8);
+		else
+			BEGIN_BATCH(8);
 
 		cmd = XY_SRC_COPY_BLT_CMD;
 
@@ -492,11 +498,12 @@  i830_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1,
 	ironlake_blt_workaround(scrn);
 }
 
-static void i830_uxa_done_copy(PixmapPtr dest)
+static void intel_uxa_done_copy(PixmapPtr dest)
 {
 	ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
 
 	intel_debug_flush(scrn);
+	snb_blt_workaround(scrn);
 }
 
 /**
@@ -1187,16 +1194,16 @@  Bool intel_uxa_init(ScreenPtr screen)
 	intel->vertex_bo = NULL;
 
 	/* Solid fill */
-	intel->uxa_driver->check_solid = i830_uxa_check_solid;
-	intel->uxa_driver->prepare_solid = i830_uxa_prepare_solid;
-	intel->uxa_driver->solid = i830_uxa_solid;
-	intel->uxa_driver->done_solid = i830_uxa_done_solid;
+	intel->uxa_driver->check_solid = intel_uxa_check_solid;
+	intel->uxa_driver->prepare_solid = intel_uxa_prepare_solid;
+	intel->uxa_driver->solid = intel_uxa_solid;
+	intel->uxa_driver->done_solid = intel_uxa_done_solid;
 
 	/* Copy */
-	intel->uxa_driver->check_copy = i830_uxa_check_copy;
-	intel->uxa_driver->prepare_copy = i830_uxa_prepare_copy;
-	intel->uxa_driver->copy = i830_uxa_copy;
-	intel->uxa_driver->done_copy = i830_uxa_done_copy;
+	intel->uxa_driver->check_copy = intel_uxa_check_copy;
+	intel->uxa_driver->prepare_copy = intel_uxa_prepare_copy;
+	intel->uxa_driver->copy = intel_uxa_copy;
+	intel->uxa_driver->done_copy = intel_uxa_done_copy;
 
 	/* Composite */
 	if (IS_GEN2(intel)) {