From bdc5241af4aa9afbd66f6c96ee6d20e09f77ea89 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 23 Dec 2013 15:30:03 -0800 Subject: [PATCH] i965: Don't call the blitter on addresses it can't handle. Noticed by tex3d-maxsize on my next commit to check that our addresses don't overflow. Reviewed-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Anuj Phogat --- src/mesa/drivers/dri/i965/intel_blit.c | 20 ++++++++++++++++ src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 23 ++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 7bc289f350e..13cc77792e4 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -229,12 +229,32 @@ intel_miptree_blit(struct brw_context *brw, src_x += src_image_x; src_y += src_image_y; + /* The blitter interprets the 16-bit src x/y as a signed 16-bit value, + * where negative values are invalid. The values we're working with are + * unsigned, so make sure we don't overflow. + */ + if (src_x >= 32768 || src_y >= 32768) { + perf_debug("Falling back due to >=32k src offset (%d, %d)\n", + src_x, src_y); + return false; + } + uint32_t dst_image_x, dst_image_y; intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice, &dst_image_x, &dst_image_y); dst_x += dst_image_x; dst_y += dst_image_y; + /* The blitter interprets the 16-bit destination x/y as a signed 16-bit + * value. The values we're working with are unsigned, so make sure we + * don't overflow. + */ + if (dst_x >= 32768 || dst_y >= 32768) { + perf_debug("Falling back due to >=32k dst offset (%d, %d)\n", + dst_x, dst_y); + return false; + } + if (!intelEmitCopyBlit(brw, src_mt->cpp, src_pitch, diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index de47143397a..0818226f3c4 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -443,7 +443,8 @@ intel_miptree_choose_tiling(struct brw_context *brw, if (minimum_pitch < 64) return I915_TILING_NONE; - if (ALIGN(minimum_pitch, 512) >= 32768) { + if (ALIGN(minimum_pitch, 512) >= 32768 || + mt->total_width >= 32768 || mt->total_height >= 32768) { perf_debug("%dx%d miptree too large to blit, falling back to untiled", mt->total_width, mt->total_height); return I915_TILING_NONE; @@ -2233,6 +2234,22 @@ intel_miptree_release_map(struct intel_mipmap_tree *mt, *map = NULL; } +static bool +can_blit_slice(struct intel_mipmap_tree *mt, + unsigned int level, unsigned int slice) +{ + uint32_t image_x; + uint32_t image_y; + intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y); + if (image_x >= 32768 || image_y >= 32768) + return false; + + if (mt->region->pitch >= 32768) + return false; + + return true; +} + static void intel_miptree_map_singlesample(struct brw_context *brw, struct intel_mipmap_tree *mt, @@ -2276,11 +2293,11 @@ intel_miptree_map_singlesample(struct brw_context *brw, !mt->compressed && (mt->region->tiling == I915_TILING_X || (brw->gen >= 6 && mt->region->tiling == I915_TILING_Y)) && - mt->region->pitch < 32768) { + can_blit_slice(mt, level, slice)) { intel_miptree_map_blit(brw, mt, map, level, slice); } else if (mt->region->tiling != I915_TILING_NONE && mt->region->bo->size >= brw->max_gtt_map_object_size) { - assert(mt->region->pitch < 32768); + assert(can_blit_slice(mt, level, slice)); intel_miptree_map_blit(brw, mt, map, level, slice); #ifdef __SSE4_1__ } else if (!(mode & GL_MAP_WRITE_BIT) && !mt->compressed) { -- 2.30.2