summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2013-12-23 15:30:03 -0800
committerEric Anholt <[email protected]>2014-01-09 15:23:00 +0800
commitbdc5241af4aa9afbd66f6c96ee6d20e09f77ea89 (patch)
tree6f49bf2be8113e126b700b60da0a6f3023ffefd9
parente8ff08edd823ddf6b0e07ef84d2ba8afc3abbc34 (diff)
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 <[email protected]> Reviewed-by: Ian Romanick <[email protected]> Reviewed-by: Anuj Phogat <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/intel_blit.c20
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.c23
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) {