diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-02 17:43:33 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-03 23:09:07 +0100 |
commit | a972affe0c78b23a119d5dd14bb4446c89122af1 (patch) | |
tree | 5356b85354d4584a021d93010bfc27873b1512bc /src | |
parent | 18d26076c778c20eb589b638fc47fa847793f149 (diff) |
sna/gen6+: Redirect fills if the destination is too large for 3D
Reported-by: Clemens Eisserer <linuxhippy@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54134
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/gen6_render.c | 68 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 68 | ||||
-rw-r--r-- | src/sna/sna_tiling.c | 1 |
3 files changed, 82 insertions, 55 deletions
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 6d5a6cec..363e8dbe 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -1287,7 +1287,8 @@ gen6_emit_composite_primitive_solid(struct sna *sna, v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); - assert(!too_large(r->dst.x + r->width, r->dst.y + r->height)); + assert(!too_large(op->dst.x + r->dst.x + r->width, + op->dst.y + r->dst.y + r->height)); dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; @@ -3249,15 +3250,8 @@ static inline bool prefer_blt_copy(struct sna *sna, prefer_blt_bo(sna, dst_bo)); } -static inline bool -overlaps(struct sna *sna, - struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, - struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, - const BoxRec *box, int n, BoxRec *extents) +inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents) { - if (src_bo != dst_bo) - return false; - *extents = box[0]; while (--n) { box++; @@ -3272,7 +3266,18 @@ overlaps(struct sna *sna, if (box->y2 > extents->y2) extents->y2 = box->y2; } +} +static inline bool +overlaps(struct sna *sna, + struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, + struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, + const BoxRec *box, int n, BoxRec *extents) +{ + if (src_bo != dst_bo) + return false; + + boxes_extents(box, n, extents); return (extents->x2 + src_dx > extents->x1 + dst_dx && extents->x1 + src_dx < extents->x2 + dst_dx && extents->y2 + src_dy > extents->y1 + dst_dy && @@ -3667,22 +3672,21 @@ gen6_render_fill_boxes(struct sna *sna, return false; } - if (op <= PictOpSrc && - (prefer_blt_fill(sna, dst_bo) || - too_large(dst->drawable.width, dst->drawable.height) || - !gen6_check_dst_format(format))) { + if (prefer_blt_fill(sna, dst_bo) || !gen6_check_dst_format(format)) { uint8_t alu = GXinvalid; - pixel = 0; - if (op == PictOpClear) - alu = GXclear; - else if (sna_get_pixel_from_rgba(&pixel, - color->red, - color->green, - color->blue, - color->alpha, - format)) - alu = GXcopy; + if (op <= PictOpSrc) { + pixel = 0; + if (op == PictOpClear) + alu = GXclear; + else if (sna_get_pixel_from_rgba(&pixel, + color->red, + color->green, + color->blue, + color->alpha, + format)) + alu = GXcopy; + } if (alu != GXinvalid && sna_blt_fill_boxes(sna, alu, @@ -3692,10 +3696,6 @@ gen6_render_fill_boxes(struct sna *sna, if (!gen6_check_dst_format(format)) return false; - - if (too_large(dst->drawable.width, dst->drawable.height)) - return sna_tiling_fill_boxes(sna, op, format, color, - dst, dst_bo, box, n); } if (op == PictOpClear) { @@ -3720,6 +3720,19 @@ gen6_render_fill_boxes(struct sna *sna, tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; + sna_render_composite_redirect_init(&tmp); + if (too_large(dst->drawable.width, dst->drawable.height)) { + BoxRec extents; + + boxes_extents(box, n, &extents); + if (!sna_render_composite_redirect(sna, &tmp, + extents.x1, extents.y1, + extents.x2 - extents.x1, + extents.y2 - extents.y1)) + return sna_tiling_fill_boxes(sna, op, format, color, + dst, dst_bo, box, n); + } + tmp.src.bo = sna_render_get_solid(sna, pixel); tmp.mask.bo = NULL; @@ -3767,6 +3780,7 @@ gen6_render_fill_boxes(struct sna *sna, gen6_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); + sna_render_composite_redirect_done(sna, &tmp); return true; } diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index ffe41cf3..0cc4cba0 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -1401,7 +1401,8 @@ gen7_emit_composite_primitive_solid(struct sna *sna, v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); - assert(!too_large(r->dst.x + r->width, r->dst.y + r->height)); + assert(!too_large(op->dst.x + r->dst.x + r->width, + op->dst.y + r->dst.y + r->height)); dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; @@ -3338,15 +3339,8 @@ static inline bool prefer_blt_copy(struct sna *sna, prefer_blt_bo(sna, dst_bo)); } -static inline bool -overlaps(struct sna *sna, - struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, - struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, - const BoxRec *box, int n, BoxRec *extents) +inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents) { - if (src_bo != dst_bo) - return false; - *extents = box[0]; while (--n) { box++; @@ -3361,7 +3355,18 @@ overlaps(struct sna *sna, if (box->y2 > extents->y2) extents->y2 = box->y2; } +} +static inline bool +overlaps(struct sna *sna, + struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, + struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, + const BoxRec *box, int n, BoxRec *extents) +{ + if (src_bo != dst_bo) + return false; + + boxes_extents(box, n, extents); return (extents->x2 + src_dx > extents->x1 + dst_dx && extents->x1 + src_dx < extents->x2 + dst_dx && extents->y2 + src_dy > extents->y1 + dst_dy && @@ -3742,22 +3747,21 @@ gen7_render_fill_boxes(struct sna *sna, return false; } - if (op <= PictOpSrc && - (prefer_blt_fill(sna, dst_bo) || - too_large(dst->drawable.width, dst->drawable.height) || - !gen7_check_dst_format(format))) { + if (prefer_blt_fill(sna, dst_bo) || !gen7_check_dst_format(format)) { uint8_t alu = GXinvalid; - pixel = 0; - if (op == PictOpClear) - alu = GXclear; - else if (sna_get_pixel_from_rgba(&pixel, - color->red, - color->green, - color->blue, - color->alpha, - format)) - alu = GXcopy; + if (op <= PictOpSrc) { + pixel = 0; + if (op == PictOpClear) + alu = GXclear; + else if (sna_get_pixel_from_rgba(&pixel, + color->red, + color->green, + color->blue, + color->alpha, + format)) + alu = GXcopy; + } if (alu != GXinvalid && sna_blt_fill_boxes(sna, alu, @@ -3767,10 +3771,6 @@ gen7_render_fill_boxes(struct sna *sna, if (!gen7_check_dst_format(format)) return false; - - if (too_large(dst->drawable.width, dst->drawable.height)) - return sna_tiling_fill_boxes(sna, op, format, color, - dst, dst_bo, box, n); } if (op == PictOpClear) { @@ -3795,6 +3795,19 @@ gen7_render_fill_boxes(struct sna *sna, tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; + sna_render_composite_redirect_init(&tmp); + if (too_large(dst->drawable.width, dst->drawable.height)) { + BoxRec extents; + + boxes_extents(box, n, &extents); + if (!sna_render_composite_redirect(sna, &tmp, + extents.x1, extents.y1, + extents.x2 - extents.x1, + extents.y2 - extents.y1)) + return sna_tiling_fill_boxes(sna, op, format, color, + dst, dst_bo, box, n); + } + tmp.src.bo = sna_render_get_solid(sna, pixel); tmp.mask.bo = NULL; @@ -3839,6 +3852,7 @@ gen7_render_fill_boxes(struct sna *sna, gen7_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); + sna_render_composite_redirect_done(sna, &tmp); return true; } diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c index e0483618..9e70833c 100644 --- a/src/sna/sna_tiling.c +++ b/src/sna/sna_tiling.c @@ -648,7 +648,6 @@ sna_tiling_fill_boxes(struct sna *sna, int16_t dy = this.extents.y1; assert(kgem_bo_can_blt(&sna->kgem, bo)); - assert(bo->pitch <= 8192); if (!sna->render.copy_boxes(sna, GXcopy, dst, dst_bo, 0, 0, |