diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-13 11:30:07 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-13 14:13:55 +0000 |
commit | b266ae6f6f8fb4c494ece532ae4621055e66beb2 (patch) | |
tree | f9748513f8acf39f3451f9e2106070a86575521a | |
parent | a2d82161436e489f23637d793c737bc6950a62b8 (diff) |
sna: Relax limitation on not mapping GPU bo with shadow pointers
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 59 | ||||
-rw-r--r-- | src/sna/kgem.h | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 82 | ||||
-rw-r--r-- | src/sna/sna_render.c | 2 | ||||
-rw-r--r-- | src/sna/sna_render_inline.h | 4 |
5 files changed, 86 insertions, 62 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index bffe13a7..83622b97 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -3362,6 +3362,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem, { uint32_t pitch, size; unsigned flags = 0; + int tiling; int bpp; DBG(("%s: %dx%d @ %d\n", __FUNCTION__, width, height, depth)); @@ -3381,33 +3382,41 @@ unsigned kgem_can_create_2d(struct kgem *kgem, size = kgem_surface_size(kgem, false, 0, width, height, bpp, I915_TILING_NONE, &pitch); - if (size > 0 && size <= kgem->max_cpu_size) - flags |= KGEM_CAN_CREATE_CPU | KGEM_CAN_CREATE_GPU; - if (size > 0 && size <= kgem->aperture_mappable/4) - flags |= KGEM_CAN_CREATE_GTT; - if (size > kgem->large_object_size) - flags |= KGEM_CAN_CREATE_LARGE; - if (size > kgem->max_object_size) { - DBG(("%s: too large (untiled) %d > %d\n", - __FUNCTION__, size, kgem->max_object_size)); - return 0; + if (size > 0) { + if (size < 4096) + flags |= KGEM_CAN_CREATE_SMALL; + if (size <= kgem->max_cpu_size) + flags |= KGEM_CAN_CREATE_CPU; + if (size <= kgem->max_gpu_size) + flags |= KGEM_CAN_CREATE_GPU; + if (size <= kgem->aperture_mappable/4) + flags |= KGEM_CAN_CREATE_GTT; + if (size > kgem->large_object_size) + flags |= KGEM_CAN_CREATE_LARGE; + if (size > kgem->max_object_size) { + DBG(("%s: too large (untiled) %d > %d\n", + __FUNCTION__, size, kgem->max_object_size)); + return 0; + } } - size = kgem_surface_size(kgem, false, 0, - width, height, bpp, - kgem_choose_tiling(kgem, I915_TILING_X, - width, height, bpp), - &pitch); - if (size > 0 && size <= kgem->max_gpu_size) - flags |= KGEM_CAN_CREATE_GPU; - if (size > 0 && size <= kgem->aperture_mappable/4) - flags |= KGEM_CAN_CREATE_GTT; - if (size > kgem->large_object_size) - flags |= KGEM_CAN_CREATE_LARGE; - if (size > kgem->max_object_size) { - DBG(("%s: too large (tiled) %d > %d\n", - __FUNCTION__, size, kgem->max_object_size)); - return 0; + tiling = kgem_choose_tiling(kgem, I915_TILING_X, + width, height, bpp); + if (tiling != I915_TILING_NONE) { + size = kgem_surface_size(kgem, false, 0, + width, height, bpp, tiling, + &pitch); + if (size > 0 && size <= kgem->max_gpu_size) + flags |= KGEM_CAN_CREATE_GPU; + if (size > 0 && size <= kgem->aperture_mappable/4) + flags |= KGEM_CAN_CREATE_GTT; + if (size > kgem->large_object_size) + flags |= KGEM_CAN_CREATE_LARGE; + if (size > kgem->max_object_size) { + DBG(("%s: too large (tiled) %d > %d\n", + __FUNCTION__, size, kgem->max_object_size)); + return 0; + } } return flags; diff --git a/src/sna/kgem.h b/src/sna/kgem.h index d2b89f54..372bfdb1 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -248,6 +248,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth) #define KGEM_CAN_CREATE_CPU 0x2 #define KGEM_CAN_CREATE_LARGE 0x4 #define KGEM_CAN_CREATE_GTT 0x8 +#define KGEM_CAN_CREATE_SMALL 0x10 struct kgem_bo * kgem_replace_bo(struct kgem *kgem, diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index e9ecfafb..483981f4 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -92,6 +92,10 @@ #define NO_TILE_8x8 0 #define NO_STIPPLE_8x8 0 +#define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1) +#define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1)) +#define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1)) + #if 0 static void __sna_fallback_flush(DrawablePtr d) { @@ -457,9 +461,9 @@ sna_pixmap_alloc_cpu(struct sna *sna, assert(priv->ptr); done: - pixmap->devPrivate.ptr = priv->ptr; - pixmap->devKind = priv->stride; assert(priv->stride); + pixmap->devPrivate.ptr = PTR(priv->ptr); + pixmap->devKind = priv->stride; return priv->ptr != NULL; } @@ -468,6 +472,9 @@ static void sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv) assert(priv->cpu_damage == NULL); assert(list_is_empty(&priv->list)); + if (IS_STATIC_PTR(priv->ptr)) + return; + if (priv->cpu_bo) { DBG(("%s: discarding CPU buffer, handle=%d, size=%d\n", __FUNCTION__, priv->cpu_bo->handle, kgem_bo_size(priv->cpu_bo))); @@ -484,8 +491,8 @@ static void sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv) priv->cpu_bo = NULL; } else free(priv->ptr); - priv->ptr = NULL; + if (!priv->mapped) priv->pixmap->devPrivate.ptr = NULL; } @@ -762,7 +769,7 @@ sna_pixmap_create_shm(ScreenPtr screen, DBG(("%s(%dx%d, depth=%d, bpp=%d, pitch=%d)\n", __FUNCTION__, width, height, depth, bpp, pitch)); - if (wedged(sna) || bpp == 0 || pitch*height <= 4096) { + if (wedged(sna) || bpp == 0 || pitch*height < 4096) { fallback: pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth); if (pixmap == NULL) @@ -831,6 +838,8 @@ fallback: priv->cpu = true; priv->shm = true; + priv->stride = pitch; + priv->ptr = MAKE_STATIC_PTR(addr); sna_damage_all(&priv->cpu_damage, width, height); pixmap->devKind = pitch; @@ -1134,8 +1143,10 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, { struct sna *sna = to_sna_from_screen(screen); PixmapPtr pixmap; + struct sna_pixmap *priv; unsigned flags; int pad; + void *ptr; DBG(("%s(%d, %d, %d, usage=%x)\n", __FUNCTION__, width, height, depth, usage)); @@ -1196,7 +1207,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, usage = 0; pad = PixmapBytePad(width, depth); - if (pad * height <= 4096) { + if (pad * height < 4096) { DBG(("%s: small buffer [%d], attaching to shadow pixmap\n", __FUNCTION__, pad * height)); pixmap = create_pixmap(sna, screen, @@ -1204,10 +1215,10 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, if (pixmap == NullPixmap) return NullPixmap; - sna_pixmap_attach(pixmap); + ptr = MAKE_STATIC_PTR(pixmap->devPrivate.ptr); + pad = pixmap->devKind; + flags |= KGEM_CAN_CREATE_SMALL; } else { - struct sna_pixmap *priv; - DBG(("%s: creating GPU pixmap %dx%d, stride=%d, flags=%x\n", __FUNCTION__, width, height, pad, flags)); @@ -1220,16 +1231,19 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, pixmap->devKind = pad; pixmap->devPrivate.ptr = NULL; - priv = sna_pixmap_attach(pixmap); - if (priv == NULL) { - free(pixmap); - goto fallback; - } + ptr = NULL; + } - priv->stride = pad; - priv->create = flags; + priv = sna_pixmap_attach(pixmap); + if (priv == NULL) { + free(pixmap); + goto fallback; } + priv->stride = pad; + priv->create = flags; + priv->ptr = ptr; + return pixmap; fallback: @@ -1422,7 +1436,7 @@ static inline bool operate_inplace(struct sna_pixmap *priv, unsigned flags) if (flags & MOVE_WRITE && kgem_bo_is_busy(priv->gpu_bo)) return false; - return priv->stride != 0; + return true; } bool @@ -1540,6 +1554,7 @@ skip_inplace_map: pixmap->devKind = priv->gpu_bo->pitch; if (flags & MOVE_WRITE) { assert(priv->gpu_bo->proxy == NULL); + sna_pixmap_free_cpu(sna, priv); sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); @@ -1563,11 +1578,10 @@ skip_inplace_map: priv->mapped = false; } - if (priv->gpu_bo && + if (priv->gpu_damage && priv->gpu_bo->tiling == I915_TILING_NONE && sna_pixmap_move_to_gpu(pixmap, flags)) { kgem_bo_submit(&sna->kgem, priv->gpu_bo); - sna_pixmap_free_cpu(sna, priv); DBG(("%s: try to operate inplace (CPU)\n", __FUNCTION__)); @@ -1579,6 +1593,7 @@ skip_inplace_map: pixmap->devKind = priv->gpu_bo->pitch; if (flags & MOVE_WRITE) { assert(priv->gpu_bo->proxy == NULL); + sna_pixmap_free_cpu(sna, priv); sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); @@ -1876,7 +1891,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, __FUNCTION__)); assert(flags & MOVE_WRITE); - if (priv->stride && priv->gpu_bo && + if (priv->gpu_bo && kgem_bo_can_map(&sna->kgem, priv->gpu_bo) && region_inplace(sna, pixmap, region, priv, true)) { assert(priv->gpu_bo->proxy == NULL); @@ -1926,7 +1941,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, } } - if (priv->gpu_bo == NULL && priv->stride && + if (priv->gpu_bo == NULL && sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING) != I915_TILING_NONE && region_inplace(sna, pixmap, region, priv, true) && sna_pixmap_create_mappable_gpu(pixmap)) { @@ -2490,8 +2505,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl } if (!ok) { if (pixmap->devPrivate.ptr == NULL) { - assert(priv->stride && priv->ptr); - pixmap->devPrivate.ptr = priv->ptr; + assert(priv->ptr); + pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; } assert(!priv->mapped); @@ -2535,8 +2550,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl } if (!ok) { if (pixmap->devPrivate.ptr == NULL) { - assert(priv->stride && priv->ptr); - pixmap->devPrivate.ptr = priv->ptr; + assert(priv->ptr); + pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; } assert(!priv->mapped); @@ -2571,8 +2586,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl } if (!ok) { if (pixmap->devPrivate.ptr == NULL) { - assert(priv->stride && priv->ptr); - pixmap->devPrivate.ptr = priv->ptr; + assert(priv->ptr); + pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; } assert(!priv->mapped); @@ -3064,7 +3079,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) sna_damage_destroy(&priv->cpu_damage); list_del(&priv->list); priv->undamaged = false; - assert(priv->cpu == false); + assert(priv->cpu == false || IS_CPU_MAP(priv->gpu_bo->map)); goto active; } @@ -3145,7 +3160,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) if (priv->mapped) { assert(priv->stride); - pixmap->devPrivate.ptr = priv->ptr; + pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; priv->mapped = false; } @@ -3167,8 +3182,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) } if (!ok) { if (pixmap->devPrivate.ptr == NULL) { - assert(priv->stride && priv->ptr); - pixmap->devPrivate.ptr = priv->ptr; + assert(priv->ptr); + pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; } assert(!priv->mapped); @@ -3203,7 +3218,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) /* For large bo, try to keep only a single copy around */ if (priv->create & KGEM_CAN_CREATE_LARGE || - (priv->stride && flags & MOVE_SOURCE_HINT)) { + flags & MOVE_SOURCE_HINT) { DBG(("%s: disposing of system copy for large/source\n", __FUNCTION__)); assert(!priv->shm); @@ -3619,7 +3634,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, } /* And mark as having a valid GTT mapping for future uploads */ - if (priv->stride && kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) { + if ( kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) { pixmap->devPrivate.ptr = kgem_bo_map__async(&sna->kgem, priv->gpu_bo); if (pixmap->devPrivate.ptr) { @@ -4679,8 +4694,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, if (src_pixmap->devPrivate.ptr == NULL) { if (!src_priv->ptr) /* uninitialised!*/ return; - assert(src_priv->stride); - src_pixmap->devPrivate.ptr = src_priv->ptr; + src_pixmap->devPrivate.ptr = PTR(src_priv->ptr); src_pixmap->devKind = src_priv->stride; } } diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index d7fa5cb3..46ce64ba 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -508,7 +508,7 @@ static struct kgem_bo *upload(struct sna *sna, if (priv->ptr == NULL) /* uninitialised */ return NULL; assert(priv->stride); - pixmap->devPrivate.ptr = priv->ptr; + pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; } } diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h index 2feb7ca5..a3297073 100644 --- a/src/sna/sna_render_inline.h +++ b/src/sna/sna_render_inline.h @@ -71,7 +71,7 @@ is_gpu(DrawablePtr drawable) { struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable); - if (priv == NULL || priv->clear) + if (priv == NULL || priv->clear || priv->cpu) return false; if (priv->cpu_damage == NULL) @@ -97,7 +97,7 @@ too_small(struct sna_pixmap *priv) if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return false; - return (priv->create & KGEM_CAN_CREATE_GPU) == 0; + return priv->create & KGEM_CAN_CREATE_SMALL; } static inline bool |