From f2affe403baea78b9c94e3d726d1b9d8a0004f35 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 6 Sep 2012 10:24:04 +0100 Subject: [PATCH] sna: Apply the minimum 256 pitch to CREATE_USAGE_SHARED pixmaps as well Signed-off-by: Chris Wilson --- src/sna/kgem.c | 42 ++++++++++++++++++---------------- src/sna/kgem.h | 7 +++--- src/sna/sna_accel.c | 56 ++++++++++++++++++++++++++++++++++----------- 3 files changed, 69 insertions(+), 36 deletions(-) diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 4b1738ee..902cba7e 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -984,12 +984,21 @@ static uint32_t kgem_get_unique_id(struct kgem *kgem) return id; } +inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags) +{ + if (flags & CREATE_PRIME) + return 256; + if (flags & CREATE_SCANOUT) + return 64; + return kgem->min_alignment; +} + static uint32_t kgem_untiled_pitch(struct kgem *kgem, uint32_t width, uint32_t bpp, - bool scanout) + unsigned flags) { width = ALIGN(width, 2) * bpp >> 3; - return ALIGN(width, scanout ? 64 : kgem->min_alignment); + return ALIGN(width, kgem_pitch_alignment(kgem, flags)); } void kgem_get_tile_size(struct kgem *kgem, int tiling, @@ -1033,7 +1042,7 @@ void kgem_get_tile_size(struct kgem *kgem, int tiling, static uint32_t kgem_surface_size(struct kgem *kgem, bool relaxed_fencing, - bool scanout, + unsigned flags, uint32_t width, uint32_t height, uint32_t bpp, @@ -1058,7 +1067,7 @@ static uint32_t kgem_surface_size(struct kgem *kgem, } else { tile_width = 2 * bpp >> 3; tile_width = ALIGN(tile_width, - scanout ? 64 : kgem->min_alignment); + kgem_pitch_alignment(kgem, flags)); tile_height = 2; } } else switch (tiling) { @@ -1066,7 +1075,7 @@ static uint32_t kgem_surface_size(struct kgem *kgem, case I915_TILING_NONE: tile_width = 2 * bpp >> 3; tile_width = ALIGN(tile_width, - scanout ? 64 : kgem->min_alignment); + kgem_pitch_alignment(kgem, flags)); tile_height = 2; break; case I915_TILING_X: @@ -2991,7 +3000,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem, return 0; } - size = kgem_surface_size(kgem, false, false, + size = kgem_surface_size(kgem, false, 0, width, height, bpp, I915_TILING_NONE, &pitch); if (size > 0 && size <= kgem->max_cpu_size) @@ -3006,7 +3015,7 @@ unsigned kgem_can_create_2d(struct kgem *kgem, return 0; } - size = kgem_surface_size(kgem, false, false, + size = kgem_surface_size(kgem, false, 0, width, height, bpp, kgem_choose_tiling(kgem, I915_TILING_X, width, height, bpp), @@ -3059,18 +3068,17 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem, if (tiling < 0) tiling = -tiling, flags |= CREATE_EXACT; - DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d, temp?=%d)\n", __FUNCTION__, + DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d, prime?=%d, temp?=%d)\n", __FUNCTION__, width, height, bpp, tiling, !!(flags & CREATE_EXACT), !!(flags & CREATE_INACTIVE), !!(flags & CREATE_CPU_MAP), !!(flags & CREATE_GTT_MAP), !!(flags & CREATE_SCANOUT), + !!(flags & CREATE_PRIME), !!(flags & CREATE_TEMPORARY))); - size = kgem_surface_size(kgem, - kgem->has_relaxed_fencing, - flags & CREATE_SCANOUT, + size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags, width, height, bpp, tiling, &pitch); assert(size && size <= kgem->max_object_size); size /= PAGE_SIZE; @@ -3084,9 +3092,7 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem, goto create; tiled_height = kgem_aligned_height(kgem, height, I915_TILING_Y); - untiled_pitch = kgem_untiled_pitch(kgem, - width, bpp, - flags & CREATE_SCANOUT); + untiled_pitch = kgem_untiled_pitch(kgem, width, bpp, flags); list_for_each_entry(bo, &kgem->large, list) { assert(!bo->purged); @@ -3289,14 +3295,10 @@ search_again: } if ((flags & CREATE_EXACT) == 0) { /* allow an active near-miss? */ - untiled_pitch = kgem_untiled_pitch(kgem, - width, bpp, - flags & CREATE_SCANOUT); + untiled_pitch = kgem_untiled_pitch(kgem, width, bpp, flags); i = tiling; while (--i >= 0) { - tiled_height = kgem_surface_size(kgem, - kgem->has_relaxed_fencing, - flags & CREATE_SCANOUT, + tiled_height = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags, width, height, bpp, tiling, &pitch); cache = active(kgem, tiled_height / PAGE_SIZE, i); tiled_height = kgem_aligned_height(kgem, height, i); diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 0d5384b0..1dc9c673 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -242,9 +242,10 @@ enum { CREATE_CPU_MAP = 0x4, CREATE_GTT_MAP = 0x8, CREATE_SCANOUT = 0x10, - CREATE_TEMPORARY = 0x20, - CREATE_NO_RETIRE = 0x40, - CREATE_NO_THROTTLE = 0x40, + CREATE_PRIME = 0x20, + CREATE_TEMPORARY = 0x40, + CREATE_NO_RETIRE = 0x80, + CREATE_NO_THROTTLE = 0x100, }; struct kgem_bo *kgem_create_2d(struct kgem *kgem, int width, diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index c00b5b83..0eaa67ad 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1020,7 +1020,8 @@ sna_set_shared_pixmap_backing(PixmapPtr pixmap, void *fd_handle) } static PixmapPtr -sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen, int depth) +sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen, + int width, int height, int depth) { PixmapPtr pixmap; struct sna_pixmap *priv; @@ -1032,8 +1033,6 @@ sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen, int depth) if (pixmap == NullPixmap) return NullPixmap; - pixmap->drawable.width = 0; - pixmap->drawable.height = 0; pixmap->devKind = 0; pixmap->devPrivate.ptr = NULL; @@ -1045,6 +1044,42 @@ sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen, int depth) priv->stride = 0; priv->create = 0; + + if (width|height) { + int bpp = bits_per_pixel(depth); + + priv->gpu_bo = kgem_create_2d(&sna->kgem, + width, height, bpp, + I915_TILING_NONE, + CREATE_GTT_MAP | CREATE_PRIME); + if (priv->gpu_bo == NULL) { + free(priv); + FreePixmap(pixmap); + return NullPixmap; + } + + /* minimal interface for sharing is linear, 256 byte pitch */ + assert(priv->gpu_bo->tiling == I915_TILING_NONE); + assert((priv->gpu_bo->pitch & 255) == 0); + + pixmap->devPrivate.ptr = + kgem_bo_map__async(&sna->kgem, priv->gpu_bo); + if (pixmap->devPrivate.ptr == NULL) { + free(priv); + FreePixmap(pixmap); + return FALSE; + } + + pixmap->devKind = priv->gpu_bo->pitch; + pixmap->drawable.width = width; + pixmap->drawable.height = height; + + priv->stride = priv->gpu_bo->pitch; + priv->mapped = true; + + sna_damage_all(&priv->gpu_damage, width, height); + } + return pixmap; } #endif @@ -1061,23 +1096,18 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, DBG(("%s(%d, %d, %d, usage=%x)\n", __FUNCTION__, width, height, depth, usage)); - if ((width|height) == 0) { #ifdef CREATE_PIXMAP_USAGE_SHARED - if (usage == CREATE_PIXMAP_USAGE_SHARED) - return sna_create_pixmap_shared(sna, screen, depth); + if (usage == CREATE_PIXMAP_USAGE_SHARED) + return sna_create_pixmap_shared(sna, screen, + width, height, depth); #endif + + if ((width|height) == 0) { usage = -1; goto fallback; } assert(width && height); -#ifdef CREATE_PIXMAP_USAGE_SHARED - if (usage == CREATE_PIXMAP_USAGE_SHARED) - return sna_pixmap_create_scratch(screen, - width, height, depth, - I915_TILING_NONE); -#endif - flags = kgem_can_create_2d(&sna->kgem, width, height, depth); if (flags == 0) { DBG(("%s: can not use GPU, just creating shadow\n",