From d641a01d981f7de600ea50fa53c85e34fc2e3174 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 May 2013 14:12:56 -0700 Subject: [PATCH] i965: Add support for Y-tiled blits on gen6+. Reviewed-by: Kenneth Graunke Reviewed-by: Ian Romanick --- src/mesa/drivers/dri/intel/intel_blit.c | 39 +++++++++++++++++++++++-- src/mesa/drivers/dri/intel/intel_reg.h | 6 ++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 1f3fad51266..63378b6740a 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -107,18 +107,19 @@ intelEmitCopyBlit(struct intel_context *intel, int dst_y2 = dst_y + h; int dst_x2 = dst_x + w; drm_intel_bo *aper_array[3]; + uint32_t bcs_swctrl = 0; BATCH_LOCALS; if (dst_tiling != I915_TILING_NONE) { if (dst_offset & 4095) return false; - if (dst_tiling == I915_TILING_Y) + if (dst_tiling == I915_TILING_Y && intel->gen < 6) return false; } if (src_tiling != I915_TILING_NONE) { if (src_offset & 4095) return false; - if (src_tiling == I915_TILING_Y) + if (src_tiling == I915_TILING_Y && intel->gen < 6) return false; } @@ -179,10 +180,16 @@ intelEmitCopyBlit(struct intel_context *intel, if (dst_tiling != I915_TILING_NONE) { CMD |= XY_DST_TILED; dst_pitch /= 4; + + if (dst_tiling == I915_TILING_Y) + bcs_swctrl |= BCS_SWCTRL_DST_Y; } if (src_tiling != I915_TILING_NONE) { CMD |= XY_SRC_TILED; src_pitch /= 4; + + if (src_tiling == I915_TILING_Y) + bcs_swctrl |= BCS_SWCTRL_SRC_Y; } #endif @@ -193,7 +200,21 @@ intelEmitCopyBlit(struct intel_context *intel, assert(dst_x < dst_x2); assert(dst_y < dst_y2); - BEGIN_BATCH_BLT(8); + BEGIN_BATCH_BLT(8 + ((bcs_swctrl != 0) ? 14 : 0)); + + if (bcs_swctrl != 0) { + /* Idle the blitter before we update how tiling is interpreted. */ + OUT_BATCH(MI_FLUSH_DW); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + + OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2)); + OUT_BATCH(BCS_SWCTRL); + OUT_BATCH((BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y) << 16 | + bcs_swctrl); + } + OUT_BATCH(CMD | (8 - 2)); OUT_BATCH(BR13 | (uint16_t)dst_pitch); OUT_BATCH((dst_y << 16) | dst_x); @@ -206,6 +227,18 @@ intelEmitCopyBlit(struct intel_context *intel, OUT_RELOC_FENCED(src_buffer, I915_GEM_DOMAIN_RENDER, 0, src_offset); + + if (bcs_swctrl != 0) { + OUT_BATCH(MI_FLUSH_DW); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + + OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2)); + OUT_BATCH(BCS_SWCTRL); + OUT_BATCH((BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y) << 16); + } + ADVANCE_BATCH(); intel_batchbuffer_emit_mi_flush(intel); diff --git a/src/mesa/drivers/dri/intel/intel_reg.h b/src/mesa/drivers/dri/intel/intel_reg.h index e4871ebf9e7..acbbcfb93e0 100644 --- a/src/mesa/drivers/dri/intel/intel_reg.h +++ b/src/mesa/drivers/dri/intel/intel_reg.h @@ -37,6 +37,8 @@ #define FLUSH_MAP_CACHE (1 << 0) #define INHIBIT_FLUSH_RENDER_CACHE (1 << 2) +#define MI_LOAD_REGISTER_IMM (CMD_MI | (0x22 << 23)) + #define MI_FLUSH_DW (CMD_MI | (0x26 << 23) | 2) /* Stalls command execution waiting for the given events to have occurred. */ @@ -277,3 +279,7 @@ #define SO_NUM_PRIMS_WRITTEN3_IVB 0x5218 #define TIMESTAMP 0x2358 + +#define BCS_SWCTRL 0x22200 +# define BCS_SWCTRL_SRC_Y (1 << 0) +# define BCS_SWCTRL_DST_Y (1 << 1) -- 2.30.2