diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-01 15:11:07 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-01 16:52:35 +0100 |
commit | a10781b70f222f3997928fa979f6292617f79316 (patch) | |
tree | ebd2d4f547ed242706f38e037592cf22cc1157a0 | |
parent | 75745cd5861481c5a9a31125d357f339349dd0f8 (diff) |
sna: Enforce LinearFramebuffer option
This option should only be used for compatibility. Previously this was
done at a high level, this changes it to enforce the tiling as we apply
the CRTC.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 6 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 156 | ||||
-rw-r--r-- | src/sna/sna_display.c | 5 | ||||
-rw-r--r-- | src/sna/sna_dri2.c | 11 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 18 | ||||
-rw-r--r-- | src/sna/sna_present.c | 10 |
6 files changed, 78 insertions, 128 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 7b89f8c3..68a65009 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -254,6 +254,7 @@ struct sna { #define SNA_REMOVE_OUTPUTS 0x400 #define SNA_HAS_FLIP 0x10000 #define SNA_HAS_ASYNC_FLIP 0x20000 +#define SNA_LINEAR_FB 0x40000 #define SNA_REPROBE 0x80000000 unsigned cpu_features; @@ -360,11 +361,6 @@ struct sna { int num_adaptors; } xv; - unsigned int tiling; -#define SNA_TILING_FB 0x1 -#define SNA_TILING_2D 0x2 -#define SNA_TILING_ALL (~0) - EntityInfoPtr pEnt; const struct intel_device_info *info; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 324107f0..02e59206 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -607,12 +607,13 @@ static bool sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv, bool a return true; } -static inline uint32_t default_tiling(PixmapPtr pixmap, - uint32_t tiling) +static inline uint32_t default_tiling(struct sna *sna, PixmapPtr pixmap) { - struct sna_pixmap *priv = sna_pixmap(pixmap); - struct sna *sna = to_sna_from_pixmap(pixmap); - +#if DEFAULT_TILING == I915_TILING_NONE + return I915_TILING_NONE; +#elif DEFAULT_TILING == I915_TILING_X + return I915_TILING_X; +#else /* Try to avoid hitting the Y-tiling GTT mapping bug on 855GM */ if (sna->kgem.gen == 021) return I915_TILING_X; @@ -626,41 +627,26 @@ static inline uint32_t default_tiling(PixmapPtr pixmap, pixmap->drawable.height > sna->render.max_3d_size)) return I915_TILING_X; - if (tiling == I915_TILING_Y && - sna_damage_is_all(&priv->cpu_damage, + if (sna_damage_is_all(&sna_pixmap(pixmap)->cpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: entire source is damaged, using Y-tiling\n", __FUNCTION__)); - sna_damage_destroy(&priv->gpu_damage); - + sna_damage_destroy(&sna_pixmap(priv)->gpu_damage); return I915_TILING_Y; } - return tiling; + return I915_TILING_Y; +#endif } -pure static uint32_t sna_pixmap_choose_tiling(PixmapPtr pixmap, - uint32_t tiling) +pure static uint32_t sna_pixmap_default_tiling(struct sna *sna, PixmapPtr pixmap) { - struct sna *sna = to_sna_from_pixmap(pixmap); - uint32_t bit; - - /* Use tiling by default, but disable per user request */ - if (pixmap->usage_hint == SNA_CREATE_FB) { - tiling = -I915_TILING_X; - bit = SNA_TILING_FB; - } else { - tiling = default_tiling(pixmap, tiling); - bit = SNA_TILING_2D; - } - if ((sna->tiling & bit) == 0) - tiling = I915_TILING_NONE; - /* Also adjust tiling if it is not supported or likely to * slow us down, */ - return kgem_choose_tiling(&sna->kgem, tiling, + return kgem_choose_tiling(&sna->kgem, + default_tiling(sna, pixmap), pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel); @@ -1617,6 +1603,28 @@ static inline bool pixmap_inplace(struct sna *sna, sna->kgem.half_cpu_cache_pages; } +static bool sna_pixmap_alloc_gpu(struct sna *sna, + PixmapPtr pixmap, + struct sna_pixmap *priv, + unsigned flags) +{ + uint32_t tiling; + + /* Use tiling by default, but disable per user request */ + if (pixmap->usage_hint == SNA_CREATE_FB && (sna->flags & SNA_LINEAR_FB) == 0) { + flags |= CREATE_SCANOUT; + tiling = -I915_TILING_X; + } else + tiling = sna_pixmap_default_tiling(sna, pixmap), + + priv->gpu_bo = kgem_create_2d(&sna->kgem, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.bitsPerPixel, + tiling, flags); + return priv->gpu_bo != NULL; +} + static bool sna_pixmap_create_mappable_gpu(PixmapPtr pixmap, bool can_replace) @@ -1643,22 +1651,9 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap, } if (priv->gpu_bo == NULL) { - unsigned create; - assert_pixmap_damage(pixmap); assert(priv->gpu_damage == NULL); - - create = CREATE_GTT_MAP | CREATE_INACTIVE; - if (pixmap->usage_hint == SNA_CREATE_FB) - create |= CREATE_SCANOUT; - - priv->gpu_bo = - kgem_create_2d(&sna->kgem, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->drawable.bitsPerPixel, - sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING), - create); + sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_GTT_MAP | CREATE_INACTIVE); } out: @@ -1874,7 +1869,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) bo = kgem_create_2d(&sna->kgem, box.x2, box.y2, pixmap->drawable.bitsPerPixel, - sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING), + sna_pixmap_default_tiling(sna, pixmap), 0); if (bo == NULL) { cow->refcnt++; @@ -1923,7 +1918,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) bo = kgem_create_2d(&sna->kgem, box.x2, box.y2, pixmap->drawable.bitsPerPixel, - sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING), + sna_pixmap_default_tiling(sna, pixmap), 0); if (bo == NULL) { cow->refcnt++; @@ -2601,8 +2596,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, RegionTranslate(region, dx, dy); if (sna->kgem.has_llc && !priv->pinned && - sna_pixmap_choose_tiling(pixmap, - DEFAULT_TILING) == I915_TILING_NONE) { + sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE) { #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs--; sna->debug_memory.cpu_bo_bytes -= kgem_bo_size(priv->cpu_bo); @@ -3313,24 +3307,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl if (priv->gpu_bo == NULL) { assert(priv->gpu_damage == NULL); - if (flags & __MOVE_FORCE || - priv->create & KGEM_CAN_CREATE_GPU) { - unsigned create, tiling; - - create = CREATE_INACTIVE; - if (pixmap->usage_hint == SNA_CREATE_FB) - create |= CREATE_SCANOUT; - - tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING; - tiling = sna_pixmap_choose_tiling(pixmap, tiling); - - assert(!priv->mapped); - priv->gpu_bo = kgem_create_2d(&sna->kgem, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->drawable.bitsPerPixel, - tiling, create); - } + if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) + sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_INACTIVE); if (priv->gpu_bo == NULL) return NULL; @@ -4127,16 +4105,13 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) priv->create)); assert(!priv->mapped); if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) { - unsigned create, tiling; + unsigned create; assert(pixmap->drawable.width > 0); assert(pixmap->drawable.height > 0); assert(pixmap->drawable.bitsPerPixel >= 8); - tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING; - tiling = sna_pixmap_choose_tiling(pixmap, tiling); - - if (tiling == I915_TILING_NONE && + if (sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE && priv->cpu_bo && !priv->shm && kgem_bo_convert_to_gpu(&sna->kgem, priv->cpu_bo, flags)) { assert(!priv->mapped); @@ -4157,15 +4132,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) create = 0; if (flags & MOVE_INPLACE_HINT || (priv->cpu_damage && priv->cpu_bo == NULL)) create = CREATE_GTT_MAP | CREATE_INACTIVE; - if (pixmap->usage_hint == SNA_CREATE_FB) - create |= CREATE_SCANOUT; - priv->gpu_bo = - kgem_create_2d(&sna->kgem, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->drawable.bitsPerPixel, - tiling, create); + sna_pixmap_alloc_gpu(sna, pixmap, priv, create); } if (priv->gpu_bo == NULL) { DBG(("%s: not creating GPU bo\n", __FUNCTION__)); @@ -4510,58 +4478,45 @@ static inline void box32_add_rect(Box32Rec *box, const xRectangle *r) } static bool -can_create_upload_tiled_x(struct kgem *kgem, +can_create_upload_tiled_x(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, bool replaces) { - unsigned tiling; - if (priv->shm || (priv->cpu && !replaces)) return false; if ((priv->create & KGEM_CAN_CREATE_GPU) == 0) return false; - if (kgem->has_llc) + if (sna->kgem.has_llc) return true; - tiling = sna_pixmap_choose_tiling(pixmap, I915_TILING_X); - assert(tiling != I915_TILING_Y && tiling != -I915_TILING_Y); - if (tiling != I915_TILING_NONE) + if (sna_pixmap_default_tiling(sna, pixmap)) return false; return true; } static bool -create_upload_tiled_x(struct kgem *kgem, +create_upload_tiled_x(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, bool replaces) { unsigned create; - if (!can_create_upload_tiled_x(kgem, pixmap, priv, replaces)) + if (!can_create_upload_tiled_x(sna, pixmap, priv, replaces)) return false; assert(priv->gpu_bo == NULL); assert(priv->gpu_damage == NULL); create = CREATE_CPU_MAP | CREATE_INACTIVE; - if (pixmap->usage_hint == SNA_CREATE_FB) - create |= CREATE_SCANOUT; - if (!kgem->has_llc) + if (!sna->kgem.has_llc) create |= CREATE_CACHED; - priv->gpu_bo = - kgem_create_2d(kgem, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->drawable.bitsPerPixel, - sna_pixmap_choose_tiling(pixmap, I915_TILING_X), - create); - return priv->gpu_bo != NULL; + return sna_pixmap_alloc_gpu(sna, pixmap, priv, create); } static bool @@ -4714,7 +4669,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region, if (priv->gpu_bo && replaces) { if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); - if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, true) && + if (can_create_upload_tiled_x(sna, pixmap, priv, true) && (priv->cow || __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) || !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) { @@ -4737,7 +4692,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region, if (priv->gpu_damage && region_subsumes_damage(region, priv->gpu_damage)) { if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo); - if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, priv->cpu_damage == NULL) && + if (can_create_upload_tiled_x(sna, pixmap, priv, priv->cpu_damage == NULL) && (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) || !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) { DBG(("%s: discarding unusable partial target bo (busy? %d, mappable? %d)\n", __FUNCTION__, @@ -4751,7 +4706,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region, } if (priv->gpu_bo == NULL && - !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu)) + !create_upload_tiled_x(sna, pixmap, priv, ignore_cpu)) return false; DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling)); @@ -5624,8 +5579,7 @@ move_to_gpu(PixmapPtr pixmap, struct sna_pixmap *priv, if (priv->cpu_bo->flush && count > SOURCE_BIAS) return true; - if (sna_pixmap_choose_tiling(pixmap, - DEFAULT_TILING) == I915_TILING_NONE) + if (sna_pixmap_default_tiling(to_sna_from_pixmap(pixmap), pixmap) == I915_TILING_NONE) return false; if (priv->cpu) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 38ebc11d..55795855 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -1666,6 +1666,9 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc) if (priv->gpu_bo->pitch > pitch_limit) return true; + if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB) + return true; + transform = NULL; if (crtc->transformPresent) transform = &crtc->transform; @@ -1779,6 +1782,8 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) tiled_limit = 8 * 1024 * 8; if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit) tiling = I915_TILING_NONE; + if (sna->flags & SNA_LINEAR_FB) + tiling = I915_TILING_NONE; bo = kgem_create_2d(&sna->kgem, crtc->mode.HDisplay, crtc->mode.VDisplay, diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 9b128daa..5adbd0b8 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -459,7 +459,7 @@ sna_dri2_create_buffer(DrawablePtr draw, bo = ref(bo); bpp = pixmap->drawable.bitsPerPixel; - if (pixmap == sna->front) + if (pixmap == sna->front && !(sna->flags & SNA_LINEAR_FB)) flags |= CREATE_SCANOUT; DBG(("%s: attaching to front buffer %dx%d [%p:%d], scanout? %d\n", __FUNCTION__, @@ -474,7 +474,7 @@ sna_dri2_create_buffer(DrawablePtr draw, flags |= CREATE_SCANOUT; if (draw->width == sna->front->drawable.width && draw->height == sna->front->drawable.height && - (sna->flags & (SNA_NO_WAIT | SNA_NO_FLIP)) == 0) + (sna->flags & (SNA_LINEAR_FB | SNA_NO_WAIT | SNA_NO_FLIP)) == 0) flags |= CREATE_SCANOUT; } case DRI2BufferBackRight: @@ -1644,11 +1644,12 @@ can_flip(struct sna * sna, } /* prevent an implicit tiling mode change */ - if (get_private(front)->bo->tiling != get_private(back)->bo->tiling) { - DBG(("%s -- no, tiling mismatch: front %d, back=%d\n", + if (get_private(back)->bo->tiling > I915_TILING_X) { + DBG(("%s -- no, tiling mismatch: front %d, back=%d, want-tiled?=%d\n", __FUNCTION__, get_private(front)->bo->tiling, - get_private(back)->bo->tiling)); + get_private(back)->bo->tiling, + !!(sna->flags & SNA_LINEAR_FB))); return false; } diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index c57832b1..ce319d22 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -614,22 +614,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags) sna->kgem.wedged = true; } - /* Enable tiling by default */ - sna->tiling = SNA_TILING_ALL; - - /* Allow user override if they set a value */ - if (!xf86ReturnOptValBool(sna->Options, OPTION_TILING_2D, TRUE)) - sna->tiling &= ~SNA_TILING_2D; if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE)) - sna->tiling &= ~SNA_TILING_FB; - - if (sna->tiling != SNA_TILING_ALL) { - xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Framebuffer %s, pixmaps %s\n", - sna->tiling & SNA_TILING_FB ? "tiled" : "linear", - sna->tiling & SNA_TILING_2D ? "tiled" : "linear"); - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "Tiling disabled, expect poor performance and increased power consumption.\n"); - } + sna->flags |= SNA_LINEAR_FB; if (xf86ReturnOptValBool(sna->Options, OPTION_DELETE_DP12, FALSE)) sna->flags |= SNA_REMOVE_OUTPUTS; @@ -665,7 +651,7 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags) } scrn->currentMode = scrn->modes; - if (sna->flags & SNA_HAS_FLIP && + if ((sna->flags & (SNA_HAS_FLIP | SNA_LINEAR_FB)) == SNA_HAS_FLIP && xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, enable_tear_free(sna))) sna->flags |= SNA_TEAR_FREE; xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "TearFree %sabled\n", diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c index 5379d1e8..dd4771c9 100644 --- a/src/sna/sna_present.c +++ b/src/sna/sna_present.c @@ -351,6 +351,7 @@ page_flip(ScreenPtr screen, static struct kgem_bo * get_flip_bo(PixmapPtr pixmap) { + struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; DBG(("%s(pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber)); @@ -361,9 +362,16 @@ get_flip_bo(PixmapPtr pixmap) return NULL; } + if (sna->flags & SNA_LINEAR_FB && + priv->gpu_bo->tiling && + !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { + DBG(("%s: invalid tiling for scanout, user requires linear\n", __FUNCTION__)); + return NULL; + } + if (priv->gpu_bo->tiling == I915_TILING_Y && !sna_pixmap_change_tiling(pixmap, I915_TILING_X)) { - DBG(("%s: bad tiling, cannot convert\n", __FUNCTION__)); + DBG(("%s: invalid Y-tiling, cannot convert\n", __FUNCTION__)); return NULL; } |