[Intel-gfx] [PATCH] enable blt acceleration on gen6
Zou Nan hai
nanhai.zou at intel.com
Wed Oct 27 08:47:32 CEST 2010
uxa: enable blt acceleration on gen6 hardware.
Signed-off-by: Zou Nan hai <nanhai.zou at intel.com>
---
src/i830_reg.h | 2 +
src/intel.h | 4 ++
src/intel_batchbuffer.c | 37 +++++++++++++++++-------
src/intel_batchbuffer.h | 10 ++++++-
src/intel_driver.c | 2 -
src/intel_uxa.c | 71 +++++++++++++++++++++++++---------------------
6 files changed, 80 insertions(+), 46 deletions(-)
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)) {
--
1.7.1
More information about the Intel-gfx
mailing list