Signed-off-by: Jason Ekstrand <ja...@jlekstrand.net> --- src/mesa/drivers/dri/i965/intel_blit.c | 56 +++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 15 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 95d00d3..78c4578 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -839,22 +839,48 @@ intel_miptree_set_alpha_to_one(struct brw_context *brw, unsigned length = brw->gen >= 8 ? 7 : 6; bool dst_y_tiled = mt->tiling == I915_TILING_Y; - BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, false); - OUT_BATCH(CMD | (length - 2)); - OUT_BATCH(BR13); - OUT_BATCH(SET_FIELD(y, BLT_Y) | SET_FIELD(x, BLT_X)); - OUT_BATCH(SET_FIELD(y + height, BLT_Y) | SET_FIELD(x + width, BLT_X)); - if (brw->gen >= 8) { - OUT_RELOC64(mt->bo, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); - } else { - OUT_RELOC(mt->bo, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); + const enum isl_tiling tiling = intel_miptree_get_isl_tiling(mt); + + /* We need to split the blit into chunks that each fit within the blitter's + * restrictions. We can't use a chunk size of 32768 because wee need to + * ensure that src_tile_x + chunk_size fits. We choose 16384 because it's + * a nice round power of two, big enough that performance won't suffer, and + * small enough to guarantee everything fits. + */ + const uint32_t max_chunk_size = 16384; + + for (uint32_t chunk_x = 0; chunk_x < width; chunk_x += max_chunk_size) { + for (uint32_t chunk_y = 0; chunk_y < height; chunk_y += max_chunk_size) { + const uint32_t chunk_w = MIN2(max_chunk_size, width - chunk_x); + const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y); + + uint32_t offset, tile_x, tile_y; + isl_tiling_get_intratile_offset_el(&brw->isl_dev, tiling, + mt->cpp, mt->pitch, + x + chunk_x, y + chunk_y, + &offset, + &tile_x, &tile_y); + + BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, false); + OUT_BATCH(CMD | (length - 2)); + OUT_BATCH(BR13); + OUT_BATCH(SET_FIELD(y + chunk_y, BLT_Y) | + SET_FIELD(x + chunk_x, BLT_X)); + OUT_BATCH(SET_FIELD(y + chunk_y + chunk_h, BLT_Y) | + SET_FIELD(x + chunk_x + chunk_w, BLT_X)); + if (brw->gen >= 8) { + OUT_RELOC64(mt->bo, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + offset); + } else { + OUT_RELOC(mt->bo, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + offset); + } + OUT_BATCH(0xffffffff); /* white, but only alpha gets written */ + ADVANCE_BATCH_TILED(dst_y_tiled, false); + } } - OUT_BATCH(0xffffffff); /* white, but only alpha gets written */ - ADVANCE_BATCH_TILED(dst_y_tiled, false); brw_emit_mi_flush(brw); } -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev