xf86-video-intel: 3 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Jun 3 05:50:15 PDT 2014
src/sna/kgem.c | 40 +++++++++++++++
src/sna/kgem.h | 1
src/sna/sna_accel.c | 136 ++++++++++++++++++++++++++++++----------------------
3 files changed, 121 insertions(+), 56 deletions(-)
New commits:
commit 8297c969ae749ef58d259b2ded2231b928efba43
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jun 3 09:47:27 2014 +0100
sna: Replace the bo for tiled uploads if not suitable and being replaced
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 20f4583..85c1c35 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4371,12 +4371,12 @@ static inline void box32_add_rect(Box32Rec *box, const xRectangle *r)
}
static bool
-create_upload_tiled_x(struct kgem *kgem,
- PixmapPtr pixmap,
- struct sna_pixmap *priv,
- bool replaces)
+can_create_upload_tiled_x(struct kgem *kgem,
+ PixmapPtr pixmap,
+ struct sna_pixmap *priv,
+ bool replaces)
{
- unsigned create, tiling;
+ unsigned tiling;
if (priv->shm || (priv->cpu && !replaces))
return false;
@@ -4384,10 +4384,26 @@ create_upload_tiled_x(struct kgem *kgem,
if ((priv->create & KGEM_CAN_CREATE_GPU) == 0)
return false;
+ if (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)
+ return false;
- if (!kgem->has_llc && tiling != I915_TILING_NONE)
+ return true;
+}
+
+static bool
+create_upload_tiled_x(struct kgem *kgem,
+ PixmapPtr pixmap,
+ struct sna_pixmap *priv,
+ bool replaces)
+{
+ unsigned create;
+
+ if (!can_create_upload_tiled_x(kgem, pixmap, priv, replaces))
return false;
assert(priv->gpu_bo == NULL);
@@ -4404,7 +4420,8 @@ create_upload_tiled_x(struct kgem *kgem,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel,
- tiling, create);
+ sna_pixmap_choose_tiling(pixmap, I915_TILING_X),
+ create);
return priv->gpu_bo != NULL;
}
@@ -4518,6 +4535,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
{
struct sna *sna = to_sna_from_pixmap(pixmap);
struct sna_pixmap *priv = sna_pixmap(pixmap);
+ bool ignore_cpu = false;
bool replaces;
BoxRec *box;
uint8_t *dst;
@@ -4540,11 +4558,15 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
if (priv->gpu_bo && replaces) {
if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
- if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
- DBG(("%s: discarding cached upload proxy\n", __FUNCTION__));
+ if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, true) &&
+ (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) ||
+ !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) {
+ DBG(("%s: discarding unusable target bo (busy? %d, mappable? %d)\n", __FUNCTION__,
+ kgem_bo_is_busy(priv->gpu_bo),
+ kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)));
sna_pixmap_free_gpu(sna, priv);
+ ignore_cpu = true;
}
- replaces = true; /* Mark it all GPU damaged afterwards */
}
assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
@@ -4557,15 +4579,19 @@ try_upload_tiled_x(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 (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
- DBG(("%s: discarding dirty pixmap\n", __FUNCTION__));
+ if (can_create_upload_tiled_x(&sna->kgem, 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__,
+ kgem_bo_is_busy(priv->gpu_bo),
+ kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)));
sna_pixmap_free_gpu(sna, priv);
+ ignore_cpu = priv->cpu_damage == NULL;
}
- replaces = true; /* Mark it all GPU damaged afterwards */
}
if (priv->gpu_bo == NULL &&
- !create_upload_tiled_x(&sna->kgem, pixmap, priv, replaces))
+ !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu))
return false;
DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling));
@@ -4692,6 +4718,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
if (priv->cpu_damage == NULL) {
list_del(&priv->flush_list);
sna_pixmap_free_cpu(sna, priv, priv->cpu);
+ priv->cpu = false;
}
}
commit 1c55d0447dba5bbde5be3903b273e04e3c9d084f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jun 3 12:43:51 2014 +0100
sna: Allow replacements to cancel operations between both bo under a Pixmap
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 3eb63d8..ea114f4 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2175,6 +2175,46 @@ void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo)
assert(bo->exec == NULL);
}
+void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b)
+{
+ if (kgem->nexec > 2)
+ return;
+
+ if (kgem->nexec == 1) {
+ if (a)
+ kgem_bo_undo(kgem, a);
+ if (b)
+ kgem_bo_undo(kgem, b);
+ return;
+ }
+
+ if (a == NULL || b == NULL)
+ return;
+ if (a->exec == NULL || b->exec == NULL)
+ return;
+
+ DBG(("%s: only handles in batch, discarding last operations for handle=%d and handle=%d\n",
+ __FUNCTION__, a->handle, b->handle));
+
+ assert(a->exec == &kgem->exec[0] || a->exec == &kgem->exec[1]);
+ assert(a->handle == kgem->exec[0].handle || a->handle == kgem->exec[1].handle);
+ assert(RQ(a->rq) == kgem->next_request);
+ assert(b->exec == &kgem->exec[0] || b->exec == &kgem->exec[1]);
+ assert(b->handle == kgem->exec[0].handle || b->handle == kgem->exec[1].handle);
+ assert(RQ(b->rq) == kgem->next_request);
+
+ a->refcnt++;
+ b->refcnt++;
+ kgem_reset(kgem);
+ b->refcnt--;
+ a->refcnt--;
+
+ assert(kgem->nreloc == 0);
+ assert(kgem->nexec == 0);
+ assert(a->exec == NULL);
+ assert(b->exec == NULL);
+}
+
static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
{
DBG(("%s: handle=%d, size=%d\n", __FUNCTION__, bo->handle, bytes(bo)));
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 6e61909..ae25821 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -548,6 +548,7 @@ static inline bool kgem_bo_is_snoop(struct kgem_bo *bo)
}
void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo);
+void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b);
bool __kgem_busy(struct kgem *kgem, int handle);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e4fad3b..20f4583 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -483,12 +483,15 @@ static void sna_pixmap_free_gpu(struct sna *sna, struct sna_pixmap *priv)
sna_damage_destroy(&priv->gpu_damage);
priv->clear = false;
- if (priv->gpu_bo && !priv->pinned) {
- assert(!priv->flush);
- assert(!priv->move_to_gpu);
- sna_pixmap_unmap(priv->pixmap, priv);
- kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
- priv->gpu_bo = NULL;
+ if (priv->gpu_bo) {
+ if (!priv->pinned) {
+ assert(!priv->flush);
+ assert(!priv->move_to_gpu);
+ sna_pixmap_unmap(priv->pixmap, priv);
+ kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
+ priv->gpu_bo = NULL;
+ } else
+ kgem_bo_undo(&sna->kgem, priv->gpu_bo);
}
/* and reset the upload counter */
@@ -1460,6 +1463,7 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap)
sna_damage_destroy(&priv->gpu_damage);
sna_damage_destroy(&priv->cpu_damage);
+ list_del(&priv->cow_list);
if (priv->cow) {
struct sna_cow *cow = COW(priv->cow);
DBG(("%s: pixmap=%ld discarding cow, refcnt=%d\n",
@@ -1468,8 +1472,8 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap)
if (!--cow->refcnt)
free(cow);
priv->cow = NULL;
- }
- list_del(&priv->cow_list);
+ } else
+ kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
if (priv->move_to_gpu)
(void)priv->move_to_gpu(sna, priv, 0);
@@ -2075,10 +2079,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
assert(priv->gpu_damage == NULL || priv->gpu_bo);
if ((flags & MOVE_READ) == 0 && UNDO) {
- if (priv->gpu_bo)
- kgem_bo_undo(&sna->kgem, priv->gpu_bo);
- if (priv->cpu_bo)
- kgem_bo_undo(&sna->kgem, priv->cpu_bo);
+ kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
if (priv->move_to_gpu)
sna_pixmap_discard_shadow_damage(priv, NULL);
}
@@ -3929,12 +3930,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
return NULL;
}
- if ((flags & MOVE_READ) == 0 && UNDO) {
- if (priv->gpu_bo)
- kgem_bo_undo(&sna->kgem, priv->gpu_bo);
- if (priv->cpu_bo)
- kgem_bo_undo(&sna->kgem, priv->cpu_bo);
- }
+ if ((flags & MOVE_READ) == 0 && UNDO)
+ kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
if (priv->cow && (flags & MOVE_WRITE || priv->cpu_damage)) {
if (!sna_pixmap_undo_cow(sna, priv, flags & MOVE_READ))
@@ -4542,8 +4539,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
}
if (priv->gpu_bo && replaces) {
- if (UNDO)
- kgem_bo_undo(&sna->kgem, priv->gpu_bo);
+ if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
DBG(("%s: discarding cached upload proxy\n", __FUNCTION__));
sna_pixmap_free_gpu(sna, priv);
@@ -4560,8 +4556,7 @@ try_upload_tiled_x(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 (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo);
if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
DBG(("%s: discarding dirty pixmap\n", __FUNCTION__));
sna_pixmap_free_gpu(sna, priv);
@@ -6013,7 +6008,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
if (n == 1) {
if (replaces && UNDO)
- kgem_bo_undo(&sna->kgem, bo);
+ kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
if (!sna->render.fill_one(sna,
dst_pixmap, bo, color,
@@ -6066,7 +6061,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
DBG(("%s: move whole src_pixmap to GPU and copy\n",
__FUNCTION__));
if (replaces && UNDO)
- kgem_bo_undo(&sna->kgem, bo);
+ kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
if (replaces &&
src_pixmap->drawable.width == dst_pixmap->drawable.width &&
@@ -6120,7 +6115,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
}
if (replaces && UNDO)
- kgem_bo_undo(&sna->kgem, bo);
+ kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
if (!sna->render.copy_boxes(sna, alu,
src_pixmap, src_priv->gpu_bo, src_dx, src_dy,
@@ -6158,7 +6153,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
}
if (replaces && UNDO)
- kgem_bo_undo(&sna->kgem, bo);
+ kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo);
if (src_priv->shm) {
assert(!src_priv->flush);
@@ -14321,7 +14316,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
goto fallback;
}
if (hint & REPLACES && (flags & 2) == 0 && UNDO)
- kgem_bo_undo(&sna->kgem, bo);
+ kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
if (gc_is_solid(gc, &color)) {
DBG(("%s: solid fill [%08x], testing for blt\n",
commit a82bfb033448eb61bf8cc7f5358be019f0cc28e6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jun 3 09:28:24 2014 +0100
sna: Discard unwanted damage when promoting to a full CPU migration
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 2513b8b..e4fad3b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2630,18 +2630,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
}
}
- if (flags & MOVE_WHOLE_HINT) {
- DBG(("%s: region (%d, %d), (%d, %d) marked with WHOLE hint, pixmap %dx%d\n",
- __FUNCTION__,
- region->extents.x1,
- region->extents.y1,
- region->extents.x2,
- region->extents.y2,
- pixmap->drawable.width,
- pixmap->drawable.height));
- return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
- }
-
if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
RegionTranslate(region, dx, dy);
@@ -2696,11 +2684,27 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (priv->clear && flags & MOVE_WRITE) {
DBG(("%s: pending clear, moving whole pixmap for partial write\n", __FUNCTION__));
+demote_to_cpu:
if (dx | dy)
RegionTranslate(region, -dx, -dy);
return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
}
+ if (flags & MOVE_WHOLE_HINT) {
+ DBG(("%s: region (%d, %d), (%d, %d) marked with WHOLE hint, pixmap %dx%d\n",
+ __FUNCTION__,
+ region->extents.x1,
+ region->extents.y1,
+ region->extents.x2,
+ region->extents.y2,
+ pixmap->drawable.width,
+ pixmap->drawable.height));
+move_to_cpu:
+ if ((flags & MOVE_READ) == 0)
+ sna_damage_subtract(&priv->gpu_damage, region);
+ goto demote_to_cpu;
+ }
+
sna_pixmap_unmap(pixmap, priv);
if (USE_INPLACE &&
@@ -2776,10 +2780,8 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (pixmap->devPrivate.ptr == NULL &&
!sna_pixmap_alloc_cpu(sna, pixmap, priv,
flags & MOVE_READ ? priv->gpu_damage && !priv->clear : 0)) {
- if (dx | dy)
- RegionTranslate(region, -dx, -dy);
DBG(("%s: CPU bo allocation failed, trying full move-to-cpu\n", __FUNCTION__));
- return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
+ goto move_to_cpu;
}
assert(priv->mapped == MAPPED_NONE);
assert(pixmap->devPrivate.ptr == PTR(priv->ptr));
More information about the xorg-commit
mailing list