diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-02-16 12:29:24 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2015-02-16 16:01:48 +0000 |
commit | 10e40489e22f7e65c919082ffe2a37d5f000dcee (patch) | |
tree | 6054787a882e7de52fcee36322d8959dcb3e169c | |
parent | 1877c8f5081f3192dd30bb1162efd6acb1957487 (diff) |
sna/present: Try exchanging the Pixmap with a scanout-ready bo
Try to avoid more clflushing on the current Pixmap if we have a
scanout-ready bo in the cache. We also note that since we unflip before
any other drawing takes place, we do not need to mark the flipped Pixmap
as being pinned to the scanout.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 3 | ||||
-rw-r--r-- | src/sna/sna_dri2.c | 2 | ||||
-rw-r--r-- | src/sna/sna_present.c | 53 |
3 files changed, 49 insertions, 9 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index c7f6ec4e..b87d49ea 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -4955,6 +4955,9 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem, } } + if (flags & CREATE_CACHED) + return NULL; + bo = __kgem_bo_create_as_display(kgem, size, tiling, pitch); if (bo) return bo; diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 840459ef..0a35e338 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -436,7 +436,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna, tiling = color_tiling(sna, &pixmap->drawable); if (tiling < 0) tiling = -tiling; - if (priv->gpu_bo->tiling != tiling) + if (priv->gpu_bo->tiling != tiling && !priv->gpu_bo->scanout) sna_pixmap_change_tiling(pixmap, tiling); return priv->gpu_bo; diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c index c96bcd2e..6efe429f 100644 --- a/src/sna/sna_present.c +++ b/src/sna/sna_present.c @@ -539,6 +539,42 @@ get_flip_bo(PixmapPtr pixmap) return NULL; } + if (priv->gpu_bo->scanout) + return priv->gpu_bo; + + if (sna->kgem.has_llc && !wedged(sna)) { + struct kgem_bo *bo; + uint32_t tiling; + + tiling = I915_TILING_NONE; + if ((sna->flags & SNA_LINEAR_FB) == 0) + tiling = I915_TILING_X; + + bo = kgem_create_2d(&sna->kgem, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.bitsPerPixel, + tiling, CREATE_SCANOUT | CREATE_CACHED); + if (bo) { + BoxRec box; + + box.x1 = box.y1 = 0; + box.x2 = pixmap->drawable.width; + box.y2 = pixmap->drawable.height; + + if (sna->render.copy_boxes(sna, GXcopy, + &pixmap->drawable, priv->gpu_bo, 0, 0, + &pixmap->drawable, bo, 0, 0, + &box, 1, 0)) { + sna_pixmap_unmap(pixmap, priv); + kgem_bo_destroy(&sna->kgem, priv->gpu_bo); + + priv->gpu_bo = bo; + } else + kgem_bo_destroy(&sna->kgem, bo); + } + } + if (sna->flags & SNA_LINEAR_FB && priv->gpu_bo->tiling && !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { @@ -552,7 +588,6 @@ get_flip_bo(PixmapPtr pixmap) return NULL; } - priv->pinned |= PIN_SCANOUT; return priv->gpu_bo; } @@ -580,19 +615,19 @@ sna_present_flip(RRCrtcPtr crtc, assert(sna->present.unflip == 0); - bo = get_flip_bo(pixmap); - if (bo == NULL) { - DBG(("%s: flip invalid bo\n", __FUNCTION__)); - return FALSE; - } - if (sna->flags & SNA_TEAR_FREE) sna->mode.shadow_enabled = false; assert(!sna->mode.shadow_enabled); if (sna->mode.flip_active) { DBG(("%s: flips still pending\n", __FUNCTION__)); - return false; + return FALSE; + } + + bo = get_flip_bo(pixmap); + if (bo == NULL) { + DBG(("%s: flip invalid bo\n", __FUNCTION__)); + return FALSE; } if (sync_flip) @@ -641,6 +676,8 @@ reset_mode: goto notify; } + assert(sna_pixmap(screen->GetScreenPixmap(screen))->pinned & PIN_SCANOUT); + if (sna->flags & SNA_HAS_ASYNC_FLIP) { DBG(("%s: trying async flip restore\n", __FUNCTION__)); if (flip__async(sna, NULL, event_id, 0, bo)) |