summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-02-16 12:29:24 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2015-02-16 16:01:48 +0000
commit10e40489e22f7e65c919082ffe2a37d5f000dcee (patch)
tree6054787a882e7de52fcee36322d8959dcb3e169c
parent1877c8f5081f3192dd30bb1162efd6acb1957487 (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.c3
-rw-r--r--src/sna/sna_dri2.c2
-rw-r--r--src/sna/sna_present.c53
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))