xf86-video-intel: 8 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/sna_accel.c src/sna/sna_composite.c src/sna/sna_glyphs.c src/sna/sna_render.c src/sna/sna_render_inline.h src/sna/sna_trapezoids.c
Chris Wilson
ickle at kemper.freedesktop.org
Thu Dec 22 09:36:50 PST 2011
src/sna/gen2_render.c | 14 +++
src/sna/gen3_render.c | 14 +++
src/sna/gen4_render.c | 14 +++
src/sna/gen5_render.c | 14 +++
src/sna/gen6_render.c | 14 +++
src/sna/gen7_render.c | 14 +++
src/sna/sna_accel.c | 50 +++++++++---
src/sna/sna_composite.c | 16 +++
src/sna/sna_glyphs.c | 4
src/sna/sna_render.c | 181 ++++++++++++++++++++++++++++++++++++++++++++
src/sna/sna_render_inline.h | 10 ++
src/sna/sna_trapezoids.c | 9 --
12 files changed, 327 insertions(+), 27 deletions(-)
New commits:
commit 609e1d9da282323ab7abc1baad4d3f24ac55588f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 22 15:54:39 2011 +0000
sna: Bump the inactivity timeout
With the goal of removing inactive pixmap froms the GPU after 5 minutes
of idleness.
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 8756fab..8a2ff9a 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -8970,8 +8970,8 @@ static Bool sna_accel_do_inactive(struct sna *sna)
if (sna->timer[INACTIVE_TIMER] == -1)
return FALSE;
- /* Periodic expiration after every 60s. */
- to.it_interval.tv_sec = 60;
+ /* Periodic expiration after every 2 minutes. */
+ to.it_interval.tv_sec = 120;
to.it_interval.tv_nsec = 0;
to.it_value = to.it_interval;
timerfd_settime(sna->timer[INACTIVE_TIMER], 0, &to, NULL);
commit 62602209e54c3568795122ee1c902c3b81985303
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 22 14:20:20 2011 +0000
sna: discard damage-all even for width|height==0 operations
Even if we don't know the extents of the render operation, if the entire
pixmap is damaged we can still reduce the damage tracking.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index 758833e..58eced0 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -139,7 +139,15 @@ sna_render_reduce_damage(struct sna_composite_op *op,
{
BoxRec r;
- if (width == 0 || height == 0 || op->damage == NULL)
+ if (op->damage == NULL || *op->damage == NULL)
+ return;
+
+ if ((*op->damage)->mode == DAMAGE_ALL) {
+ op->damage = NULL;
+ return;
+ }
+
+ if (width == 0 || height == 0)
return;
r.x1 = dst_x + op->dst.x;
commit f68a99a55e1e63d7e76a13a7b77b4bb3f7802b9e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 22 15:04:22 2011 +0000
sna: Mark fresh GPU only bo as being all damaged
Presume that we will not fallback and so treat a GPU only bo (one that
is initially created on the GPU) as being all-damaged. This makes future
operations cheaper as the damage tracking overhead is much reduced, and
the cost of the first readback will mainly be in the synchronisation
overhead.
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 27fd354..8756fab 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1347,6 +1347,18 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap)
assert(list_is_empty(&priv->list));
return NULL;
}
+
+ if (priv->cpu_damage == NULL) {
+ /* Presume that we will only ever write to the GPU
+ * bo. Readbacks are expensive but fairly constant
+ * in cost for all sizes i.e. it is the act of
+ * synchronisation that takes the most time. This is
+ * mitigated by avoiding fallbacks in the first place.
+ */
+ sna_damage_all(&priv->gpu_damage,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
+ }
}
if (priv->cpu_damage == NULL)
commit 1f2cd536bc712843233de3f5c50802c388d63c72
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 22 14:30:04 2011 +0000
sna: Reduce damage after complete solid fills
RenderFillRectangles is often used to initially clear a pixmap after
creation by flooding it with a solid colour, as is PolyRect. We can
reduce further damage operations by checking for this condition.
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 e899760..27fd354 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -6283,7 +6283,13 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
gc->alu)) {
if (damage) {
assert_pixmap_contains_box(pixmap, &r);
- sna_damage_add_box(damage, &r);
+ if (r.x2 - r.x1 == pixmap->drawable.width &&
+ r.y2 - r.y1 == pixmap->drawable.height)
+ sna_damage_all(damage,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
+ else
+ sna_damage_add_box(damage, &r);
}
} else
success = false;
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 7adbbfb..98bf871 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -742,7 +742,17 @@ sna_composite_rectangles(CARD8 op,
}
assert_pixmap_contains_box(pixmap, RegionExtents(®ion));
- sna_damage_add(&priv->gpu_damage, ®ion);
+
+ /* Clearing a pixmap after creation is a common operation, so take
+ * advantage and reduce further damage operations.
+ */
+ if (region.data == NULL &&
+ region.extents.x2 - region.extents.x1 == pixmap->drawable.width &&
+ region.extents.y2 - region.extents.y1 == pixmap->drawable.height)
+ sna_damage_all(&priv->gpu_damage,
+ pixmap->drawable.width, pixmap->drawable.height);
+ else
+ sna_damage_add(&priv->gpu_damage, ®ion);
goto done;
@@ -759,7 +769,7 @@ fallback:
!sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, error))
goto done;
- if (op == PictOpSrc || op == PictOpClear) {
+ if (op <= PictOpSrc) {
int nbox = REGION_NUM_RECTS(®ion);
BoxPtr box = REGION_RECTS(®ion);
uint32_t pixel;
commit 7a6a2c5d4cc98da76c73152cb7eafcbdb0c088ec
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 22 13:24:07 2011 +0000
sna: Setup the pixmap correctly in order to attach our private
During creation of sna_pixmap we validate that we can use a GPU bo with
the target pixmap. This fails if we pass in a raw pixmap header, so
make sure the scratch pixmap is fully initialised first.
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 b3fc05b..e899760 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -508,9 +508,14 @@ sna_pixmap_create_scratch(ScreenPtr screen,
sna->freed_pixmap = NULL;
pixmap->usage_hint = CREATE_PIXMAP_USAGE_SCRATCH;
- pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pixmap->refcnt = 1;
+ pixmap->drawable.width = width;
+ pixmap->drawable.height = height;
+ pixmap->drawable.depth = depth;
+ pixmap->drawable.bitsPerPixel = bpp;
+ pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
priv = _sna_pixmap_reset(pixmap);
} else {
pixmap = create_pixmap(sna, screen, 0, 0, depth,
@@ -518,6 +523,11 @@ sna_pixmap_create_scratch(ScreenPtr screen,
if (pixmap == NullPixmap)
return NullPixmap;
+ pixmap->drawable.width = width;
+ pixmap->drawable.height = height;
+ pixmap->drawable.depth = depth;
+ pixmap->drawable.bitsPerPixel = bpp;
+
priv = _sna_pixmap_attach(sna, pixmap);
if (!priv) {
fbDestroyPixmap(pixmap);
@@ -525,6 +535,9 @@ sna_pixmap_create_scratch(ScreenPtr screen,
}
}
+ pixmap->devKind = PixmapBytePad(width, depth);
+ pixmap->devPrivate.ptr = NULL;
+
priv->gpu_bo = kgem_create_2d(&sna->kgem,
width, height, bpp, tiling,
0);
@@ -537,12 +550,6 @@ sna_pixmap_create_scratch(ScreenPtr screen,
priv->header = true;
sna_damage_all(&priv->gpu_damage, width, height);
- pixmap->drawable.width = width;
- pixmap->drawable.height = height;
- pixmap->drawable.depth = depth;
- pixmap->drawable.bitsPerPixel = bpp;
- pixmap->devKind = PixmapBytePad(width, depth);
- pixmap->devPrivate.ptr = NULL;
return pixmap;
}
commit f621b3de841f6037d387ca1439a0abe12ef29811
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 22 11:19:45 2011 +0000
sna: flatten source alphamaps
Replace the source picture+alpha with a bo that contains the RGB
channels from source and A from the alpha map.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 53accbd..519ba18 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1155,6 +1155,12 @@ gen2_composite_picture(struct sna *sna,
x, y, w, h, dst_x, dst_y);
}
+ if (picture->alphaMap) {
+ DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h, dst_x, dst_y);
+ }
+
if (!gen2_check_repeat(picture)) {
DBG(("%s -- fallback, unhandled repeat %d\n",
__FUNCTION__, picture->repeat));
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 1dec2b3..12eebaa 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2099,6 +2099,12 @@ gen3_composite_picture(struct sna *sna,
return ret;
}
+ if (picture->alphaMap) {
+ DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h, dst_x, dst_y);
+ }
+
if (sna_picture_is_solid(picture, &color))
return gen3_init_solid(channel, color);
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 150b7c8..6ccddd2 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1745,6 +1745,12 @@ gen4_composite_picture(struct sna *sna,
x, y, w, h, dst_x, dst_y);
}
+ if (picture->alphaMap) {
+ DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h, dst_x, dst_y);
+ }
+
if (!gen4_check_repeat(picture)) {
DBG(("%s: unknown repeat mode fixup\n", __FUNCTION__));
return sna_render_picture_fixup(sna, picture, channel,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index e1117cc..180b561 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1785,6 +1785,12 @@ gen5_composite_picture(struct sna *sna,
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
+ if (picture->alphaMap) {
+ DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h, dst_x, dst_y);
+ }
+
if (!gen5_check_repeat(picture))
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 7d48137..8e7ea15 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -1962,6 +1962,12 @@ gen6_composite_picture(struct sna *sna,
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
+ if (picture->alphaMap) {
+ DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h, dst_x, dst_y);
+ }
+
if (!gen6_check_repeat(picture))
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 885a5dc..58647f7 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2075,6 +2075,12 @@ gen7_composite_picture(struct sna *sna,
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
+ if (picture->alphaMap) {
+ DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
+ return sna_render_picture_fixup(sna, picture, channel,
+ x, y, w, h, dst_x, dst_y);
+ }
+
if (!gen7_check_repeat(picture))
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index fcc0070..7adbbfb 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -437,7 +437,7 @@ sna_composite(CARD8 op,
goto fallback;
}
- if (dst->alphaMap || src->alphaMap || (mask && mask->alphaMap)) {
+ if (dst->alphaMap) {
DBG(("%s: fallback due to unhandled alpha-map\n", __FUNCTION__));
goto fallback;
}
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 4fd4752..811b866 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -1225,8 +1225,8 @@ sna_glyphs(CARD8 op,
goto fallback;
}
- if (dst->alphaMap || src->alphaMap) {
- DBG(("%s: fallback -- alpha maps\n", __FUNCTION__));
+ if (dst->alphaMap) {
+ DBG(("%s: fallback -- dst alpha map\n", __FUNCTION__));
goto fallback;
}
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 72b3f78..89d1d81 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1014,6 +1014,73 @@ sna_render_picture_convolve(struct sna *sna,
return 1;
}
+static int
+sna_render_picture_flatten(struct sna *sna,
+ PicturePtr picture,
+ struct sna_composite_channel *channel,
+ int16_t x, int16_t y,
+ int16_t w, int16_t h,
+ int16_t dst_x, int16_t dst_y)
+{
+ ScreenPtr screen = picture->pDrawable->pScreen;
+ PixmapPtr pixmap;
+ PicturePtr tmp, alpha;
+ int old_format, error;
+
+ assert(picture->pDrawable);
+ assert(picture->alphaMap);
+ assert(w <= sna->render.max_3d_size && h <= sna->render.max_3d_size);
+
+ /* XXX shortcut a8? */
+
+ pixmap = screen->CreatePixmap(screen, w, h, 32, SNA_CREATE_SCRATCH);
+ if (pixmap == NullPixmap)
+ return 0;
+
+ tmp = CreatePicture(0, &pixmap->drawable,
+ PictureMatchFormat(screen, 32, PICT_a8r8g8b8),
+ 0, NULL, serverClient, &error);
+ screen->DestroyPixmap(pixmap);
+ if (tmp == NULL)
+ return 0;
+
+ old_format = picture->format;
+ picture->format = PICT_FORMAT(PICT_FORMAT_BPP(picture->format),
+ PICT_FORMAT_TYPE(picture->format),
+ 0,
+ PICT_FORMAT_R(picture->format),
+ PICT_FORMAT_G(picture->format),
+ PICT_FORMAT_B(picture->format));
+
+ alpha = picture->alphaMap;
+ picture->alphaMap = NULL;
+
+ sna_composite(PictOpSrc, picture, alpha, tmp,
+ x, y,
+ x + picture->alphaOrigin.x, y + picture->alphaOrigin.y,
+ 0, 0,
+ w, h);
+
+ picture->format = old_format;
+ picture->alphaMap = alpha;
+
+ channel->height = h;
+ channel->width = w;
+ channel->filter = PictFilterNearest;
+ channel->repeat = RepeatNone;
+ channel->pict_format = PIXMAN_a8r8g8b8;
+ channel->is_affine = TRUE;
+ channel->transform = NULL;
+ channel->scale[0] = 1.f / w;
+ channel->scale[1] = 1.f / h;
+ channel->offset[0] = -dst_x;
+ channel->offset[1] = -dst_y;
+ channel->bo = kgem_bo_reference(sna_pixmap_get_bo(pixmap));
+ FreePicture(tmp, 0);
+
+ return 1;
+}
+
int
sna_render_picture_fixup(struct sna *sna,
PicturePtr picture,
@@ -1042,6 +1109,16 @@ sna_render_picture_fixup(struct sna *sna,
return -1;
}
+ if (picture->alphaMap) {
+ DBG(("%s: alphamap\n", __FUNCTION__));
+ if ((is_gpu(picture->pDrawable) || is_gpu(picture->alphaMap->pDrawable))) {
+ return sna_render_picture_flatten(sna, picture, channel,
+ x, y, w, y, dst_x, dst_y);
+ }
+
+ goto do_fixup;
+ }
+
if (picture->filter == PictFilterConvolution) {
DBG(("%s: convolution\n", __FUNCTION__));
if (picture->pDrawable && is_gpu(picture->pDrawable)) {
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 287f883..3837532 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -3094,8 +3094,8 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst,
__FUNCTION__));
return false;
}
- if (dst->alphaMap || src->alphaMap) {
- DBG(("%s: fallback -- alphamaps\n",
+ if (dst->alphaMap) {
+ DBG(("%s: fallback -- dst alphamap\n",
__FUNCTION__));
return false;
}
@@ -3374,9 +3374,8 @@ sna_composite_trapezoids(CARD8 op,
goto fallback;
}
- if (dst->alphaMap || src->alphaMap) {
- DBG(("%s: fallback -- alpha maps=(dst=%p, src=%p)\n",
- __FUNCTION__, dst->alphaMap, src->alphaMap));
+ if (dst->alphaMap) {
+ DBG(("%s: fallback -- dst alpha map\n", __FUNCTION__));
goto fallback;
}
commit 6c08eb4d6f8789e692ef018e007d1ae97a57c25f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 22 11:42:39 2011 +0000
sna/gen2+: Prefer to use the CPU if we have a source alphamap and CPU pictures
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index d10f03e..53accbd 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1304,9 +1304,15 @@ is_gradient(PicturePtr picture)
}
static bool
+has_alphamap(PicturePtr p)
+{
+ return p->alphaMap != NULL;
+}
+
+static bool
source_fallback(PicturePtr p)
{
- return is_gradient(p) || !gen2_check_filter(p) || !gen2_check_repeat(p);
+ return has_alphamap(p) || is_gradient(p) || !gen2_check_filter(p) || !gen2_check_repeat(p);
}
static bool
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 4ada863..1dec2b3 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2297,9 +2297,15 @@ is_solid(PicturePtr picture)
}
static bool
+has_alphamap(PicturePtr p)
+{
+ return p->alphaMap != NULL;
+}
+
+static bool
source_fallback(PicturePtr p)
{
- return !gen3_check_filter(p->filter) || !gen3_check_repeat(p);
+ return has_alphamap(p) || !gen3_check_filter(p->filter) || !gen3_check_repeat(p);
}
static bool
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index aec5ca0..150b7c8 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1911,9 +1911,15 @@ is_gradient(PicturePtr picture)
}
static bool
+has_alphamap(PicturePtr p)
+{
+ return p->alphaMap != NULL;
+}
+
+static bool
source_fallback(PicturePtr p)
{
- return is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p);
+ return has_alphamap(p) || is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p);
}
static bool
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 6d89ca3..e1117cc 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1953,9 +1953,15 @@ is_gradient(PicturePtr picture)
}
static bool
+has_alphamap(PicturePtr p)
+{
+ return p->alphaMap != NULL;
+}
+
+static bool
source_fallback(PicturePtr p)
{
- return is_gradient(p) || !gen5_check_filter(p) || !gen5_check_repeat(p);
+ return has_alphamap(p) || is_gradient(p) || !gen5_check_filter(p) || !gen5_check_repeat(p);
}
static bool
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index c276f7e..7d48137 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2128,9 +2128,15 @@ is_gradient(PicturePtr picture)
}
static bool
+has_alphamap(PicturePtr p)
+{
+ return p->alphaMap != NULL;
+}
+
+static bool
source_fallback(PicturePtr p)
{
- return is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p);
+ return has_alphamap(p) || is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p);
}
static bool
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index dc97d18..885a5dc 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2241,9 +2241,15 @@ is_gradient(PicturePtr picture)
}
static bool
+has_alphamap(PicturePtr p)
+{
+ return p->alphaMap != NULL;
+}
+
+static bool
source_fallback(PicturePtr p)
{
- return is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p);
+ return has_alphamap(p) || is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p);
}
static bool
commit 354dc3c65b9cb86885b6927ee2b80cd2ee6a82ff
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 21 21:35:06 2011 +0000
sna: Avoid fallbacks for convolutions by rendering the convolved texture
If we have no shader support for generic convolutions, we currently
create the convolved texture using pixman. A multipass accumulation
algorithm can be implemented on top of CompositePicture, so try it!
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 33a75c1..b3fc05b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -491,6 +491,11 @@ sna_pixmap_create_scratch(ScreenPtr screen,
if (tiling == I915_TILING_Y && !sna->have_render)
tiling = I915_TILING_X;
+ if (tiling == I915_TILING_Y &&
+ (width > sna->render.max_3d_size ||
+ height > sna->render.max_3d_size))
+ tiling = I915_TILING_X;
+
bpp = BitsPerPixel(depth);
tiling = kgem_choose_tiling(&sna->kgem, tiling, width, height, bpp);
if (!kgem_can_create_2d(&sna->kgem, width, height, bpp, tiling))
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 341cf2c..72b3f78 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -921,6 +921,99 @@ sna_render_picture_extract(struct sna *sna,
return 1;
}
+static int
+sna_render_picture_convolve(struct sna *sna,
+ PicturePtr picture,
+ struct sna_composite_channel *channel,
+ int16_t x, int16_t y,
+ int16_t w, int16_t h,
+ int16_t dst_x, int16_t dst_y)
+{
+ ScreenPtr screen = picture->pDrawable->pScreen;
+ PixmapPtr pixmap;
+ PicturePtr tmp;
+ pixman_fixed_t *params = picture->filter_params;
+ int x_off = (params[0] - pixman_fixed_1) >> 1;
+ int y_off = (params[1] - pixman_fixed_1) >> 1;
+ int cw = pixman_fixed_to_int(params[0]);
+ int ch = pixman_fixed_to_int(params[1]);
+ int i, j, error, depth;
+
+ /* Lame multi-pass accumulation implementation of a general convolution
+ * that works everywhere.
+ */
+
+ assert(picture->pDrawable);
+ assert(picture->filter == PictFilterConvolution);
+ assert(w <= sna->render.max_3d_size && h <= sna->render.max_3d_size);
+
+ if (PICT_FORMAT_RGB(picture->format) == 0) {
+ channel->pict_format = PIXMAN_a8;
+ depth = 8;
+ } else {
+ channel->pict_format = PIXMAN_a8r8g8b8;
+ depth = 32;
+ }
+
+ pixmap = screen->CreatePixmap(screen, w, h, depth, SNA_CREATE_SCRATCH);
+ if (pixmap == NullPixmap)
+ return 0;
+
+ tmp = CreatePicture(0, &pixmap->drawable,
+ PictureMatchFormat(screen, depth, channel->pict_format),
+ 0, NULL, serverClient, &error);
+ screen->DestroyPixmap(pixmap);
+ if (tmp == NULL)
+ return 0;
+
+ if (!sna->render.fill_one(sna, pixmap, sna_pixmap_get_bo(pixmap), 0,
+ 0, 0, w, h, GXclear)) {
+ FreePicture(tmp, 0);
+ return 0;
+ }
+
+ picture->filter = PictFilterBilinear;
+ params += 2;
+ for (j = 0; j < ch; j++) {
+ for (i = 0; i < cw; i++) {
+ xRenderColor color;
+ PicturePtr alpha;
+
+ color.alpha = *params++;
+ color.red = color.green = color.blue = 0;
+
+ if (color.alpha <= 0x00ff)
+ continue;
+
+ alpha = CreateSolidPicture(0, &color, &error);
+ if (alpha) {
+ sna_composite(PictOpAdd, picture, alpha, tmp,
+ x, y,
+ 0, 0,
+ x_off-i, y_off-j,
+ w, h);
+ FreePicture(alpha, 0);
+ }
+ }
+ }
+ picture->filter = PictFilterConvolution;
+
+ channel->height = h;
+ channel->width = w;
+ channel->filter = PictFilterNearest;
+ channel->repeat = RepeatNone;
+ channel->is_affine = TRUE;
+ channel->transform = NULL;
+ channel->scale[0] = 1.f / w;
+ channel->scale[1] = 1.f / h;
+ channel->offset[0] = -dst_x;
+ channel->offset[1] = -dst_y;
+ channel->bo = kgem_bo_reference(sna_pixmap_get_bo(pixmap));
+ FreePicture(tmp, 0);
+
+ return 1;
+}
+
int
sna_render_picture_fixup(struct sna *sna,
PicturePtr picture,
@@ -949,6 +1042,17 @@ sna_render_picture_fixup(struct sna *sna,
return -1;
}
+ if (picture->filter == PictFilterConvolution) {
+ DBG(("%s: convolution\n", __FUNCTION__));
+ if (picture->pDrawable && is_gpu(picture->pDrawable)) {
+ return sna_render_picture_convolve(sna, picture, channel,
+ x, y, w, y, dst_x, dst_y);
+ }
+
+ goto do_fixup;
+ }
+
+do_fixup:
if (PICT_FORMAT_RGB(picture->format) == 0) {
pitch = ALIGN(w, 4);
channel->pict_format = PIXMAN_a8;
More information about the xorg-commit
mailing list