summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-12 21:08:41 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-12 21:15:58 +0000
commit8d2f1eefe142b65db7d8821ba0f80fdb0902b2d5 (patch)
tree86b4739e1cc332823319a22dfdd55f720f3ff5ef
parent48ab72754d0069a3247c5fee8c353a6b593eaed9 (diff)
sna: Pass a hint that we may like to perform the fallback in place
If we do not read back from the destination, we may prefer to utilize a GTT mapping and perform the fallback inplace. For the rare event that we wish to fallback and do not already have a shadow... Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna.h1
-rw-r--r--src/sna/sna_accel.c121
2 files changed, 90 insertions, 32 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 07ae683b..09926add 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -442,6 +442,7 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling);
#define MOVE_WRITE 0x1
#define MOVE_READ 0x2
+#define MOVE_INPLACE_HINT 0x4
bool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags);
static inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags)
{
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c8a1e154..8aa30fcf 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -60,6 +60,7 @@
#define FORCE_FLUSH 0
#define USE_SPANS 0
+#define USE_INPLACE 1
#define USE_ZERO_SPANS 1
#define USE_BO_FOR_SCRATCH_PIXMAP 1
@@ -726,6 +727,9 @@ static inline bool pixmap_inplace(struct sna *sna,
sna->kgem.half_cpu_cache_pages;
}
+static bool
+sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box);
+
bool
_sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
{
@@ -741,6 +745,11 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
return true;
}
+ if (DAMAGE_IS_ALL(priv->cpu_damage)) {
+ DBG(("%s: all-damaged\n", __FUNCTION__));
+ goto done;
+ }
+
DBG(("%s: gpu_bo=%d, gpu_damage=%p\n",
__FUNCTION__,
priv->gpu_bo ? priv->gpu_bo->handle : 0,
@@ -890,7 +899,7 @@ region_subsumes_damage(const RegionRec *region, struct sna_damage *damage)
if (re->x2 < de->x2 || re->x1 > de->x1 ||
re->y2 < de->y2 || re->y1 > de->y1) {
- DBG(("%s: no overlap\n", __FUNCTION__));
+ DBG(("%s: not contained\n", __FUNCTION__));
return false;
}
@@ -1093,6 +1102,28 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
}
}
+ if (flags & MOVE_INPLACE_HINT &&
+ priv->stride && priv->gpu_bo &&
+ (DAMAGE_IS_ALL(priv->gpu_damage) ||
+ region_inplace(sna, pixmap, region, priv)) &&
+ sna_pixmap_move_area_to_gpu(pixmap, &region->extents)) {
+ kgem_bo_submit(&sna->kgem, priv->gpu_bo);
+
+ DBG(("%s: operate inplace\n", __FUNCTION__));
+
+ pixmap->devPrivate.ptr =
+ kgem_bo_map(&sna->kgem, priv->gpu_bo);
+ if (pixmap->devPrivate.ptr != NULL) {
+ priv->mapped = 1;
+ pixmap->devKind = priv->gpu_bo->pitch;
+ if (!DAMAGE_IS_ALL(priv->gpu_damage))
+ sna_damage_add(&priv->gpu_damage, region);
+ return true;
+ }
+
+ priv->mapped = 0;
+ }
+
if (priv->mapped) {
pixmap->devPrivate.ptr = NULL;
priv->mapped = 0;
@@ -1254,10 +1285,50 @@ done:
if (dx | dy)
RegionTranslate(region, -dx, -dy);
- priv->source_count = SOURCE_BIAS;
return true;
}
+static bool alu_overwrites(uint8_t alu)
+{
+ switch (alu) {
+ case GXclear:
+ case GXcopy:
+ case GXcopyInverted:
+ case GXset:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline static unsigned drawable_gc_flags(DrawablePtr draw, GCPtr gc)
+{
+ unsigned flags = MOVE_READ | MOVE_WRITE;
+
+ if (!USE_INPLACE)
+ return flags;
+
+ if (!alu_overwrites(gc->alu)) {
+ DBG(("%s: read due to alu %d\n", __FUNCTION__, gc->alu));
+ return flags;
+ }
+
+ if (!PM_IS_SOLID(draw, gc->planemask)) {
+ DBG(("%s: read due to planemask %lx\n",
+ __FUNCTION__, gc->planemask));
+ return flags;
+ }
+
+ if (gc->fillStyle == FillStippled) {
+ DBG(("%s: read due to fill %d\n",
+ __FUNCTION__, gc->fillStyle));
+ return flags;
+ }
+
+ DBG(("%s: try operating on drawable inplace\n", __FUNCTION__));
+ return flags | MOVE_INPLACE_HINT;
+}
+
static bool
sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
{
@@ -1685,8 +1756,10 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
if (priv == NULL)
return NULL;
- if (DAMAGE_IS_ALL(priv->gpu_damage))
+ if (DAMAGE_IS_ALL(priv->gpu_damage)) {
+ DBG(("%s: already all-damaged\n", __FUNCTION__));
goto done;
+ }
if ((flags & MOVE_READ) == 0)
sna_damage_destroy(&priv->cpu_damage);
@@ -1768,10 +1841,6 @@ done:
sna_damage_reduce_all(&priv->gpu_damage,
pixmap->drawable.width,
pixmap->drawable.height);
- if (priv->mapped) {
- pixmap->devPrivate.ptr = NULL;
- priv->mapped = 0;
- }
if (!priv->pinned)
list_move(&priv->inactive, &sna->active_pixmaps);
return priv;
@@ -2579,7 +2648,7 @@ fallback:
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fbPutImage(%d, %d, %d, %d)\n",
@@ -3659,7 +3728,7 @@ fallback:
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
fbFillSpans(drawable, gc, n, pt, width, sorted);
@@ -3688,7 +3757,7 @@ sna_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
fbSetSpans(drawable, gc, src, pt, width, n, sorted);
@@ -4308,7 +4377,7 @@ fallback:
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fbPolyPoint\n", __FUNCTION__));
@@ -5187,7 +5256,7 @@ fallback:
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fbPolyLine\n", __FUNCTION__));
@@ -6040,7 +6109,7 @@ fallback:
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fbPolySegment\n", __FUNCTION__));
@@ -6590,7 +6659,7 @@ fallback:
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fbPolyRectangle\n", __FUNCTION__));
@@ -6716,7 +6785,7 @@ fallback:
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
/* XXX may still fallthrough to miZeroPolyArc */
@@ -8112,19 +8181,6 @@ sna_poly_fill_rect_extents(DrawablePtr drawable, GCPtr gc,
return 1 | clipped << 1;
}
-static bool alu_overwrites(uint8_t alu)
-{
- switch (alu) {
- case GXclear:
- case GXcopy:
- case GXcopyInverted:
- case GXset:
- return true;
- default:
- return false;
- }
-}
-
static void
sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
{
@@ -8842,7 +8898,7 @@ sna_image_text8(DrawablePtr drawable, GCPtr gc,
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
@@ -8909,7 +8965,7 @@ sna_image_text16(DrawablePtr drawable, GCPtr gc,
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
if(!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
@@ -9155,7 +9211,8 @@ fallback:
DBG(("%s: fallback\n", __FUNCTION__));
if (!sna_gc_move_to_cpu(gc, drawable))
goto out;
- if (!sna_drawable_move_region_to_cpu(drawable, &region, true))
+ if (!sna_drawable_move_region_to_cpu(drawable, &region,
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
@@ -9395,7 +9452,7 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
if (!sna_pixmap_move_to_cpu(bitmap, MOVE_READ))
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &region,
- MOVE_READ | MOVE_WRITE))
+ drawable_gc_flags(drawable, gc)))
goto out;
DBG(("%s: fallback, fbPushPixels(%d, %d, %d %d)\n",