xf86-video-intel: 6 commits - src/sna/blt.c src/sna/gen3_render.c src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_composite.c src/sna/sna_glyphs.c src/sna/sna_io.c src/sna/sna_render_inline.h
Chris Wilson
ickle at kemper.freedesktop.org
Mon Nov 7 12:09:33 PST 2011
src/sna/blt.c | 9 ++--
src/sna/gen3_render.c | 18 +++++---
src/sna/sna_accel.c | 91 ++++++++++++++++++++++++++++++++++++++------
src/sna/sna_blt.c | 75 ++++++++++++++----------------------
src/sna/sna_composite.c | 90 +++++++++++++++++--------------------------
src/sna/sna_glyphs.c | 27 +++++++------
src/sna/sna_io.c | 10 ++++
src/sna/sna_render_inline.h | 2
8 files changed, 189 insertions(+), 133 deletions(-)
New commits:
commit 8f7a8a80237db77452f02273bd8ade68dfba575f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 7 20:08:25 2011 +0000
sna/composite: Minor fixes in operator and colour reduction
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 725a3cf..a6f867f 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -41,25 +41,6 @@
#define DBG(x) ErrorF x
#endif
-static void dst_move_area_to_cpu(PicturePtr picture,
- uint8_t op,
- BoxPtr box)
-{
- RegionRec area;
-
- DBG(("%s: (%d, %d), (%d %d)\n", __FUNCTION__,
- box->x1, box->y1, box->x2, box->y2));
-
- RegionInit(&area, box, 1);
- if (picture->pCompositeClip)
- RegionIntersect(&area, &area, picture->pCompositeClip);
- sna_drawable_move_region_to_cpu(picture->pDrawable, &area, true);
- RegionUninit(&area);
-
- /* XXX use op to avoid a readback? */
- (void)op;
-}
-
#define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
static inline bool
@@ -492,7 +473,7 @@ fallback:
dst->pDrawable->x, dst->pDrawable->y,
width, height));
- dst_move_area_to_cpu(dst, op, ®ion.extents);
+ sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, true);
if (dst->alphaMap)
sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, true);
if (src->pDrawable) {
@@ -506,7 +487,7 @@ fallback:
sna_drawable_move_to_cpu(mask->alphaMap->pDrawable, false);
}
- DBG(("%s: fallback -- fbCompposite\n", __FUNCTION__));
+ DBG(("%s: fallback -- fbComposite\n", __FUNCTION__));
fbComposite(op, src, mask, dst,
src_x, src_y,
mask_x, mask_y,
@@ -540,13 +521,15 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t *region,
}
for (i = j = 0; i < num_rects; i++) {
- boxes[j].x1 = rects[i].x + tx;
+ boxes[j].x1 = rects[i].x;
if (boxes[j].x1 < 0)
boxes[j].x1 = 0;
+ boxes[j].x1 += tx;
- boxes[j].y1 = rects[i].y + ty;
+ boxes[j].y1 = rects[i].y;
if (boxes[j].y1 < 0)
boxes[j].y1 = 0;
+ boxes[j].y1 += ty;
boxes[j].x2 = bound(rects[i].x, rects[i].width);
if (boxes[j].x2 > maxx)
@@ -642,6 +625,7 @@ sna_composite_rectangles(CARD8 op,
break;
}
}
+ DBG(("%s: converted to op %d\n", __FUNCTION__, op));
if (!pixman_region_not_empty(dst->pCompositeClip)) {
DBG(("%s: empty clip, skipping\n", __FUNCTION__));
@@ -696,13 +680,6 @@ sna_composite_rectangles(CARD8 op,
boxes = pixman_region_rectangles(®ion, &num_boxes);
- if (op == PictOpClear) {
- color->red = color->green = color->blue = color->alpha = 0;
- } else if (color->alpha >= 0xff00 && op == PictOpOver) {
- color->alpha = 0xffff;
- op = PictOpSrc;
- }
-
if (too_small(dst->pDrawable)) {
DBG(("%s: fallback, dst is too small\n", __FUNCTION__));
goto fallback;
@@ -750,33 +727,38 @@ fallback:
BoxPtr box = REGION_RECTS(®ion);
uint32_t pixel;
- if (sna_get_pixel_from_rgba(&pixel,
- color->red,
- color->green,
- color->blue,
- color->alpha,
- dst->format)) {
- do {
- DBG(("%s: fallback fill: (%d, %d)x(%d, %d) %08x\n",
- __FUNCTION__,
- box->x1, box->y1,
- box->x2 - box->x1,
- box->y2 - box->y1,
- pixel));
-
- pixman_fill(pixmap->devPrivate.ptr,
- pixmap->devKind/sizeof(uint32_t),
- pixmap->drawable.bitsPerPixel,
- box->x1, box->y1,
- box->x2 - box->x1,
- box->y2 - box->y1,
- pixel);
- box++;
- } while (--nbox);
- }
+ if (op == PictOpClear)
+ pixel = 0;
+ else if (!sna_get_pixel_from_rgba(&pixel,
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha,
+ dst->format))
+ goto fallback_composite;
+
+ do {
+ DBG(("%s: fallback fill: (%d, %d)x(%d, %d) %08x\n",
+ __FUNCTION__,
+ box->x1, box->y1,
+ box->x2 - box->x1,
+ box->y2 - box->y1,
+ pixel));
+
+ pixman_fill(pixmap->devPrivate.ptr,
+ pixmap->devKind/sizeof(uint32_t),
+ pixmap->drawable.bitsPerPixel,
+ box->x1, box->y1,
+ box->x2 - box->x1,
+ box->y2 - box->y1,
+ pixel);
+ box++;
+ } while (--nbox);
} else {
PicturePtr src;
+fallback_composite:
+ DBG(("%s: fallback -- fbComposite()\n", __FUNCTION__));
src = CreateSolidPicture(0, color, &error);
if (src) {
do {
commit b1234f3d3a27f326b8048e3d6b476021a26e9101
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 7 20:07:37 2011 +0000
sna: Expand multiplies of two 16-bit values to a full 32-bit range
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index a9dbed7..acec111 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -723,7 +723,7 @@ glyphs_via_mask(struct sna *sna,
}
component_alpha = NeedsComponent(format->format);
- if (width * height * format->depth < 8 * 256) {
+ if ((uint32_t)width * height * format->depth < 8 * 256) {
pixman_image_t *mask_image;
int s;
@@ -1137,27 +1137,30 @@ glyphs_fallback(CARD8 op,
g->info.width,
g->info.height);
} else {
- DBG(("%s: glyph+(%d, %d) to dst (%d, %d)x(%d, %d)\n",
+ int xi = x - g->info.x;
+ int yi = y - g->info.y;
+
+ DBG(("%s: glyph+(%d, %d) to dst (%d, %d)x(%d, %d), src (%d, %d) [op=%d]\n",
__FUNCTION__,
dx, dy,
- x - g->info.x,
- y - g->info.y,
- g->info.width,
- g->info.height));
+ xi, yi,
+ g->info.width, g->info.height,
+ src_x + xi,
+ src_y + yi,
+ op));
pixman_image_composite(op,
src_image,
glyph_image,
dst_image,
- src_x + (x - g->info.x),
- src_y + (y - g->info.y),
+ src_x + xi,
+ src_y + yi,
dx, dy,
- x - g->info.x,
- y - g->info.y,
+ xi, yi,
g->info.width,
g->info.height);
}
- free_pixman_pict(picture,glyph_image);
+ free_pixman_pict(picture, glyph_image);
next_glyph:
x += g->info.xOff;
@@ -1207,7 +1210,7 @@ sna_glyphs(CARD8 op,
if (REGION_NUM_RECTS(dst->pCompositeClip) == 0)
return;
- if (FALLBACK)
+ if (FALLBACK || DEBUG_NO_RENDER)
goto fallback;
if (sna->kgem.wedged || !sna->have_render) {
diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index 8ad755c..91aa7e4 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -90,7 +90,7 @@ is_dirty_gpu(DrawablePtr drawable)
static inline Bool
too_small(DrawablePtr drawable)
{
- return (drawable->width * drawable->height * drawable->bitsPerPixel <= 8*4096) &&
+ return ((uint32_t)drawable->width * drawable->height * drawable->bitsPerPixel <= 8*4096) &&
!is_dirty_gpu(drawable);
}
commit afdf931e61821985b31b339d1f346ddd7c4e9e3c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 7 20:06:35 2011 +0000
sna: Add some more debugging in the hunt for overflows
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e33d45a..9fddd4f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1087,11 +1087,15 @@ static void sna_gc_move_to_cpu(GCPtr gc, DrawablePtr drawable)
}
sgc->changes = 0;
- if (gc->stipple)
- sna_drawable_move_to_cpu(&gc->stipple->drawable, false);
-
- if (gc->fillStyle == FillTiled)
+ switch (gc->fillStyle) {
+ case FillTiled:
sna_drawable_move_to_cpu(&gc->tile.pixmap->drawable, false);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ sna_drawable_move_to_cpu(&gc->stipple->drawable, false);
+ break;
+ }
}
static inline bool clip_box(BoxPtr box, GCPtr gc)
@@ -2142,6 +2146,10 @@ fallback:
__FUNCTION__,
box->x1, box->y1,
box->x2, box->y2));
+ assert(box->x1 + src_dx >= 0);
+ assert(box->y1 + src_dy >= 0);
+ assert(box->x1 + dst_dx >= 0);
+ assert(box->y1 + dst_dy >= 0);
fbBlt(src_bits + (box->y1 + src_dy) * src_stride,
src_stride,
(box->x1 + src_dx) * bpp,
@@ -4717,7 +4725,7 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
if (gc->capStyle != CapProjecting)
extra >>= 1;
- if (seg->x2 > seg->x1) {
+ if (seg->x2 >= seg->x1) {
box.x1 = seg->x1;
box.x2 = seg->x2;
} else {
@@ -4725,7 +4733,7 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
box.x1 = seg->x2;
}
- if (seg->y2 > seg->y1) {
+ if (seg->y2 >= seg->y1) {
box.y1 = seg->y1;
box.y2 = seg->y2;
} else {
@@ -4766,9 +4774,13 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
box.y2 += extra;
}
+ DBG(("%s: unclipped, untranslated extents (%d, %d), (%d, %d)\n",
+ __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+
clipped = trim_and_translate_box(&box, drawable, gc);
if (box_empty(&box))
return 0;
+
*out = box;
return 1 | clipped << 1 | can_blit << 2;
}
@@ -5575,9 +5587,10 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes);
int16_t dx, dy;
- DBG(("%s x %d [(%d, %d)+(%d, %d)...], clipped?=%d\n",
- __FUNCTION__,
- n, rect->x, rect->y, rect->width, rect->height,
+ DBG(("%s x %d [(%d, %d)x(%d, %d)...]+(%d,%d), clipped?=%d\n",
+ __FUNCTION__, n,
+ rect->x, rect->y, rect->width, rect->height,
+ drawable->x, drawable->y,
clipped));
if (n == 1 && gc->pCompositeClip->data == NULL) {
@@ -6764,10 +6777,66 @@ fallback:
sna_gc_move_to_cpu(gc, draw);
sna_drawable_move_region_to_cpu(draw, ®ion, true);
- RegionUninit(®ion);
DBG(("%s: fallback - fbPolyFillRect\n", __FUNCTION__));
- fbPolyFillRect(draw, gc, n, rect);
+ if (region.data == NULL) {
+ do {
+ BoxRec box;
+
+ box.x1 = rect->x + draw->x;
+ box.y1 = rect->y + draw->y;
+ box.x2 = bound(box.x1, rect->width);
+ box.y2 = bound(box.y1, rect->height);
+ rect++;
+
+ if (box_intersect(&box, ®ion.extents)) {
+ DBG(("%s: fallback - fbFill((%d, %d), (%d, %d))\n",
+ __FUNCTION__,
+ box.x1, box.y1,
+ box.x2-box.x1, box.y2-box.y1));
+ fbFill(draw, gc,
+ box.x1, box.y1,
+ box.x2-box.x1, box.y2-box.y1);
+ }
+ } while (--n);
+ } else {
+ const BoxRec * const clip_start = RegionBoxptr(®ion);
+ const BoxRec * const clip_end = clip_start + region.data->numRects;
+ const BoxRec *c;
+
+ do {
+ BoxRec box;
+
+ box.x1 = rect->x + draw->x;
+ box.y1 = rect->y + draw->y;
+ box.x2 = bound(box.x1, rect->width);
+ box.y2 = bound(box.y1, rect->height);
+ rect++;
+
+ c = find_clip_box_for_y(clip_start,
+ clip_end,
+ box.y1);
+
+ while (c != clip_end) {
+ BoxRec b;
+
+ if (box.y2 <= c->y1)
+ break;
+
+ b = box;
+ if (box_intersect(&b, c++)) {
+ DBG(("%s: fallback - fbFill((%d, %d), (%d, %d))\n",
+ __FUNCTION__,
+ b.x1, b.y1,
+ b.x2-b.x1, b.y2-b.y1));
+ fbFill(draw, gc,
+ b.x1, b.y1,
+ b.x2-b.x1, b.y2-b.y1);
+ }
+ }
+ } while (--n);
+ }
+ RegionUninit(®ion);
}
struct sna_font {
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index a36adc9..963efb3 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -61,6 +61,16 @@ static void read_boxes_inplace(struct kgem *kgem,
return;
do {
+ assert(box->x1 + src_dx >= 0);
+ assert(box->y1 + src_dy >= 0);
+ assert(box->x2 + src_dx <= pixmap->drawable.width);
+ assert(box->y2 + src_dy <= pixmap->drawable.height);
+
+ assert(box->x1 + dst_dx >= 0);
+ assert(box->y1 + dst_dy >= 0);
+ assert(box->x2 + dst_dx <= pixmap->drawable.width);
+ assert(box->y2 + dst_dy <= pixmap->drawable.height);
+
memcpy_blt(src, dst, bpp,
src_pitch, dst_pitch,
box->x1 + src_dx, box->y1 + src_dy,
commit 8f3c845782fdb2fa8bdf751bdd7dd83ca02c42ac
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 7 20:05:41 2011 +0000
sna/blt: Small cleanups
Whilst perusing for overflows, remove some redundant conditionals.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 6965cbd..2e61bb9 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -137,8 +137,7 @@ static bool sna_blt_fill_init(struct sna *sna,
blt->cmd |= 1 << 11;
pitch >>= 2;
}
- if (pitch > MAXSHORT)
- return FALSE;
+ assert(pitch < MAXSHORT);
if (alu == GXclear)
pixel = 0;
@@ -280,16 +279,14 @@ static Bool sna_blt_copy_init(struct sna *sna,
blt->cmd |= BLT_SRC_TILED;
blt->pitch[0] >>= 2;
}
- if (blt->pitch[0] > MAXSHORT)
- return FALSE;
+ assert(blt->pitch[0] < MAXSHORT);
blt->pitch[1] = dst->pitch;
if (kgem->gen >= 40 && dst->tiling) {
blt->cmd |= BLT_DST_TILED;
blt->pitch[1] >>= 2;
}
- if (blt->pitch[1] > MAXSHORT)
- return FALSE;
+ assert(blt->pitch[1] < MAXSHORT);
blt->overwrites = alu == GXcopy || alu == GXclear || alu == GXset;
blt->br13 = (copy_ROP[alu] << 16) | blt->pitch[1];
@@ -1078,9 +1075,10 @@ static void blt_put_composite_boxes(struct sna *sna,
PixmapPtr src = op->u.blt.src_pixmap;
struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap);
- DBG(("%s: src=(%d, %d), dst=(%d, %d) x %d\n", __FUNCTION__,
+ DBG(("%s: src=(%d, %d), dst=(%d, %d), [(%d, %d), (%d, %d) x %d]\n", __FUNCTION__,
op->u.blt.sx, op->u.blt.sy,
- op->dst.x, op->dst.y, n));
+ op->dst.x, op->dst.y,
+ box->x1, box->y1, box->x2, box->y2, n));
if (n == 1 && !dst_priv->pinned &&
box->x2 - box->x1 == op->dst.width &&
@@ -1176,6 +1174,7 @@ has_gpu_area(PixmapPtr pixmap, int x, int y, int w, int h)
area.y1 = y;
area.x2 = x + w;
area.y2 = y + h;
+
return sna_damage_contains_box(priv->cpu_damage,
&area) == PIXMAN_REGION_OUT;
}
@@ -1220,7 +1219,10 @@ reduce_damage(struct sna_composite_op *op,
r.y1 = dst_y + op->dst.y;
r.y2 = r.y1 + height;
- if (sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
+ if (sna_damage_is_all(op->damage,
+ op->dst.pixmap->drawable.width,
+ op->dst.pixmap->drawable.width) ||
+ sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
op->damage = NULL;
}
@@ -1310,11 +1312,9 @@ sna_blt_composite(struct sna *sna,
return FALSE;
}
- if (!sna_blt_compare_depth(src->pDrawable, dst->pDrawable)) {
- DBG(("%s: mismatching depth src=%d/%d, dst=%d/%d\n",
- __FUNCTION__,
- src->pDrawable->depth, src->pDrawable->bitsPerPixel,
- dst->pDrawable->depth, dst->pDrawable->bitsPerPixel));
+ if (src->filter == PictFilterConvolution) {
+ DBG(("%s: convolutions filters not handled\n",
+ __FUNCTION__));
return FALSE;
}
@@ -1327,12 +1327,6 @@ sna_blt_composite(struct sna *sna,
return FALSE;
}
- if (src->filter == PictFilterConvolution) {
- DBG(("%s: convolutions filters not handled\n",
- __FUNCTION__));
- return FALSE;
- }
-
if (!(dst->format == src_format ||
dst->format == PICT_FORMAT(PICT_FORMAT_BPP(src_format),
PICT_FORMAT_TYPE(src_format),
@@ -1505,8 +1499,7 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
const BoxRec *box)
{
struct kgem *kgem = &sna->kgem;
- uint32_t br13, cmd;
- uint32_t *b;
+ uint32_t br13, cmd, *b;
DBG(("%s: box=((%d, %d), (%d, %d))\n", __FUNCTION__,
box->x1, box->y1, box->x2, box->y2));
@@ -1515,27 +1508,27 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
assert(box->y1 >= 0);
cmd = XY_COLOR_BLT;
- if (bpp == 32)
- cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
-
br13 = bo->pitch;
if (kgem->gen >= 40 && bo->tiling) {
cmd |= BLT_DST_TILED;
br13 >>= 2;
}
- if (br13 > MAXSHORT) {
- DBG(("%s: fallback -- pitch is too large %d [%d]\n",
- __FUNCTION__, bo->pitch, br13));
- return FALSE;
- }
+ assert(br13 < MAXSHORT);
- if (color == 0)
- alu = GXclear;
+ if (alu == GXclear)
+ color = 0;
+ else if (alu == GXcopy) {
+ if (color == 0)
+ alu = GXclear;
+ else if (color == -1)
+ alu = GXset;
+ }
br13 |= fill_ROP[alu] << 16;
switch (bpp) {
default: assert(0);
- case 32: br13 |= 1 << 25; /* RGB8888 */
+ case 32: cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+ br13 |= 1 << 25; /* RGB8888 */
case 16: br13 |= 1 << 24; /* RGB565 */
case 8: break;
}
@@ -1544,8 +1537,7 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
if (kgem->nbatch >= 6 &&
(alu == GXcopy || alu == GXclear || alu == GXset) &&
kgem->batch[kgem->nbatch-6] == cmd &&
- kgem->batch[kgem->nbatch-4] == ((uint32_t)box[0].y1 << 16 | (uint16_t)box[0].x1) &&
- kgem->batch[kgem->nbatch-3] == ((uint32_t)box[0].y2 << 16 | (uint16_t)box[0].x2) &&
+ *(uint64_t *)&kgem->batch[kgem->nbatch-4] == *(uint64_t *)box &&
kgem->reloc[kgem->nreloc-1].target_handle == bo->handle) {
DBG(("%s: replacing last fill\n", __FUNCTION__));
kgem->batch[kgem->nbatch-5] = br13;
@@ -1562,12 +1554,10 @@ static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
}
b = kgem->batch + kgem->nbatch;
-
b[0] = cmd;
b[1] = br13;
*(uint64_t *)(b+2) = *(uint64_t *)box;
- b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4,
- bo,
+ b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo,
I915_GEM_DOMAIN_RENDER << 16 |
I915_GEM_DOMAIN_RENDER |
KGEM_RELOC_FENCED,
@@ -1608,8 +1598,7 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
cmd |= 1 << 11;
br13 >>= 2;
}
- if (br13 > MAXSHORT)
- return FALSE;
+ assert(br13 < MAXSHORT);
if (alu == GXclear)
pixel = 0;
@@ -1756,16 +1745,14 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
cmd |= BLT_SRC_TILED;
src_pitch >>= 2;
}
- if (src_pitch > MAXSHORT)
- return FALSE;
+ assert(src_pitch < MAXSHORT);
br13 = dst_bo->pitch;
if (kgem->gen >= 40 && dst_bo->tiling) {
cmd |= BLT_DST_TILED;
br13 >>= 2;
}
- if (br13 > MAXSHORT)
- return FALSE;
+ assert(br13 < MAXSHORT);
br13 |= copy_ROP[alu] << 16;
switch (bpp) {
commit 8e775cecccebe543d344721d45b2d43ee9f122b3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 7 20:01:33 2011 +0000
sna/gen3: Fix false reduction of ComponentAlpha with white source
The principle behind the opertator reduction of WHITE * maskca is valid,
except that we failed to account for the src/mask transposition when
emitting the vertices - garbage ensued.
Given that we agressively reduce the shader required for WHITE * maskca,
it does not seem worthwhile to special case the primitive emitter as
well.
Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42676
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 5439672..c8ad209 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1078,7 +1078,6 @@ gen3_composite_emit_shader(struct sna *sna,
*/
if (op->has_component_alpha) {
switch (src->u.gen3.type) {
- case SHADER_WHITE:
case SHADER_BLACK:
if (gen3_blend_op[blend].src_alpha)
gen3_fs_mov(out_reg,
@@ -1087,6 +1086,10 @@ gen3_composite_emit_shader(struct sna *sna,
gen3_fs_mov(out_reg,
gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
break;
+ case SHADER_WHITE:
+ gen3_fs_mov(out_reg,
+ gen3_fs_operand_reg(mask_reg));
+ break;
default:
if (gen3_blend_op[blend].src_alpha)
gen3_fs_mul(out_reg,
@@ -1853,6 +1856,9 @@ gen3_init_solid(struct sna_composite_channel *channel, uint32_t color)
channel->alpha_fixup = 0;
channel->rb_reversed = 0;
+ DBG(("%s: color=%08x, is_opaque=%d, type=%d\n",
+ __FUNCTION__, color, channel->is_opaque, channel->u.gen3.type));
+
/* for consistency */
channel->repeat = RepeatNormal;
channel->filter = PictFilterNearest;
@@ -2182,7 +2188,10 @@ reduce_damage(struct sna_composite_op *op,
r.y1 = dst_y + op->dst.y;
r.y2 = r.y1 + height;
- if (sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
+ if (sna_damage_is_all(op->damage,
+ op->dst.pixmap->drawable.width,
+ op->dst.pixmap->drawable.width) ||
+ sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
op->damage = NULL;
}
@@ -2378,11 +2387,6 @@ gen3_render_composite(struct sna *sna,
if (tmp->mask.u.gen3.type == SHADER_WHITE) {
tmp->mask.u.gen3.type = SHADER_NONE;
tmp->has_component_alpha = FALSE;
- } else if (tmp->src.u.gen3.type == SHADER_WHITE) {
- tmp->src = tmp->mask;
- tmp->mask.u.gen3.type = SHADER_NONE;
- tmp->mask.bo = NULL;
- tmp->has_component_alpha = FALSE;
} else if (is_constant_ps(tmp->src.u.gen3.type) &&
is_constant_ps(tmp->mask.u.gen3.type)) {
uint32_t a,r,g,b;
commit 65a440543b13e3e605a4a2d6209a460fbbe55736
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Nov 7 20:00:20 2011 +0000
sna: Fix 16-bit overflow of rowlength for memcpy
Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42619
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/blt.c b/src/sna/blt.c
index 5dc318c..ca15453 100644
--- a/src/sna/blt.c
+++ b/src/sna/blt.c
@@ -45,6 +45,7 @@ memcpy_blt(const void *src, void *dst, int bpp,
{
uint8_t *src_bytes;
uint8_t *dst_bytes;
+ int byte_width;
assert(width && height);
assert(bpp >= 8);
@@ -53,18 +54,18 @@ memcpy_blt(const void *src, void *dst, int bpp,
__FUNCTION__, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride));
bpp /= 8;
- width *= bpp;
src_bytes = (uint8_t *)src + src_stride * src_y + src_x * bpp;
dst_bytes = (uint8_t *)dst + dst_stride * dst_y + dst_x * bpp;
- if (width == src_stride && width == dst_stride) {
- memcpy(dst_bytes, src_bytes, width * height);
+ byte_width = width * bpp;
+ if (byte_width == src_stride && byte_width == dst_stride) {
+ memcpy(dst_bytes, src_bytes, byte_width * height);
return;
}
do {
- memcpy(dst_bytes, src_bytes, width);
+ memcpy(dst_bytes, src_bytes, byte_width);
src_bytes += src_stride;
dst_bytes += dst_stride;
} while (--height);
More information about the xorg-commit
mailing list