xf86-video-intel: 7 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_composite.c src/sna/sna.h src/sna/sna_render.c
Chris Wilson
ickle at kemper.freedesktop.org
Sun Jan 22 08:09:37 PST 2012
src/sna/kgem.c | 2
src/sna/sna.h | 2
src/sna/sna_accel.c | 158 +++++++++++++++++++++++++++++++++++++++++++-----
src/sna/sna_composite.c | 13 +++
src/sna/sna_render.c | 42 ++++++++----
5 files changed, 186 insertions(+), 31 deletions(-)
New commits:
commit 5aa494305e90eed5df211427741a75380add8e96
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 22 16:10:39 2012 +0000
sna: Correct the offsets for performing partial downsampling on the GPU
Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
References: https://bugs.freedesktop.org/show_bug.cgi?id=45086
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 0796453..5f79e04 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -785,7 +785,7 @@ static int sna_render_picture_downsample(struct sna *sna,
if (!sna->render.composite(sna,
PictOpSrc,
tmp_src, NULL, tmp_dst,
- box.x1 + b.x1, box.y1 + b.y1,
+ box.x1/2 + b.x1, box.y1/2 + b.y1,
0, 0,
b.x1, b.y1,
b.x2 - b.x1, b.y2 - b.y1,
commit a7b24bb4342eefb2b23fa40d7c7216c38f2edc09
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 22 15:50:47 2012 +0000
sna: Correct image buffer size when uploading a downsampled image
Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
References: https://bugs.freedesktop.org/show_bug.cgi?id=45086
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 3b4db90..8b553b9 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3224,7 +3224,7 @@ struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
__FUNCTION__, x, y, width, height, stride, bpp));
bo = kgem_create_buffer_2d(kgem,
- width, height, bpp,
+ width/2, height/2, bpp,
KGEM_BUFFER_WRITE_INPLACE,
&dst);
if (bo == NULL)
commit 238fc67aa945d5669eccd2a8fe8e98402b9a6223
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 22 16:04:13 2012 +0000
sna: Incude prefer-gpu hint in decision to upload CPU textures
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index efe415e..0796453 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -373,17 +373,20 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
w = box->x2 - box->x1;
h = box->y2 - box->y1;
if (w == pixmap->drawable.width && h == pixmap->drawable.height) {
- bool upload = true;
+ bool upload;
- if (pixmap->devKind * pixmap->drawable.height <= 4096 ||
+ priv = sna_pixmap_attach(pixmap);
+ if (!priv)
+ return false;
+
+ upload = true;
+ if (!priv->gpu ||
kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem,
I915_TILING_X,
pixmap->drawable.width,
pixmap->drawable.height,
- pixmap->drawable.bitsPerPixel) == I915_TILING_NONE) {
- priv = sna_pixmap_attach(pixmap);
- upload = priv && priv->source_count++ > SOURCE_BIAS;
- }
+ pixmap->drawable.bitsPerPixel) == I915_TILING_NONE)
+ upload = priv->source_count++ > SOURCE_BIAS;
DBG(("%s: migrating whole pixmap (%dx%d) for source (%d,%d),(%d,%d)? %d\n",
__FUNCTION__,
@@ -397,12 +400,14 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
if (64*w*h < pixmap->drawable.width * pixmap->drawable.height)
return FALSE;
- count = SOURCE_BIAS;
priv = sna_pixmap_attach(pixmap);
- if (priv)
- count = priv->source_count++;
+ if (!priv)
+ return FALSE;
- if (kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem, I915_TILING_X,
+ count = priv->source_count++;
+ if (!priv->gpu ||
+ kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem,
+ I915_TILING_X,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel) == I915_TILING_NONE)
commit aeaffb102190a8846c6341e72a4338b41639d679
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 22 15:52:41 2012 +0000
sna: Add some more DBG along the downsampling source extraction path
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index fde95f9..efe415e 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -671,11 +671,17 @@ static int sna_render_picture_downsample(struct sna *sna,
w = box.x2 - box.x1;
h = box.y2 - box.y1;
+ DBG(("%s: sample area (%d, %d), (%d, %d): %dx%d\n",
+ __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h));
assert(w && h);
- if (w > 2*sna->render.max_3d_size || h > 2*sna->render.max_3d_size)
+ if (w > 2*sna->render.max_3d_size || h > 2*sna->render.max_3d_size) {
+ DBG(("%s: sample size too large for pixman downscaling\n",
+ __FUNCTION__));
goto fixup;
+ }
if (texture_is_cpu(pixmap, &box) && !move_to_gpu(pixmap, &box)) {
+ DBG(("%s: uploading partial texture\n", __FUNCTION__));
bo = kgem_upload_source_image_halved(&sna->kgem,
picture->format,
pixmap->devPrivate.ptr,
@@ -746,8 +752,8 @@ static int sna_render_picture_downsample(struct sna *sna,
ni = 1;
}
- DBG(("%s downsampling using %dx%d GPU tiles\n",
- __FUNCTION__, ww, hh));
+ DBG(("%s %d:%d downsampling using %dx%d GPU tiles\n",
+ __FUNCTION__, nj, ni, ww, hh));
for (i = 0; i < ni; i++) {
BoxRec b;
@@ -767,6 +773,9 @@ static int sna_render_picture_downsample(struct sna *sna,
else
b.x2 = b.x1 + ww;
+ DBG(("%s: tile %d:%d, box=(%d,%d), (%d, %d)\n",
+ __FUNCTION__, i, j, b.x1, b.y1, b.x2, b.y2));
+
memset(&op, 0, sizeof(op));
if (!sna->render.composite(sna,
PictOpSrc,
commit 92badc9c9c2636284af8bc56b098d24ff222f167
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 22 12:41:31 2012 +0000
sna: Avoid a common readback after clearing
It is surprisingly common for a pixmap to be created, cleared and then
used as an upload target or, even worse, as a source for a ShmGetImage.
In order to prevent this folly, we can trivially track when we clear an
entire pixmap and its GPU bo and avoid the readback in such cases.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 0c0cb39..38ae404 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -137,12 +137,14 @@ struct sna_pixmap {
struct list inactive;
uint32_t stride;
+ uint32_t clear_color;
#define SOURCE_BIAS 4
uint16_t source_count;
uint8_t pinned :1;
uint8_t mapped :1;
uint8_t flush :1;
+ uint8_t clear :1;
uint8_t undamaged :1;
uint8_t gpu :1;
uint8_t header :1;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 1e9ee16..f9b3a48 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -798,6 +798,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
if ((flags & MOVE_READ) == 0) {
assert(flags & MOVE_WRITE);
sna_damage_destroy(&priv->gpu_damage);
+ priv->clear = false;
if (priv->gpu && pixmap_inplace(sna, pixmap, priv)) {
DBG(("%s: write inplace\n", __FUNCTION__));
@@ -882,6 +883,7 @@ skip_inplace_map:
sna_damage_all(&priv->gpu_damage,
pixmap->drawable.width,
pixmap->drawable.height);
+ priv->clear = false;
return true;
}
@@ -897,6 +899,28 @@ skip_inplace_map:
!sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL))
return false;
+ if (priv->clear) {
+ DBG(("%s: applying clear [%08x]\n",
+ __FUNCTION__, priv->clear_color));
+
+ if (priv->cpu_bo) {
+ DBG(("%s: syncing CPU bo\n", __FUNCTION__));
+ kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
+ }
+
+ pixman_fill(pixmap->devPrivate.ptr,
+ pixmap->devKind/sizeof(uint32_t),
+ pixmap->drawable.bitsPerPixel,
+ 0, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ priv->clear_color);
+
+ sna_damage_destroy(&priv->gpu_damage);
+ priv->undamaged = true;
+ priv->clear = false;
+ }
+
if (priv->gpu_damage) {
BoxPtr box;
int n;
@@ -1082,6 +1106,9 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (DAMAGE_IS_ALL(priv->cpu_damage))
goto out;
+ if (priv->clear)
+ return _sna_pixmap_move_to_cpu(pixmap, flags);
+
if (priv->gpu_bo == NULL && !priv->gpu && flags & MOVE_WRITE)
return _sna_pixmap_move_to_cpu(pixmap, flags);
@@ -1575,6 +1602,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
done:
if (!priv->pinned)
list_move(&priv->inactive, &sna->active_pixmaps);
+ priv->clear = false;
return true;
}
@@ -2008,6 +2036,7 @@ done:
active:
if (!priv->pinned)
list_move(&priv->inactive, &sna->active_pixmaps);
+ priv->clear = false;
return priv;
}
@@ -2341,6 +2370,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
}
}
+ priv->clear = false;
return true;
}
@@ -2373,6 +2403,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
sna_damage_add(&priv->gpu_damage, region);
}
+ priv->clear = false;
return true;
}
} else {
@@ -2436,6 +2467,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
}
if (priv->flush)
list_move(&priv->list, &sna->dirty_pixmaps);
+ priv->clear = false;
}
blt:
@@ -2969,7 +3001,7 @@ fallback:
alu, -1, bpp,
reverse, upsidedown);
box++;
- }while (--n);
+ } while (--n);
}
}
}
@@ -3097,7 +3129,62 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
goto fallback;
}
- if (src_priv &&
+ if (src_priv && src_priv->clear) {
+ DBG(("%s: applying src clear[%08x] to dst\n",
+ __FUNCTION__, src_priv->clear_color));
+ RegionTranslate(®ion, dst_dx, dst_dy);
+ if (n == 1) {
+ if (!sna->render.fill_one(sna,
+ dst_pixmap,
+ dst_priv->gpu_bo,
+ src_priv->clear_color,
+ box->x1, box->y1,
+ box->x2, box->y2,
+ alu)) {
+ DBG(("%s: unsupported fill\n",
+ __FUNCTION__));
+ goto fallback;
+ }
+ } else {
+ struct sna_fill_op fill;
+
+ if (!sna_fill_init_blt(&fill, sna,
+ dst_pixmap, dst_priv->gpu_bo,
+ alu, src_priv->clear_color)) {
+ DBG(("%s: unsupported fill\n",
+ __FUNCTION__));
+ goto fallback;
+ }
+
+ fill.boxes(sna, &fill, box, n);
+ fill.done(sna, &fill);
+ }
+
+ if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
+ if (replaces) {
+ sna_damage_destroy(&dst_priv->cpu_damage);
+ sna_damage_all(&dst_priv->gpu_damage,
+ dst_pixmap->drawable.width,
+ dst_pixmap->drawable.height);
+ list_del(&dst_priv->list);
+ dst_priv->undamaged = false;
+
+ dst_priv->clear = true;
+ dst_priv->clear_color = src_priv->clear_color;
+ } else {
+ assert_pixmap_contains_box(dst_pixmap,
+ RegionExtents(®ion));
+ sna_damage_add(&dst_priv->gpu_damage, ®ion);
+ }
+ RegionTranslate(®ion, -dst_dx, -dst_dy);
+ }
+
+ if (replaces) {
+ DBG(("%s: mark dst as clear\n", __FUNCTION__));
+ dst_priv->clear = true;
+ dst_priv->clear_color = src_priv->clear_color;
+ }
+ } else if (src_priv &&
move_to_gpu(src_pixmap, src_priv, ®ion.extents, alu) &&
sna_pixmap_move_to_gpu(src_pixmap, MOVE_READ)) {
if (!sna->render.copy_boxes(sna, alu,
@@ -3261,11 +3348,43 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
}
}
}
+
+ goto out;
+ }
+
+fallback:
+ if (alu == GXcopy && src_priv && src_priv->clear) {
+ DBG(("%s: copying clear [%08x]\n",
+ __FUNCTION__, src_priv->clear_color));
+
+ RegionTranslate(®ion, dst_dx, dst_dy);
+ box = REGION_RECTS(®ion);
+ n = REGION_NUM_RECTS(®ion);
+
+ if (dst_priv) {
+ assert_pixmap_contains_box(dst_pixmap,
+ RegionExtents(®ion));
+
+ if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable,
+ ®ion,
+ MOVE_WRITE | MOVE_INPLACE_HINT))
+ goto out;
+ }
+
+ do {
+ pixman_fill(dst_pixmap->devPrivate.ptr,
+ dst_pixmap->devKind/sizeof(uint32_t),
+ dst_pixmap->drawable.bitsPerPixel,
+ box->x1, box->y1,
+ box->x2 - box->x1,
+ box->y2 - box->y1,
+ src_priv->clear_color);
+ box++;
+ } while (--n);
} else {
FbBits *dst_bits, *src_bits;
int dst_stride, src_stride;
-fallback:
DBG(("%s: fallback -- src=(%d, %d), dst=(%d, %d)\n",
__FUNCTION__, src_dx, src_dy, dst_dx, dst_dy));
if (src_priv) {
@@ -3351,9 +3470,10 @@ fallback:
alu, -1, bpp,
reverse, upsidedown);
box++;
- }while (--n);
+ } while (--n);
}
}
+
out:
RegionUninit(®ion);
}
@@ -7219,6 +7339,18 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
} else
sna_damage_add_box(damage, &r);
}
+
+ if ((gc->alu == GXcopy || gc->alu == GXclear) &&
+ r.x2 - r.x1 == pixmap->drawable.width &&
+ r.y2 - r.y1 == pixmap->drawable.height) {
+ struct sna_pixmap *priv = sna_pixmap(pixmap);
+
+ priv->clear = true;
+ priv->clear_color = gc->alu == GXcopy ? pixel : 0;
+
+ DBG(("%s: pixmap=%ld, marking clear [%08x]\n",
+ __FUNCTION__, pixmap->drawable.serialNumber, priv->clear_color));
+ }
} else
success = false;
}
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 47eac63..6fb2d27 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -778,6 +778,19 @@ sna_composite_rectangles(CARD8 op,
sna_damage_all(&priv->gpu_damage,
pixmap->drawable.width, pixmap->drawable.height);
priv->undamaged = false;
+ if (op <= PictOpSrc) {
+ priv->clear = true;
+ priv->clear_color = 0;
+ if (op == PictOpSrc)
+ sna_get_pixel_from_rgba(&priv->clear_color,
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha,
+ dst->format);
+ DBG(("%s: marking clear [%08x]\n",
+ __FUNCTION__, priv->clear_color));
+ }
} else
sna_damage_add(&priv->gpu_damage, ®ion);
}
commit 67a166d1247a1197fc851308c33c4970868f6a21
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 22 13:46:05 2012 +0000
sna: Pass inplace hint for sna_copy_boxes fallback
In the unlikely event that this makes a difference, provide the hint as
to when we do not read back from the destination and so a streaming copy
would be preferable.
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 37385eb..1e9ee16 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3283,9 +3283,10 @@ fallback:
assert_pixmap_contains_box(dst_pixmap,
RegionExtents(®ion));
- mode = MOVE_WRITE;
- if (alu != GXcopy)
- mode |= MOVE_READ;
+ if (alu_overwrites(alu))
+ mode = MOVE_WRITE | MOVE_INPLACE_HINT;
+ else
+ mode = MOVE_WRITE | MOVE_READ;
if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable,
®ion, mode))
goto out;
commit 77ee92248582d65a03619d1bb1d93a74468eea00
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 22 13:42:57 2012 +0000
sna: Use full usage flags for moving the dst pixmap for a copy
Now that the migration code can decide for itself when to not move
damage, we can pass the hints to the code rather than perform the
optimisation in sna_copy_boxes.
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 8801477..37385eb 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3090,7 +3090,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
goto fallback;
}
- if (alu != GXcopy && !sna_pixmap_move_to_gpu(dst_pixmap, MOVE_READ | MOVE_WRITE)) {
+ if (!sna_pixmap_move_to_gpu(dst_pixmap,
+ MOVE_WRITE | (alu_overwrites(alu) ? 0 : MOVE_READ))) {
DBG(("%s: fallback - not a pure copy and failed to move dst to GPU\n",
__FUNCTION__));
goto fallback;
@@ -3121,9 +3122,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
assert_pixmap_contains_box(dst_pixmap,
RegionExtents(®ion));
sna_damage_add(&dst_priv->gpu_damage, ®ion);
- if (alu == GXcopy)
- sna_damage_subtract(&dst_priv->cpu_damage,
- ®ion);
RegionTranslate(®ion, -dst_dx, -dst_dy);
}
}
@@ -3152,9 +3150,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
assert_pixmap_contains_box(dst_pixmap,
RegionExtents(®ion));
sna_damage_add(&dst_priv->gpu_damage, ®ion);
- if (alu == GXcopy)
- sna_damage_subtract(&dst_priv->cpu_damage,
- ®ion);
RegionTranslate(®ion, -dst_dx, -dst_dy);
}
}
@@ -3262,8 +3257,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
RegionExtents(®ion));
sna_damage_add(&dst_priv->gpu_damage,
®ion);
- sna_damage_subtract(&dst_priv->cpu_damage,
- ®ion);
RegionTranslate(®ion, -dst_dx, -dst_dy);
}
}
More information about the xorg-commit
mailing list