From patchwork Wed Oct 27 06:47:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zou, Nanhai" X-Patchwork-Id: 284882 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9R6m9oB032683 for ; Wed, 27 Oct 2010 06:48:31 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9B4499E7DB for ; Tue, 26 Oct 2010 23:48:09 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by gabe.freedesktop.org (Postfix) with ESMTP id E78C69E77E for ; Tue, 26 Oct 2010 23:47:47 -0700 (PDT) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 26 Oct 2010 23:47:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.58,245,1286175600"; d="scan'208";a="340983041" Received: from linux-g45.sh.intel.com (HELO hdmi.sh.intel.com) ([10.239.13.57]) by azsmga001.ch.intel.com with ESMTP; 26 Oct 2010 23:47:46 -0700 From: Zou Nan hai To: intel-gfx@lists.freedesktop.org Date: Wed, 27 Oct 2010 14:47:32 +0800 Message-Id: <1288162052-9318-1-git-send-email-nanhai.zou@intel.com> X-Mailer: git-send-email 1.7.1 Subject: [Intel-gfx] [PATCH] enable blt acceleration on gen6 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 27 Oct 2010 06:48:31 +0000 (UTC) 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)) {