summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-09-02 17:43:33 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-09-03 23:09:07 +0100
commita972affe0c78b23a119d5dd14bb4446c89122af1 (patch)
tree5356b85354d4584a021d93010bfc27873b1512bc /src
parent18d26076c778c20eb589b638fc47fa847793f149 (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.c68
-rw-r--r--src/sna/gen7_render.c68
-rw-r--r--src/sna/sna_tiling.c1
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,