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_render.c
Chris Wilson
ickle at kemper.freedesktop.org
Thu Dec 8 04:37:33 PST 2011
src/sna/gen2_render.c | 108 ++++++++++++++++++++++++++++++++++++++++++--
src/sna/gen3_render.c | 114 ++++++++++++++++++++++++++++++++++++++++++-----
src/sna/gen4_render.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++--
src/sna/gen5_render.c | 109 +++++++++++++++++++++++++++++++++++++++++++++
src/sna/gen6_render.c | 109 +++++++++++++++++++++++++++++++++++++++++++++
src/sna/gen7_render.c | 109 +++++++++++++++++++++++++++++++++++++++++++++
src/sna/sna_accel.c | 2
src/sna/sna_render.c | 6 +-
8 files changed, 656 insertions(+), 22 deletions(-)
New commits:
commit 84aaf1537cbd29e163346d03debc39f4623c69eb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 8 12:36:08 2011 +0000
sna/gen7: Reduce dst readbacks for unsupported sources
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 3159da3..68ec221 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2202,6 +2202,109 @@ try_blt(struct sna *sna, int width, int height)
return FALSE;
}
+static bool
+is_solid(PicturePtr picture)
+{
+ return picture->pDrawable->width == 1 &&
+ picture->pDrawable->height == 1 &&
+ picture->repeat;
+}
+
+static bool
+is_gradient(PicturePtr picture)
+{
+ if (picture->pDrawable)
+ return FALSE;
+
+ return picture->pSourcePict->type != SourcePictTypeSolidFill;
+}
+
+static bool
+source_fallback(PicturePtr p)
+{
+ return is_gradient(p) || !gen7_check_filter(p) || !gen7_check_repeat(p);
+}
+
+static bool
+gen7_composite_fallback(struct sna *sna,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst)
+{
+ struct sna_pixmap *priv;
+ PixmapPtr src_pixmap;
+ PixmapPtr mask_pixmap;
+ PixmapPtr dst_pixmap;
+
+ if (!gen7_check_dst_format(dst->format)) {
+ DBG(("%s: unknown destination format: %d\n",
+ __FUNCTION__, dst->format));
+ return TRUE;
+ }
+
+ dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
+ mask_pixmap = (mask && mask->pDrawable) ? get_drawable_pixmap(mask->pDrawable) : NULL;
+
+ /* If we are using the destination as a source and need to
+ * readback in order to upload the source, do it all
+ * on the cpu.
+ */
+ if (src_pixmap == dst_pixmap && source_fallback(src)) {
+ DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+ if (mask_pixmap == dst_pixmap && source_fallback(mask)) {
+ DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+
+ /* If anything is on the GPU, push everything out to the GPU */
+ priv = sna_pixmap(dst_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: dst is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+
+ if (src_pixmap && !is_solid(src) && !source_fallback(src)) {
+ priv = sna_pixmap(src_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: src is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+ if (mask_pixmap && !is_solid(mask) && !source_fallback(mask)) {
+ priv = sna_pixmap(mask_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: mask is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+
+ /* However if the dst is not on the GPU and we need to
+ * render one of the sources using the CPU, we may
+ * as well do the entire operation in place onthe CPU.
+ */
+ if (source_fallback(src)) {
+ DBG(("%s: dst is on the CPU and src will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ if (mask && source_fallback(mask)) {
+ DBG(("%s: dst is on the CPU and mask will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
+ __FUNCTION__));
+ return FALSE;
+}
+
static Bool
gen7_render_composite(struct sna *sna,
uint8_t op,
@@ -2240,6 +2343,9 @@ gen7_render_composite(struct sna *sna,
width, height, tmp))
return TRUE;
+ if (gen7_composite_fallback(sna, src, mask, dst))
+ return FALSE;
+
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
src_x, src_y,
@@ -2603,6 +2709,9 @@ gen7_render_composite_spans(struct sna *sna,
if (need_tiling(sna, width, height))
return FALSE;
+ if (gen7_composite_fallback(sna, src, NULL, dst))
+ return FALSE;
+
tmp->base.op = op;
if (!gen7_composite_set_target(&tmp->base, dst))
return FALSE;
commit 440ac68ec074e82818713773f3e2cb5d363862aa
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 8 12:35:54 2011 +0000
sna/gen6: Reduce dst readbacks for unsupported sources
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 5a889e7..cb62463 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2081,6 +2081,109 @@ try_blt(struct sna *sna, int width, int height)
return FALSE;
}
+static bool
+is_solid(PicturePtr picture)
+{
+ return picture->pDrawable->width == 1 &&
+ picture->pDrawable->height == 1 &&
+ picture->repeat;
+}
+
+static bool
+is_gradient(PicturePtr picture)
+{
+ if (picture->pDrawable)
+ return FALSE;
+
+ return picture->pSourcePict->type != SourcePictTypeSolidFill;
+}
+
+static bool
+source_fallback(PicturePtr p)
+{
+ return is_gradient(p) || !gen6_check_filter(p) || !gen6_check_repeat(p);
+}
+
+static bool
+gen6_composite_fallback(struct sna *sna,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst)
+{
+ struct sna_pixmap *priv;
+ PixmapPtr src_pixmap;
+ PixmapPtr mask_pixmap;
+ PixmapPtr dst_pixmap;
+
+ if (!gen6_check_dst_format(dst->format)) {
+ DBG(("%s: unknown destination format: %d\n",
+ __FUNCTION__, dst->format));
+ return TRUE;
+ }
+
+ dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
+ mask_pixmap = (mask && mask->pDrawable) ? get_drawable_pixmap(mask->pDrawable) : NULL;
+
+ /* If we are using the destination as a source and need to
+ * readback in order to upload the source, do it all
+ * on the cpu.
+ */
+ if (src_pixmap == dst_pixmap && source_fallback(src)) {
+ DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+ if (mask_pixmap == dst_pixmap && source_fallback(mask)) {
+ DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+
+ /* If anything is on the GPU, push everything out to the GPU */
+ priv = sna_pixmap(dst_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: dst is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+
+ if (src_pixmap && !is_solid(src) && !source_fallback(src)) {
+ priv = sna_pixmap(src_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: src is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+ if (mask_pixmap && !is_solid(mask) && !source_fallback(mask)) {
+ priv = sna_pixmap(mask_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: mask is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+
+ /* However if the dst is not on the GPU and we need to
+ * render one of the sources using the CPU, we may
+ * as well do the entire operation in place onthe CPU.
+ */
+ if (source_fallback(src)) {
+ DBG(("%s: dst is on the CPU and src will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ if (mask && source_fallback(mask)) {
+ DBG(("%s: dst is on the CPU and mask will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
+ __FUNCTION__));
+ return FALSE;
+}
+
static Bool
gen6_render_composite(struct sna *sna,
uint8_t op,
@@ -2119,6 +2222,9 @@ gen6_render_composite(struct sna *sna,
width, height, tmp))
return TRUE;
+ if (gen6_composite_fallback(sna, src, mask, dst))
+ return FALSE;
+
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
src_x, src_y,
@@ -2482,6 +2588,9 @@ gen6_render_composite_spans(struct sna *sna,
if (need_tiling(sna, width, height))
return FALSE;
+ if (gen6_composite_fallback(sna, src, NULL, dst))
+ return FALSE;
+
tmp->base.op = op;
if (!gen6_composite_set_target(&tmp->base, dst))
return FALSE;
commit bc68211d18356c4a0e011ac360665d600de9fa30
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 8 12:35:39 2011 +0000
sna/gen5: Reduce dst readbacks for unsupported sources
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 8b683a8..e8a9606 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1921,6 +1921,109 @@ try_blt(struct sna *sna, PicturePtr source, int width, int height)
return picture_is_cpu(source);
}
+static bool
+is_solid(PicturePtr picture)
+{
+ return picture->pDrawable->width == 1 &&
+ picture->pDrawable->height == 1 &&
+ picture->repeat;
+}
+
+static bool
+is_gradient(PicturePtr picture)
+{
+ if (picture->pDrawable)
+ return FALSE;
+
+ return picture->pSourcePict->type != SourcePictTypeSolidFill;
+}
+
+static bool
+source_fallback(PicturePtr p)
+{
+ return is_gradient(p) || !gen5_check_filter(p) || !gen5_check_repeat(p);
+}
+
+static bool
+gen5_composite_fallback(struct sna *sna,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst)
+{
+ struct sna_pixmap *priv;
+ PixmapPtr src_pixmap;
+ PixmapPtr mask_pixmap;
+ PixmapPtr dst_pixmap;
+
+ if (!gen5_check_dst_format(dst->format)) {
+ DBG(("%s: unknown destination format: %d\n",
+ __FUNCTION__, dst->format));
+ return TRUE;
+ }
+
+ dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
+ mask_pixmap = (mask && mask->pDrawable) ? get_drawable_pixmap(mask->pDrawable) : NULL;
+
+ /* If we are using the destination as a source and need to
+ * readback in order to upload the source, do it all
+ * on the cpu.
+ */
+ if (src_pixmap == dst_pixmap && source_fallback(src)) {
+ DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+ if (mask_pixmap == dst_pixmap && source_fallback(mask)) {
+ DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+
+ /* If anything is on the GPU, push everything out to the GPU */
+ priv = sna_pixmap(dst_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: dst is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+
+ if (src_pixmap && !is_solid(src) && !source_fallback(src)) {
+ priv = sna_pixmap(src_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: src is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+ if (mask_pixmap && !is_solid(mask) && !source_fallback(mask)) {
+ priv = sna_pixmap(mask_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: mask is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+
+ /* However if the dst is not on the GPU and we need to
+ * render one of the sources using the CPU, we may
+ * as well do the entire operation in place onthe CPU.
+ */
+ if (source_fallback(src)) {
+ DBG(("%s: dst is on the CPU and src will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ if (mask && source_fallback(mask)) {
+ DBG(("%s: dst is on the CPU and mask will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
+ __FUNCTION__));
+ return FALSE;
+}
+
static Bool
gen5_render_composite(struct sna *sna,
uint8_t op,
@@ -1950,6 +2053,9 @@ gen5_render_composite(struct sna *sna,
width, height, tmp))
return TRUE;
+ if (gen5_composite_fallback(sna, src, mask, dst))
+ return FALSE;
+
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
src_x, src_y,
@@ -2312,6 +2418,9 @@ gen5_render_composite_spans(struct sna *sna,
if (need_tiling(sna, width, height))
return FALSE;
+ if (gen5_composite_fallback(sna, src, NULL, dst))
+ return FALSE;
+
tmp->base.op = op;
if (!gen5_composite_set_target(dst, &tmp->base))
return FALSE;
commit a5df7c28e458c2f2b173fe5d745f447087eb8c6f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 8 12:35:22 2011 +0000
sna/gen4: Reduce dst readbacks for unsupported sources
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 5e9bd37..73f659f 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -585,6 +585,7 @@ static uint32_t gen4_check_filter(PicturePtr picture)
case PictFilterBilinear:
return TRUE;
default:
+ DBG(("%s: unknown filter: %d\n", __FUNCTION__, picture->filter));
return FALSE;
}
}
@@ -617,6 +618,8 @@ static bool gen4_check_repeat(PicturePtr picture)
case RepeatReflect:
return TRUE;
default:
+ DBG(("%s: unknown repeat: %d\n",
+ __FUNCTION__, picture->repeatType));
return FALSE;
}
}
@@ -1735,17 +1738,23 @@ gen4_composite_picture(struct sna *sna,
if (sna_picture_is_solid(picture, &color))
return gen4_composite_solid_init(sna, channel, color);
- if (picture->pDrawable == NULL)
+ if (picture->pDrawable == NULL) {
+ DBG(("%s: procedural source fixup\n", __FUNCTION__));
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
+ }
- if (!gen4_check_repeat(picture))
+ if (!gen4_check_repeat(picture)) {
+ DBG(("%s: unknown repeat mode fixup\n", __FUNCTION__));
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
+ }
- if (!gen4_check_filter(picture))
+ if (!gen4_check_filter(picture)) {
+ DBG(("%s: unhandled filter fixup\n", __FUNCTION__));
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
+ }
channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
channel->filter = picture->filter;
@@ -1884,6 +1893,109 @@ try_blt(struct sna *sna,
return picture_is_cpu(source);
}
+static bool
+is_solid(PicturePtr picture)
+{
+ return picture->pDrawable->width == 1 &&
+ picture->pDrawable->height == 1 &&
+ picture->repeat;
+}
+
+static bool
+is_gradient(PicturePtr picture)
+{
+ if (picture->pDrawable)
+ return FALSE;
+
+ return picture->pSourcePict->type != SourcePictTypeSolidFill;
+}
+
+static bool
+source_fallback(PicturePtr p)
+{
+ return is_gradient(p) || !gen4_check_filter(p) || !gen4_check_repeat(p);
+}
+
+static bool
+gen4_composite_fallback(struct sna *sna,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst)
+{
+ struct sna_pixmap *priv;
+ PixmapPtr src_pixmap;
+ PixmapPtr mask_pixmap;
+ PixmapPtr dst_pixmap;
+
+ if (!gen4_check_dst_format(dst->format)) {
+ DBG(("%s: unknown destination format: %d\n",
+ __FUNCTION__, dst->format));
+ return TRUE;
+ }
+
+ dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
+ mask_pixmap = (mask && mask->pDrawable) ? get_drawable_pixmap(mask->pDrawable) : NULL;
+
+ /* If we are using the destination as a source and need to
+ * readback in order to upload the source, do it all
+ * on the cpu.
+ */
+ if (src_pixmap == dst_pixmap && source_fallback(src)) {
+ DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+ if (mask_pixmap == dst_pixmap && source_fallback(mask)) {
+ DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+
+ /* If anything is on the GPU, push everything out to the GPU */
+ priv = sna_pixmap(dst_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: dst is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+
+ if (src_pixmap && !is_solid(src) && !source_fallback(src)) {
+ priv = sna_pixmap(src_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: src is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+ if (mask_pixmap && !is_solid(mask) && !source_fallback(mask)) {
+ priv = sna_pixmap(mask_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: mask is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+
+ /* However if the dst is not on the GPU and we need to
+ * render one of the sources using the CPU, we may
+ * as well do the entire operation in place onthe CPU.
+ */
+ if (source_fallback(src)) {
+ DBG(("%s: dst is on the CPU and src will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ if (mask && source_fallback(mask)) {
+ DBG(("%s: dst is on the CPU and mask will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
+ __FUNCTION__));
+ return FALSE;
+}
+
static Bool
gen4_render_composite(struct sna *sna,
uint8_t op,
@@ -1922,6 +2034,9 @@ gen4_render_composite(struct sna *sna,
width, height, tmp))
return TRUE;
+ if (gen4_composite_fallback(sna, src, mask, dst))
+ return FALSE;
+
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
src_x, src_y,
commit cc8cab649c0a4788803d2c62f186142ec7152b89
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 8 12:34:58 2011 +0000
sna/gen3: Reduce readbacks on dst for unsupported sources
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 d23f422..ea9d40a 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -305,9 +305,12 @@ static uint32_t gen3_gradient_repeat(uint32_t repeat)
#undef REPEAT
}
-static Bool gen3_check_repeat(uint32_t repeat)
+static Bool gen3_check_repeat(PicturePtr p)
{
- switch (repeat) {
+ if (!p->repeat)
+ return TRUE;
+
+ switch (p->repeatType) {
case RepeatNone:
case RepeatNormal:
case RepeatPad:
@@ -2074,7 +2077,7 @@ gen3_composite_picture(struct sna *sna,
if (sna_picture_is_solid(picture, &color))
return gen3_init_solid(channel, color);
- if (!gen3_check_repeat(picture->repeat))
+ if (!gen3_check_repeat(picture))
return sna_render_picture_fixup(sna, picture, channel,
x, y, w, h, dst_x, dst_y);
@@ -2225,6 +2228,101 @@ static inline bool is_constant_ps(uint32_t type)
}
}
+
+static bool
+is_solid(PicturePtr picture)
+{
+ return picture->pDrawable->width == 1 &&
+ picture->pDrawable->height == 1 &&
+ picture->repeat;
+}
+
+static bool
+source_fallback(PicturePtr p)
+{
+ return !gen3_check_filter(p->filter) || !gen3_check_repeat(p);
+}
+
+static bool
+gen3_composite_fallback(struct sna *sna,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst)
+{
+ struct sna_pixmap *priv;
+ PixmapPtr src_pixmap;
+ PixmapPtr mask_pixmap;
+ PixmapPtr dst_pixmap;
+
+ if (!gen3_check_dst_format(dst->format)) {
+ DBG(("%s: unknown destination format: %d\n",
+ __FUNCTION__, dst->format));
+ return TRUE;
+ }
+
+ dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
+ mask_pixmap = (mask && mask->pDrawable) ? get_drawable_pixmap(mask->pDrawable) : NULL;
+
+ /* If we are using the destination as a source and need to
+ * readback in order to upload the source, do it all
+ * on the cpu.
+ */
+ if (src_pixmap == dst_pixmap && source_fallback(src)) {
+ DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+ if (mask_pixmap == dst_pixmap && source_fallback(mask)) {
+ DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+
+ /* If anything is on the GPU, push everything out to the GPU */
+ priv = sna_pixmap(dst_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: dst is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+
+ if (src_pixmap && !is_solid(src) && !source_fallback(src)) {
+ priv = sna_pixmap(src_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: src is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+ if (mask_pixmap && !is_solid(mask) && !source_fallback(mask)) {
+ priv = sna_pixmap(mask_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: mask is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+
+ /* However if the dst is not on the GPU and we need to
+ * render one of the sources using the CPU, we may
+ * as well do the entire operation in place onthe CPU.
+ */
+ if (source_fallback(src)) {
+ DBG(("%s: dst is on the CPU and src will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ if (mask && source_fallback(mask)) {
+ DBG(("%s: dst is on the CPU and mask will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
+ __FUNCTION__));
+ return FALSE;
+}
+
static Bool
gen3_render_composite(struct sna *sna,
uint8_t op,
@@ -2269,11 +2367,8 @@ gen3_render_composite(struct sna *sna,
tmp))
return TRUE;
- if (!gen3_check_dst_format(dst->format)) {
- DBG(("%s: fallback due to unhandled dst format: %x\n",
- __FUNCTION__, dst->format));
+ if (gen3_composite_fallback(sna, src, mask, dst))
return FALSE;
- }
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
@@ -2812,11 +2907,8 @@ gen3_render_composite_spans(struct sna *sna,
return FALSE;
}
- if (!gen3_check_dst_format(dst->format)) {
- DBG(("%s: fallback due to unhandled dst format: %x\n",
- __FUNCTION__, dst->format));
+ if (gen3_composite_fallback(sna, src, NULL, dst))
return FALSE;
- }
if (need_tiling(sna, width, height))
return FALSE;
commit e5bc0c823b8fd46b3f851c5e9a4b4de39cda9a91
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 8 12:34:34 2011 +0000
sna/gen2: Avoid readbacks for unsupported sources
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 e97e2d7..d35f2da 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1238,6 +1238,109 @@ try_blt(struct sna *sna,
return is_cpu(source->pDrawable);
}
+static bool
+is_solid(PicturePtr picture)
+{
+ return picture->pDrawable->width == 1 &&
+ picture->pDrawable->height == 1 &&
+ picture->repeat;
+}
+
+static bool
+is_gradient(PicturePtr picture)
+{
+ if (picture->pDrawable)
+ return FALSE;
+
+ return picture->pSourcePict->type != SourcePictTypeSolidFill;
+}
+
+static bool
+source_fallback(PicturePtr p)
+{
+ return is_gradient(p) || !gen2_check_filter(p) || !gen2_check_repeat(p);
+}
+
+static bool
+gen2_composite_fallback(struct sna *sna,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst)
+{
+ struct sna_pixmap *priv;
+ PixmapPtr src_pixmap;
+ PixmapPtr mask_pixmap;
+ PixmapPtr dst_pixmap;
+
+ if (!gen2_check_dst_format(dst->format)) {
+ DBG(("%s: unknown destination format: %d\n",
+ __FUNCTION__, dst->format));
+ return TRUE;
+ }
+
+ dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
+ mask_pixmap = (mask && mask->pDrawable) ? get_drawable_pixmap(mask->pDrawable) : NULL;
+
+ /* If we are using the destination as a source and need to
+ * readback in order to upload the source, do it all
+ * on the cpu.
+ */
+ if (src_pixmap == dst_pixmap && source_fallback(src)) {
+ DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+ if (mask_pixmap == dst_pixmap && source_fallback(mask)) {
+ DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
+ return TRUE;
+ }
+
+ /* If anything is on the GPU, push everything out to the GPU */
+ priv = sna_pixmap(dst_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: dst is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+
+ if (src_pixmap && !is_solid(src) && !source_fallback(src)) {
+ priv = sna_pixmap(src_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: src is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+ if (mask_pixmap && !is_solid(mask) && !source_fallback(mask)) {
+ priv = sna_pixmap(mask_pixmap);
+ if (priv && priv->gpu_damage) {
+ DBG(("%s: mask is already on the GPU, try to use GPU\n",
+ __FUNCTION__));
+ return FALSE;
+ }
+ }
+
+ /* However if the dst is not on the GPU and we need to
+ * render one of the sources using the CPU, we may
+ * as well do the entire operation in place onthe CPU.
+ */
+ if (source_fallback(src)) {
+ DBG(("%s: dst is on the CPU and src will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ if (mask && source_fallback(mask)) {
+ DBG(("%s: dst is on the CPU and mask will fallback\n",
+ __FUNCTION__));
+ return TRUE;
+ }
+
+ DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
+ __FUNCTION__));
+ return FALSE;
+}
+
static Bool
gen2_render_composite(struct sna *sna,
uint8_t op,
@@ -1282,11 +1385,8 @@ gen2_render_composite(struct sna *sna,
tmp))
return TRUE;
- if (!gen2_check_dst_format(dst->format)) {
- DBG(("%s: fallback due to unhandled dst format: %x\n",
- __FUNCTION__, dst->format));
+ if (gen2_composite_fallback(sna, src, mask, dst))
return FALSE;
- }
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
commit 874c722c86b06ac0aa10e6943d3faf76fcb751be
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Dec 8 12:07:28 2011 +0000
sna: Beware flushing partial buffers before they are written
A partial buffer is considered finished upon the next batch submission,
so one needs to be careful that it is completely written to before such
an event is triggered. move-to-cpu is such a trigger as demonstrated by
the picture fixup routine for handling convolution filters.
Reported-by: Victor Machado <machado.prx at gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=43607
Signed-off-by: Chris Wilson <ickle at crestline.(none)>
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index cf227c6..13c0526 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -900,6 +900,9 @@ sna_render_picture_fixup(struct sna *sna,
__FUNCTION__, channel->pict_format, pitch, picture->format));
}
+ if (picture->pDrawable)
+ sna_drawable_move_to_cpu(picture->pDrawable, false);
+
channel->bo = kgem_create_buffer(&sna->kgem,
pitch*h, KGEM_BUFFER_WRITE,
&ptr);
@@ -923,9 +926,6 @@ sna_render_picture_fixup(struct sna *sna,
return 0;
}
- if (picture->pDrawable)
- sna_drawable_move_to_cpu(picture->pDrawable, false);
-
src = image_from_pict(picture, FALSE, &dx, &dy);
if (src == NULL) {
pixman_image_unref(dst);
commit 6ccb114a7e685c69fb388ebd119393455b315c36
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Dec 7 21:09:31 2011 +0000
sna: Prefer to use our pixmap upload paths
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 c467f74..e1905d1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1385,7 +1385,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
int16_t dx, dy;
int n;
- if (!priv->gpu_bo)
+ if (!priv)
return false;
if (priv->gpu_only)
More information about the xorg-commit
mailing list