diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-31 00:09:42 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-31 00:31:21 +0000 |
commit | 3f7c1646c78d8854c88b214d3699e51839ba9711 (patch) | |
tree | 697558dbb763265d5ce6a7fd7c0d8229f115406a | |
parent | e504fab6c5354ae9d18ccefb10bd586fa49b924c (diff) |
sna: Check that the intermediate IO buffer can also be used for blitting
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 4 | ||||
-rw-r--r-- | src/sna/sna_io.c | 36 |
2 files changed, 29 insertions, 11 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index e35be974..3115bd7d 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -716,8 +716,8 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, } else { struct sna_pixmap *priv; - DBG(("%s: creating GPU pixmap %dx%d, stride=%d\n", - __FUNCTION__, width, height, pad)); + DBG(("%s: creating GPU pixmap %dx%d, stride=%d, flags=%x\n", + __FUNCTION__, width, height, pad, flags)); pixmap = create_pixmap(sna, screen, 0, 0, depth, usage); if (pixmap == NullPixmap) diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index 4f86f8de..f4278bed 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -59,11 +59,16 @@ box_intersect(BoxPtr a, const BoxRec *b) return a->x1 < a->x2 && a->y1 < a->y2; } +static inline bool upload_too_large(struct sna *sna, int width, int height) +{ + return width * height * 4 > sna->kgem.max_tile_size; +} + static inline bool must_tile(struct sna *sna, int width, int height) { return (width > sna->render.max_3d_size || height > sna->render.max_3d_size || - width * height * 4 > sna->kgem.max_tile_size); + upload_too_large(sna, width, height)); } static void read_boxes_inplace(struct kgem *kgem, @@ -118,6 +123,7 @@ void sna_read_boxes(struct sna *sna, void *ptr; int src_pitch, cpp, offset; int n, cmd, br13; + bool can_blt; DBG(("%s x %d, src=(handle=%d, offset=(%d,%d)), dst=(size=(%d, %d), offset=(%d,%d))\n", __FUNCTION__, nbox, src_bo->handle, src_dx, src_dy, @@ -154,6 +160,7 @@ fallback: return; } + can_blt = kgem_bo_can_blt(kgem, src_bo); extents = box[0]; for (n = 1; n < nbox; n++) { if (box[n].x1 < extents.x1) @@ -161,6 +168,9 @@ fallback: if (box[n].x2 > extents.x2) extents.x2 = box[n].x2; + if (can_blt) + can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); + if (box[n].y1 < extents.y1) extents.y1 = box[n].y1; if (box[n].y2 > extents.y2) @@ -173,9 +183,8 @@ fallback: } /* Try to avoid switching rings... */ - if (kgem->ring == KGEM_RENDER || - !kgem_bo_can_blt(kgem, src_bo) || - must_tile(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { + if (!can_blt || kgem->ring == KGEM_RENDER || + upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { PixmapRec tmp; tmp.drawable.width = extents.x2 - extents.x1; @@ -531,6 +540,7 @@ bool sna_write_boxes(struct sna *sna, PixmapPtr dst, void *ptr; int offset; int n, cmd, br13; + bool can_blt; DBG(("%s x %d\n", __FUNCTION__, nbox)); @@ -542,6 +552,7 @@ fallback: box, nbox); } + can_blt = kgem_bo_can_blt(kgem, dst_bo); extents = box[0]; for (n = 1; n < nbox; n++) { if (box[n].x1 < extents.x1) @@ -549,6 +560,9 @@ fallback: if (box[n].x2 > extents.x2) extents.x2 = box[n].x2; + if (can_blt) + can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); + if (box[n].y1 < extents.y1) extents.y1 = box[n].y1; if (box[n].y2 > extents.y2) @@ -556,9 +570,8 @@ fallback: } /* Try to avoid switching rings... */ - if (kgem->ring == KGEM_RENDER || - !kgem_bo_can_blt(kgem, dst_bo) || - must_tile(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { + if (!can_blt || kgem->ring == KGEM_RENDER || + upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { PixmapRec tmp; tmp.drawable.width = extents.x2 - extents.x1; @@ -579,6 +592,7 @@ fallback: BoxRec tile, stack[64], *clipped, *c; int step; +tile: step = MIN(sna->render.max_3d_size, 8*(MAXSHORT&~63) / dst->drawable.bitsPerPixel); while (step * step * 4 > sna->kgem.max_tile_size) @@ -693,7 +707,7 @@ fallback: kgem_bo_destroy(&sna->kgem, src_bo); if (!n) - goto fallback; + goto tile; } return true; @@ -1069,9 +1083,13 @@ indirect_replace(struct sna *sna, if ((int)pixmap->devKind * pixmap->drawable.height >> 12 > kgem->half_cpu_cache_pages) return false; - if (bo->tiling == I915_TILING_Y || kgem->ring == KGEM_RENDER) { + if (kgem->ring == KGEM_RENDER || !kgem_bo_can_blt(kgem, bo)) { BoxRec box; + assert(!must_tile(sna, + pixmap->drawable.width, + pixmap->drawable.height)); + src_bo = kgem_create_buffer_2d(kgem, pixmap->drawable.width, pixmap->drawable.height, |