From 9eed6bea6b781d2df21720df440594dc87805e1d Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 3 Jan 2018 12:40:00 -0800 Subject: [PATCH] i965: Make intelEmitCopyBlit static MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit And rename to emit_copy_blit. v2: sed --in-place -e 's/color_logic_ops/gl_logicop_mode/g' $(grep -lr color_logic_ops src/) suggested by Brian. Signed-off-by: Ian Romanick Reviewed-by: Samuel Iglesias Gonsálvez [v1] --- src/mesa/drivers/dri/i965/intel_blit.c | 398 ++++++++++++------------- src/mesa/drivers/dri/i965/intel_blit.h | 16 - 2 files changed, 199 insertions(+), 215 deletions(-) diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 96e5aba85df..dcecab677e4 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -202,6 +202,183 @@ get_blit_intratile_offset_el(const struct brw_context *brw, } } +static bool +alignment_valid(struct brw_context *brw, unsigned offset, + enum isl_tiling tiling) +{ + const struct gen_device_info *devinfo = &brw->screen->devinfo; + + /* Tiled buffers must be page-aligned (4K). */ + if (tiling != ISL_TILING_LINEAR) + return (offset & 4095) == 0; + + /* On Gen8+, linear buffers must be cacheline-aligned. */ + if (devinfo->gen >= 8) + return (offset & 63) == 0; + + return true; +} + +static uint32_t +xy_blit_cmd(enum isl_tiling src_tiling, enum isl_tiling dst_tiling, + uint32_t cpp) +{ + uint32_t CMD = 0; + + assert(cpp <= 4); + switch (cpp) { + case 1: + case 2: + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; + break; + default: + unreachable("not reached"); + } + + if (dst_tiling != ISL_TILING_LINEAR) + CMD |= XY_DST_TILED; + + if (src_tiling != ISL_TILING_LINEAR) + CMD |= XY_SRC_TILED; + + return CMD; +} + +/* Copy BitBlt + */ +static bool +emit_copy_blit(struct brw_context *brw, + GLuint cpp, + int32_t src_pitch, + struct brw_bo *src_buffer, + GLuint src_offset, + enum isl_tiling src_tiling, + int32_t dst_pitch, + struct brw_bo *dst_buffer, + GLuint dst_offset, + enum isl_tiling dst_tiling, + GLshort src_x, GLshort src_y, + GLshort dst_x, GLshort dst_y, + GLshort w, GLshort h, + enum gl_logicop_mode logic_op) +{ + const struct gen_device_info *devinfo = &brw->screen->devinfo; + GLuint CMD, BR13; + int dst_y2 = dst_y + h; + int dst_x2 = dst_x + w; + bool dst_y_tiled = dst_tiling == ISL_TILING_Y0; + bool src_y_tiled = src_tiling == ISL_TILING_Y0; + uint32_t src_tile_w, src_tile_h; + uint32_t dst_tile_w, dst_tile_h; + + if ((dst_y_tiled || src_y_tiled) && devinfo->gen < 6) + return false; + + const unsigned bo_sizes = dst_buffer->size + src_buffer->size; + + /* do space check before going any further */ + if (!brw_batch_has_aperture_space(brw, bo_sizes)) + intel_batchbuffer_flush(brw); + + if (!brw_batch_has_aperture_space(brw, bo_sizes)) + return false; + + unsigned length = devinfo->gen >= 8 ? 10 : 8; + + intel_batchbuffer_require_space(brw, length * 4, BLT_RING); + DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __func__, + src_buffer, src_pitch, src_offset, src_x, src_y, + dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); + + intel_get_tile_dims(src_tiling, cpp, &src_tile_w, &src_tile_h); + intel_get_tile_dims(dst_tiling, cpp, &dst_tile_w, &dst_tile_h); + + /* For Tiled surfaces, the pitch has to be a multiple of the Tile width + * (X direction width of the Tile). This is ensured while allocating the + * buffer object. + */ + assert(src_tiling == ISL_TILING_LINEAR || (src_pitch % src_tile_w) == 0); + assert(dst_tiling == ISL_TILING_LINEAR || (dst_pitch % dst_tile_w) == 0); + + /* For big formats (such as floating point), do the copy using 16 or + * 32bpp and multiply the coordinates. + */ + if (cpp > 4) { + if (cpp % 4 == 2) { + dst_x *= cpp / 2; + dst_x2 *= cpp / 2; + src_x *= cpp / 2; + cpp = 2; + } else { + assert(cpp % 4 == 0); + dst_x *= cpp / 4; + dst_x2 *= cpp / 4; + src_x *= cpp / 4; + cpp = 4; + } + } + + if (!alignment_valid(brw, dst_offset, dst_tiling)) + return false; + if (!alignment_valid(brw, src_offset, src_tiling)) + return false; + + /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop + * the low bits. Offsets must be naturally aligned. + */ + if (src_pitch % 4 != 0 || src_offset % cpp != 0 || + dst_pitch % 4 != 0 || dst_offset % cpp != 0) + return false; + + assert(cpp <= 4); + BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16; + + CMD = xy_blit_cmd(src_tiling, dst_tiling, cpp); + + /* For tiled source and destination, pitch value should be specified + * as a number of Dwords. + */ + if (dst_tiling != ISL_TILING_LINEAR) + dst_pitch /= 4; + + if (src_tiling != ISL_TILING_LINEAR) + src_pitch /= 4; + + if (dst_y2 <= dst_y || dst_x2 <= dst_x) + return true; + + assert(dst_x < dst_x2); + assert(dst_y < dst_y2); + + BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, src_y_tiled); + OUT_BATCH(CMD | (length - 2)); + OUT_BATCH(BR13 | (uint16_t)dst_pitch); + OUT_BATCH(SET_FIELD(dst_y, BLT_Y) | SET_FIELD(dst_x, BLT_X)); + OUT_BATCH(SET_FIELD(dst_y2, BLT_Y) | SET_FIELD(dst_x2, BLT_X)); + if (devinfo->gen >= 8) { + OUT_RELOC64(dst_buffer, RELOC_WRITE, dst_offset); + } else { + OUT_RELOC(dst_buffer, RELOC_WRITE, dst_offset); + } + OUT_BATCH(SET_FIELD(src_y, BLT_Y) | SET_FIELD(src_x, BLT_X)); + OUT_BATCH((uint16_t)src_pitch); + if (devinfo->gen >= 8) { + OUT_RELOC64(src_buffer, 0, src_offset); + } else { + OUT_RELOC(src_buffer, 0, src_offset); + } + + ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled); + + brw_emit_mi_flush(brw); + + return true; +} + static bool emit_miptree_blit(struct brw_context *brw, struct intel_mipmap_tree *src_mt, @@ -254,19 +431,19 @@ emit_miptree_blit(struct brw_context *brw, dst_x + chunk_x, dst_y + chunk_y, &dst_offset, &dst_tile_x, &dst_tile_y); - if (!intelEmitCopyBlit(brw, - src_mt->cpp, - reverse ? -src_mt->surf.row_pitch : - src_mt->surf.row_pitch, - src_mt->bo, src_mt->offset + src_offset, - src_mt->surf.tiling, - dst_mt->surf.row_pitch, - dst_mt->bo, dst_mt->offset + dst_offset, - dst_mt->surf.tiling, - src_tile_x, src_tile_y, - dst_tile_x, dst_tile_y, - chunk_w, chunk_h, - logicop)) { + if (!emit_copy_blit(brw, + src_mt->cpp, + reverse ? -src_mt->surf.row_pitch : + src_mt->surf.row_pitch, + src_mt->bo, src_mt->offset + src_offset, + src_mt->surf.tiling, + dst_mt->surf.row_pitch, + dst_mt->bo, dst_mt->offset + dst_offset, + dst_mt->surf.tiling, + src_tile_x, src_tile_y, + dst_tile_x, dst_tile_y, + chunk_w, chunk_h, + logicop)) { /* If this is ever going to fail, it will fail on the first chunk */ assert(chunk_x == 0 && chunk_y == 0); return false; @@ -448,183 +625,6 @@ intel_miptree_copy(struct brw_context *brw, src_width, src_height, false, COLOR_LOGICOP_COPY); } -static bool -alignment_valid(struct brw_context *brw, unsigned offset, - enum isl_tiling tiling) -{ - const struct gen_device_info *devinfo = &brw->screen->devinfo; - - /* Tiled buffers must be page-aligned (4K). */ - if (tiling != ISL_TILING_LINEAR) - return (offset & 4095) == 0; - - /* On Gen8+, linear buffers must be cacheline-aligned. */ - if (devinfo->gen >= 8) - return (offset & 63) == 0; - - return true; -} - -static uint32_t -xy_blit_cmd(enum isl_tiling src_tiling, enum isl_tiling dst_tiling, - uint32_t cpp) -{ - uint32_t CMD = 0; - - assert(cpp <= 4); - switch (cpp) { - case 1: - case 2: - CMD = XY_SRC_COPY_BLT_CMD; - break; - case 4: - CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; - break; - default: - unreachable("not reached"); - } - - if (dst_tiling != ISL_TILING_LINEAR) - CMD |= XY_DST_TILED; - - if (src_tiling != ISL_TILING_LINEAR) - CMD |= XY_SRC_TILED; - - return CMD; -} - -/* Copy BitBlt - */ -bool -intelEmitCopyBlit(struct brw_context *brw, - GLuint cpp, - int32_t src_pitch, - struct brw_bo *src_buffer, - GLuint src_offset, - enum isl_tiling src_tiling, - int32_t dst_pitch, - struct brw_bo *dst_buffer, - GLuint dst_offset, - enum isl_tiling dst_tiling, - GLshort src_x, GLshort src_y, - GLshort dst_x, GLshort dst_y, - GLshort w, GLshort h, - enum gl_logicop_mode logic_op) -{ - const struct gen_device_info *devinfo = &brw->screen->devinfo; - GLuint CMD, BR13; - int dst_y2 = dst_y + h; - int dst_x2 = dst_x + w; - bool dst_y_tiled = dst_tiling == ISL_TILING_Y0; - bool src_y_tiled = src_tiling == ISL_TILING_Y0; - uint32_t src_tile_w, src_tile_h; - uint32_t dst_tile_w, dst_tile_h; - - if ((dst_y_tiled || src_y_tiled) && devinfo->gen < 6) - return false; - - const unsigned bo_sizes = dst_buffer->size + src_buffer->size; - - /* do space check before going any further */ - if (!brw_batch_has_aperture_space(brw, bo_sizes)) - intel_batchbuffer_flush(brw); - - if (!brw_batch_has_aperture_space(brw, bo_sizes)) - return false; - - unsigned length = devinfo->gen >= 8 ? 10 : 8; - - intel_batchbuffer_require_space(brw, length * 4, BLT_RING); - DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", - __func__, - src_buffer, src_pitch, src_offset, src_x, src_y, - dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); - - intel_get_tile_dims(src_tiling, cpp, &src_tile_w, &src_tile_h); - intel_get_tile_dims(dst_tiling, cpp, &dst_tile_w, &dst_tile_h); - - /* For Tiled surfaces, the pitch has to be a multiple of the Tile width - * (X direction width of the Tile). This is ensured while allocating the - * buffer object. - */ - assert(src_tiling == ISL_TILING_LINEAR || (src_pitch % src_tile_w) == 0); - assert(dst_tiling == ISL_TILING_LINEAR || (dst_pitch % dst_tile_w) == 0); - - /* For big formats (such as floating point), do the copy using 16 or - * 32bpp and multiply the coordinates. - */ - if (cpp > 4) { - if (cpp % 4 == 2) { - dst_x *= cpp / 2; - dst_x2 *= cpp / 2; - src_x *= cpp / 2; - cpp = 2; - } else { - assert(cpp % 4 == 0); - dst_x *= cpp / 4; - dst_x2 *= cpp / 4; - src_x *= cpp / 4; - cpp = 4; - } - } - - if (!alignment_valid(brw, dst_offset, dst_tiling)) - return false; - if (!alignment_valid(brw, src_offset, src_tiling)) - return false; - - /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop - * the low bits. Offsets must be naturally aligned. - */ - if (src_pitch % 4 != 0 || src_offset % cpp != 0 || - dst_pitch % 4 != 0 || dst_offset % cpp != 0) - return false; - - assert(cpp <= 4); - BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16; - - CMD = xy_blit_cmd(src_tiling, dst_tiling, cpp); - - /* For tiled source and destination, pitch value should be specified - * as a number of Dwords. - */ - if (dst_tiling != ISL_TILING_LINEAR) - dst_pitch /= 4; - - if (src_tiling != ISL_TILING_LINEAR) - src_pitch /= 4; - - if (dst_y2 <= dst_y || dst_x2 <= dst_x) - return true; - - assert(dst_x < dst_x2); - assert(dst_y < dst_y2); - - BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, src_y_tiled); - OUT_BATCH(CMD | (length - 2)); - OUT_BATCH(BR13 | (uint16_t)dst_pitch); - OUT_BATCH(SET_FIELD(dst_y, BLT_Y) | SET_FIELD(dst_x, BLT_X)); - OUT_BATCH(SET_FIELD(dst_y2, BLT_Y) | SET_FIELD(dst_x2, BLT_X)); - if (devinfo->gen >= 8) { - OUT_RELOC64(dst_buffer, RELOC_WRITE, dst_offset); - } else { - OUT_RELOC(dst_buffer, RELOC_WRITE, dst_offset); - } - OUT_BATCH(SET_FIELD(src_y, BLT_Y) | SET_FIELD(src_x, BLT_X)); - OUT_BATCH((uint16_t)src_pitch); - if (devinfo->gen >= 8) { - OUT_RELOC64(src_buffer, 0, src_offset); - } else { - OUT_RELOC(src_buffer, 0, src_offset); - } - - ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled); - - brw_emit_mi_flush(brw); - - return true; -} - bool intelEmitImmediateColorExpandBlit(struct brw_context *brw, GLuint cpp, @@ -737,15 +737,15 @@ intel_emit_linear_blit(struct brw_context *brw, assert(src_x + pitch < 1 << 15); assert(dst_x + pitch < 1 << 15); - ok = intelEmitCopyBlit(brw, 1, - pitch, src_bo, src_offset - src_x, - ISL_TILING_LINEAR, - pitch, dst_bo, dst_offset - dst_x, - ISL_TILING_LINEAR, - src_x, 0, /* src x/y */ - dst_x, 0, /* dst x/y */ - MIN2(size, pitch), height, /* w, h */ - COLOR_LOGICOP_COPY); + ok = emit_copy_blit(brw, 1, + pitch, src_bo, src_offset - src_x, + ISL_TILING_LINEAR, + pitch, dst_bo, dst_offset - dst_x, + ISL_TILING_LINEAR, + src_x, 0, /* src x/y */ + dst_x, 0, /* dst x/y */ + MIN2(size, pitch), height, /* w, h */ + COLOR_LOGICOP_COPY); if (!ok) { _mesa_problem(ctx, "Failed to linear blit %dx%d\n", MIN2(size, pitch), height); diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index ce36b2609b0..f3ca7b0182d 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -28,22 +28,6 @@ #include "brw_context.h" -bool -intelEmitCopyBlit(struct brw_context *brw, - GLuint cpp, - int32_t src_pitch, - struct brw_bo *src_buffer, - GLuint src_offset, - enum isl_tiling src_tiling, - int32_t dst_pitch, - struct brw_bo *dst_buffer, - GLuint dst_offset, - enum isl_tiling dst_tiling, - GLshort srcx, GLshort srcy, - GLshort dstx, GLshort dsty, - GLshort w, GLshort h, - enum gl_logicop_mode logicop); - bool intel_miptree_blit_compatible_formats(mesa_format src, mesa_format dst); bool intel_miptree_blit(struct brw_context *brw, -- 2.30.2