diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-01 14:31:32 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-01 14:31:32 +0100 |
commit | 75745cd5861481c5a9a31125d357f339349dd0f8 (patch) | |
tree | 0f76281b92f19d2d1ca61358eb57fb641178b1d2 /src | |
parent | 02715490db13dcd47c5e4bef713f400838d94b99 (diff) |
sna/dri2: Use CPU fallback if possible
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna_dri2.c | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index b03bf6a9..9b128daa 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -820,24 +820,64 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg _kgem_set_mode(&sna->kgem, mode); } +static bool can_copy_cpu(struct sna *sna, + struct kgem_bo *src, + struct kgem_bo *dst) +{ + if (src->tiling != dst->tiling) + return false; + + if (src->pitch != dst->pitch) + return false; + + if (!kgem_bo_can_map__cpu(&sna->kgem, src, false)) + return false; + + if (!kgem_bo_can_map__cpu(&sna->kgem, dst, true)) + return false; + + DBG(("%s -- yes, src handle=%d, dst handle=%d\n", __FUNCTION__, src->handle, dst->handle)); + return true; +} + static void -sna_dri2_copy_fallback(struct sna *sna, int bpp, +sna_dri2_copy_fallback(struct sna *sna, + const DrawableRec *draw, struct kgem_bo *src_bo, int sx, int sy, struct kgem_bo *dst_bo, int dx, int dy, const BoxRec *box, int n) { - void *dst = kgem_bo_map__gtt(&sna->kgem, dst_bo); - void *src = kgem_bo_map__gtt(&sna->kgem, src_bo); + void *dst, *src; + bool clipped; - if (dst == NULL || src == NULL) - return; + clipped = (n > 1 || + box->x1 + sx > 0 || + box->y1 + sy > 0 || + box->x2 + sx < draw->width || + box->y2 + sy < draw->height); + + dst = src = NULL; + if (!clipped && can_copy_cpu(sna, src_bo, dst_bo)) { + dst = kgem_bo_map__cpu(&sna->kgem, dst_bo); + src = kgem_bo_map__cpu(&sna->kgem, src_bo); + } + + if (dst == NULL || src == NULL) { + dst = kgem_bo_map__gtt(&sna->kgem, dst_bo); + src = kgem_bo_map__gtt(&sna->kgem, src_bo); + if (dst == NULL || src == NULL) + return; + } else { + kgem_bo_sync__cpu_full(&sna->kgem, dst_bo, true); + kgem_bo_sync__cpu_full(&sna->kgem, src_bo, false); + } DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n", __FUNCTION__, sx, sy, dx, dy, n)); if (sigtrap_get() == 0) { do { - memcpy_blt(src, dst, bpp, + memcpy_blt(src, dst, draw->bitsPerPixel, src_bo->pitch, dst_bo->pitch, box->x1 + sx, box->y1 + sy, box->x1 + dx, box->y1 + dy, @@ -945,6 +985,11 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, } else sync = false; + scratch.x = scratch.y = 0; + scratch.width = scratch.height = 0; + scratch.depth = draw->depth; + scratch.bitsPerPixel = draw->bitsPerPixel; + src_bo = src_priv->bo; assert(src_bo->refcnt); if (is_front(src->attachment)) { @@ -959,11 +1004,8 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, } else { RegionRec source; - scratch.x = scratch.y = 0; scratch.width = src_priv->size & 0xffff; scratch.height = src_priv->size >> 16; - scratch.depth = draw->depth; - scratch.bitsPerPixel = draw->bitsPerPixel; src_draw = &scratch; DBG(("%s: source size %dx%d, region size %dx%d\n", @@ -1005,11 +1047,8 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, } else { RegionRec target; - scratch.x = scratch.y = 0; scratch.width = dst_priv->size & 0xffff; scratch.height = dst_priv->size >> 16; - scratch.depth = draw->depth; - scratch.bitsPerPixel = draw->bitsPerPixel; dst_draw = &scratch; DBG(("%s: target size %dx%d, region size %dx%d\n", @@ -1056,7 +1095,7 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, if (wedged(sna)) { fallback: - sna_dri2_copy_fallback(sna, draw->bitsPerPixel, + sna_dri2_copy_fallback(sna, src_draw, src_bo, sx, sy, dst_bo, dx, dy, boxes, n); |