diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-19 11:15:38 +0000 |
|---|---|---|
| committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-19 11:59:53 +0000 |
| commit | d3f7d5d614748306cc376d1929da2bbc14494a6e (patch) | |
| tree | 16c4ab00014d8c2d8931023397e9ed5ad0413649 | |
| parent | ff2eb116ef85182eea9ed06daaa1e9a4f7bdbad3 (diff) | |
sna: Only use the blitter to emit spans if we cannot stream the updates
If either the region is busy on the gpu or if we need to read the
destination then we would incur penalties for trying to perform the
operation through the GTT. However, if we are simply streaming pixels to
an unbusy bo then we can do so inplace faster than computing the
corresponding GPU commands and uploading them.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| -rw-r--r-- | src/sna/sna_accel.c | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 08889f89..dd13eba7 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -60,7 +60,7 @@ #define USE_SPANS 0 #define USE_INPLACE 1 -#define USE_ZERO_SPANS 1 +#define USE_ZERO_SPANS 1 /* -1 force CPU, 1 force GPU */ #define USE_BO_FOR_SCRATCH_PIXMAP 1 #define MIGRATE_ALL 0 @@ -1148,8 +1148,6 @@ 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); @@ -5250,6 +5248,69 @@ sna_poly_line_extents(DrawablePtr drawable, GCPtr gc, return 1 | blt << 2 | clip << 1; } +/* Only use our spans code if the destination is busy and we can't perform + * the operation in place. + * + * Currently it looks to be faster to use the GPU for zero spans on all + * platforms. + */ +inline static bool +_use_zero_spans(DrawablePtr drawable, GCPtr gc, const BoxRec *extents) +{ + PixmapPtr pixmap; + struct sna_pixmap *priv; + BoxRec area; + int16_t dx, dy; + + if (USE_ZERO_SPANS) + return USE_ZERO_SPANS > 0; + + if ((drawable_gc_flags(drawable, gc, false) & MOVE_INPLACE_HINT) == 0) + return TRUE; + + /* XXX check for GPU stalls on the gc (stipple, tile, etc) */ + + pixmap = get_drawable_pixmap(drawable); + priv = sna_pixmap(pixmap); + if (priv == NULL) + return FALSE; + + if (DAMAGE_IS_ALL(priv->cpu_damage)) + return FALSE; + + if (priv->stride == 0 || priv->gpu_bo == NULL) + return FALSE; + + if (!kgem_bo_is_busy(priv->gpu_bo)) + return FALSE; + + if (DAMAGE_IS_ALL(priv->gpu_damage)) + return TRUE; + + if (priv->gpu_damage == NULL) + return FALSE; + + get_drawable_deltas(drawable, pixmap, &dx, &dy); + area = *extents; + area.x1 += dx; + area.x2 += dx; + area.y1 += dy; + area.y2 += dy; + DBG(("%s extents (%d, %d), (%d, %d)\n", __FUNCTION__, + area.x1, area.y1, area.x2, area.y2)); + + return sna_damage_contains_box(priv->gpu_damage, + &area) != PIXMAN_REGION_OUT; +} + +static bool +use_zero_spans(DrawablePtr drawable, GCPtr gc, const BoxRec *extents) +{ + bool ret = _use_zero_spans(drawable, gc, extents); + DBG(("%s? %d\n", __FUNCTION__, ret)); + return ret; +} + static void sna_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) @@ -5339,7 +5400,7 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc, ®ion.extents, flags & 2)) return; } else { /* !rectilinear */ - if (USE_ZERO_SPANS && + if (use_zero_spans(drawable, gc, ®ion.extents) && sna_drawable_use_gpu_bo(drawable, ®ion.extents, &damage) && @@ -6219,7 +6280,7 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg) ®ion.extents, flags & 2)) return; } else { - if (USE_ZERO_SPANS && + if (use_zero_spans(drawable, gc, ®ion.extents) && sna_drawable_use_gpu_bo(drawable, ®ion.extents, &damage) && |
