diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-12 21:08:41 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-12 21:15:58 +0000 |
commit | 8d2f1eefe142b65db7d8821ba0f80fdb0902b2d5 (patch) | |
tree | 86b4739e1cc332823319a22dfdd55f720f3ff5ef | |
parent | 48ab72754d0069a3247c5fee8c353a6b593eaed9 (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.h | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 121 |
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, ®ion->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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, - 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, ®ion, true)) + if (!sna_drawable_move_region_to_cpu(drawable, ®ion, + 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, ®ion, - MOVE_READ | MOVE_WRITE)) + drawable_gc_flags(drawable, gc))) goto out; DBG(("%s: fallback, fbPushPixels(%d, %d, %d %d)\n", |