xf86-video-intel: 5 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_render.c src/sna/sna_render.h
Chris Wilson
ickle at kemper.freedesktop.org
Tue Jul 17 01:54:03 PDT 2012
src/sna/kgem.c | 15 ++++
src/sna/sna_accel.c | 157 ++++++++++++++++++++++++++++++++-------------------
src/sna/sna_blt.c | 154 +++++++++++---------------------------------------
src/sna/sna_render.c | 114 ++++++++++++++++++++++---------------
src/sna/sna_render.h | 6 +
5 files changed, 224 insertions(+), 222 deletions(-)
New commits:
commit 4f21dba6ee505217d63edd84611622e05aeb4593
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jul 17 09:26:46 2012 +0100
sna: Only drop the clear flag when writing to the GPU pixmap
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 c4a43a1..c4b6aba 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2103,7 +2103,6 @@ sna_pixmap_mark_active(struct sna *sna, struct sna_pixmap *priv)
if (!priv->pinned && priv->gpu_bo->proxy == NULL &&
(priv->create & KGEM_CAN_CREATE_LARGE) == 0)
list_move(&priv->inactive, &sna->active_pixmaps);
- priv->clear = false;
priv->cpu = false;
return priv;
}
@@ -2282,15 +2281,16 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
}
done:
- if (priv->cpu_damage == NULL &&
- flags & MOVE_WRITE &&
- box_inplace(pixmap, box)) {
- DBG(("%s: large operation on undamaged, promoting to full GPU\n",
- __FUNCTION__));
- sna_damage_all(&priv->gpu_damage,
- pixmap->drawable.width,
- pixmap->drawable.height);
- priv->undamaged = false;
+ if (flags & MOVE_WRITE) {
+ priv->clear = false;
+ if (priv->cpu_damage == NULL && box_inplace(pixmap, box)) {
+ DBG(("%s: large operation on undamaged, promoting to full GPU\n",
+ __FUNCTION__));
+ sna_damage_all(&priv->gpu_damage,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
+ priv->undamaged = false;
+ }
}
assert(!priv->gpu_bo->proxy || (flags & MOVE_WRITE) == 0);
@@ -2766,6 +2766,8 @@ done:
sna_pixmap_free_cpu(sna, priv);
}
}
+ if (flags & MOVE_WRITE)
+ priv->clear = false;
active:
assert(!priv->gpu_bo->proxy || (flags & MOVE_WRITE) == 0);
return sna_pixmap_mark_active(sna, priv);
commit fbfbbee8288aba1e4754fd2dbc02e71f5e118cda
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jul 17 09:20:21 2012 +0100
sna: Fix glyph DBG to include clip extents and actual glyph origin
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 308f52f..c4a43a1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -10942,6 +10942,12 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
_kgem_submit(&sna->kgem);
_kgem_set_mode(&sna->kgem, KGEM_BLT);
}
+
+ DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ extents->x1, extents->y1,
+ extents->x2, extents->y2));
+
b = sna->kgem.batch + sna->kgem.nbatch;
b[0] = XY_SETUP_BLT | 3 << 20;
b[1] = bo->pitch;
@@ -10984,12 +10990,12 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
goto skip;
len = (w8 * h + 7) >> 3 << 1;
- DBG(("%s glyph: (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__,
- x,y, w, w8, h, len));
-
x1 = x + c->metrics.leftSideBearing;
y1 = y - c->metrics.ascent;
+ DBG(("%s glyph: (%d, %d) -> (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__,
+ x,y, x1, y1, w, w8, h, len));
+
if (x1 >= extents->x2 || y1 >= extents->y2)
goto skip;
if (x1 + w <= extents->x1 || y1 + h <= extents->y1)
@@ -11000,6 +11006,11 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
_kgem_submit(&sna->kgem);
_kgem_set_mode(&sna->kgem, KGEM_BLT);
+ DBG(("%s: new batch, glyph clip box (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ extents->x1, extents->y1,
+ extents->x2, extents->y2));
+
b = sna->kgem.batch + sna->kgem.nbatch;
b[0] = XY_SETUP_BLT | 3 << 20;
b[1] = bo->pitch;
@@ -11059,6 +11070,11 @@ skip:
b = sna->kgem.batch + sna->kgem.nbatch;
sna->kgem.nbatch += 3;
+ DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ extents->x1, extents->y1,
+ extents->x2, extents->y2));
+
b[0] = XY_SETUP_CLIP;
b[1] = extents->y1 << 16 | extents->x1;
b[2] = extents->y2 << 16 | extents->x2;
@@ -11637,6 +11653,11 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
_kgem_submit(&sna->kgem);
_kgem_set_mode(&sna->kgem, KGEM_BLT);
}
+
+ DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ extents->x1, extents->y1,
+ extents->x2, extents->y2));
b = sna->kgem.batch + sna->kgem.nbatch;
b[0] = XY_SETUP_BLT | 1 << 20;
b[1] = bo->pitch;
@@ -11675,12 +11696,12 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
goto skip;
len = (w8 * h + 7) >> 3 << 1;
- DBG(("%s glyph: (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__,
- x,y, w, w8, h, len));
-
x1 = x + c->metrics.leftSideBearing;
y1 = y - c->metrics.ascent;
+ DBG(("%s glyph: (%d, %d) -> (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__,
+ x,y, x1, y1, w, w8, h, len));
+
if (x1 >= extents->x2 || y1 >= extents->y2 ||
x1 + w <= extents->x1 || y1 + h <= extents->y1) {
DBG(("%s: glyph is clipped (%d, %d)x(%d,%d) against extents (%d, %d), (%d, %d)\n",
@@ -11713,6 +11734,11 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
_kgem_submit(&sna->kgem);
_kgem_set_mode(&sna->kgem, KGEM_BLT);
+ DBG(("%s: new batch, glyph clip box (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ extents->x1, extents->y1,
+ extents->x2, extents->y2));
+
b = sna->kgem.batch + sna->kgem.nbatch;
b[0] = XY_SETUP_BLT | 1 << 20;
b[1] = bo->pitch;
@@ -11778,6 +11804,11 @@ skip:
b = sna->kgem.batch + sna->kgem.nbatch;
sna->kgem.nbatch += 3;
+ DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ extents->x1, extents->y1,
+ extents->x2, extents->y2));
+
b[0] = XY_SETUP_CLIP;
b[1] = extents->y1 << 16 | extents->x1;
b[2] = extents->y2 << 16 | extents->x2;
commit f0ed0ca234a4bed986824845ff70e8554c0e579f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jul 17 08:35:20 2012 +0100
sna: Promote an undamaged pixmap to use the full GPU
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 6c069ee..308f52f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2135,12 +2135,16 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
sna_damage_reduce(&priv->cpu_damage);
assert_pixmap_damage(pixmap);
+ if (priv->cpu_damage == NULL) {
+ priv->undamaged = false;
+ list_del(&priv->list);
+ return sna_pixmap_move_to_gpu(pixmap, flags);
+ }
+
if (priv->gpu_bo == NULL) {
unsigned create, tiling;
- create = 0;
- if (priv->cpu_damage)
- create |= CREATE_INACTIVE;
+ create = CREATE_INACTIVE;
if (pixmap->usage_hint == SNA_CREATE_FB)
create |= CREATE_EXACT | CREATE_SCANOUT;
@@ -2156,22 +2160,9 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
return false;
DBG(("%s: created gpu bo\n", __FUNCTION__));
-
- if (flags & MOVE_WRITE && priv->cpu_damage == NULL) {
- sna_damage_all(&priv->gpu_damage,
- pixmap->drawable.width,
- pixmap->drawable.height);
- list_del(&priv->list);
- goto done;
- }
}
assert(priv->gpu_bo->proxy == NULL);
- if (priv->cpu_damage == NULL) {
- list_del(&priv->list);
- goto done;
- }
-
if (priv->mapped) {
pixmap->devPrivate.ptr = NULL;
priv->mapped = false;
commit 1f79e877fb6602bd0f9dd14ac9c3511f3b7044fb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jul 16 21:18:24 2012 +0100
sna: Share the pixmap migration decision with the BLT composite routines
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 d7ecb00..6c069ee 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -425,8 +425,8 @@ sna_pixmap_alloc_cpu(struct sna *sna,
pixmap->drawable.bitsPerPixel,
from_gpu ? 0 : CREATE_CPU_MAP | CREATE_INACTIVE);
if (priv->cpu_bo) {
- DBG(("%s: allocated CPU handle=%d\n", __FUNCTION__,
- priv->cpu_bo->handle));
+ DBG(("%s: allocated CPU handle=%d (vmap? %d)\n", __FUNCTION__,
+ priv->cpu_bo->handle, priv->cpu_bo->vmap));
priv->ptr = kgem_bo_map__cpu(&sna->kgem, priv->cpu_bo);
priv->stride = priv->cpu_bo->pitch;
@@ -525,7 +525,17 @@ static inline uint32_t default_tiling(PixmapPtr pixmap,
if (sna->kgem.gen == 21)
return I915_TILING_X;
- if (sna_damage_is_all(&priv->cpu_damage,
+ /* Only on later generations was the render pipeline
+ * more flexible than the BLT. So on gen2/3, prefer to
+ * keep large objects accessible through the BLT.
+ */
+ if (sna->kgem.gen < 40 &&
+ (pixmap->drawable.width > sna->render.max_3d_size ||
+ pixmap->drawable.height > sna->render.max_3d_size))
+ return I915_TILING_X;
+
+ if (tiling == I915_TILING_Y &&
+ sna_damage_is_all(&priv->cpu_damage,
pixmap->drawable.width,
pixmap->drawable.height)) {
DBG(("%s: entire source is damaged, using Y-tiling\n",
@@ -533,15 +543,6 @@ static inline uint32_t default_tiling(PixmapPtr pixmap,
sna_damage_destroy(&priv->gpu_damage);
priv->undamaged = false;
- /* Only on later generations was the render pipeline
- * more flexible than the BLT. So on gen2/3, prefer to
- * keep large objects accessible through the BLT.
- */
- if (sna->kgem.gen < 40 &&
- (pixmap->drawable.width > sna->render.max_3d_size ||
- pixmap->drawable.height > sna->render.max_3d_size))
- return I915_TILING_X;
-
return I915_TILING_Y;
}
@@ -1089,7 +1090,8 @@ static inline bool use_cpu_bo_for_download(struct sna *sna,
return priv->cpu_bo != NULL && sna->kgem.can_blt_cpu;
}
-static inline bool use_cpu_bo_for_upload(struct sna_pixmap *priv)
+static inline bool use_cpu_bo_for_upload(struct sna_pixmap *priv,
+ unsigned flags)
{
if (DBG_NO_CPU_UPLOAD)
return false;
@@ -1097,6 +1099,14 @@ static inline bool use_cpu_bo_for_upload(struct sna_pixmap *priv)
if (priv->cpu_bo == NULL)
return false;
+ DBG(("%s? flags=%x, gpu busy?=%d, cpu busy?=%d\n", __FUNCTION__,
+ flags,
+ kgem_bo_is_busy(priv->gpu_bo),
+ kgem_bo_is_busy(priv->cpu_bo)));
+
+ if (flags & (MOVE_WRITE | MOVE_ASYNC_HINT))
+ return true;
+
return kgem_bo_is_busy(priv->gpu_bo) || kgem_bo_is_busy(priv->cpu_bo);
}
@@ -2135,14 +2145,13 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
create |= CREATE_EXACT | CREATE_SCANOUT;
tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING;
+ tiling = sna_pixmap_choose_tiling(pixmap, tiling);
priv->gpu_bo = kgem_create_2d(&sna->kgem,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel,
- sna_pixmap_choose_tiling(pixmap,
- tiling),
- create);
+ tiling, create);
if (priv->gpu_bo == NULL)
return false;
@@ -2182,7 +2191,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
if (n) {
bool ok = false;
- if (use_cpu_bo_for_upload(priv)) {
+ if (use_cpu_bo_for_upload(priv, 0)) {
DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->cpu_bo, 0, 0,
@@ -2222,7 +2231,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
} else if (DAMAGE_IS_ALL(priv->cpu_damage) ||
sna_damage_contains_box__no_reduce(priv->cpu_damage, box)) {
bool ok = false;
- if (use_cpu_bo_for_upload(priv)) {
+ if (use_cpu_bo_for_upload(priv, 0)) {
DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->cpu_bo, 0, 0,
@@ -2253,7 +2262,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
box = REGION_RECTS(&i);
ok = false;
- if (use_cpu_bo_for_upload(priv)) {
+ if (use_cpu_bo_for_upload(priv, 0)) {
DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->cpu_bo, 0, 0,
@@ -2641,17 +2650,25 @@ 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;
+
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);
+
+ create = 0;
+ if (priv->cpu_damage && priv->cpu_bo == NULL)
+ create = CREATE_GTT_MAP | CREATE_INACTIVE;
+
priv->gpu_bo =
kgem_create_2d(&sna->kgem,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel,
- sna_pixmap_choose_tiling(pixmap,
- DEFAULT_TILING),
- (priv->cpu_damage && priv->cpu_bo == NULL) ? CREATE_GTT_MAP | CREATE_INACTIVE : 0);
+ tiling, create);
}
if (priv->gpu_bo == NULL) {
DBG(("%s: not creating GPU bo\n", __FUNCTION__));
@@ -2698,8 +2715,11 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
assert(pixmap_contains_damage(pixmap, priv->cpu_damage));
DBG(("%s: uploading %d damage boxes\n", __FUNCTION__, n));
+ if (DAMAGE_IS_ALL(priv->cpu_damage))
+ flags |= MOVE_ASYNC_HINT;
+
ok = false;
- if (use_cpu_bo_for_upload(priv)) {
+ if (use_cpu_bo_for_upload(priv, flags)) {
DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
ok = sna->render.copy_boxes(sna, GXcopy,
pixmap, priv->cpu_bo, 0, 0,
@@ -3055,7 +3075,8 @@ static bool upload_inplace(struct sna *sna,
}
if (priv->gpu_bo) {
- assert(priv->gpu_bo->proxy == NULL);
+ if (priv->gpu_bo->proxy)
+ return false;
if (!kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) {
DBG(("%s? no, GPU bo not mappable\n", __FUNCTION__));
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 80fad6d..ff8e3eb 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1138,20 +1138,20 @@ blt_composite_copy_boxes_with_alpha(struct sna *sna,
static bool
prepare_blt_copy(struct sna *sna,
struct sna_composite_op *op,
+ struct kgem_bo *bo,
uint32_t alpha_fixup)
{
PixmapPtr src = op->u.blt.src_pixmap;
- struct sna_pixmap *priv = sna_pixmap(src);
- if (!kgem_bo_can_blt(&sna->kgem, priv->gpu_bo)) {
+ if (!kgem_bo_can_blt(&sna->kgem, bo)) {
DBG(("%s: fallback -- can't blt from source\n", __FUNCTION__));
return false;
}
- if (!kgem_check_many_bo_fenced(&sna->kgem, op->dst.bo, priv->gpu_bo, NULL)) {
+ if (!kgem_check_many_bo_fenced(&sna->kgem, op->dst.bo, bo, NULL)) {
_kgem_submit(&sna->kgem);
if (!kgem_check_many_bo_fenced(&sna->kgem,
- op->dst.bo, priv->gpu_bo, NULL)) {
+ op->dst.bo, bo, NULL)) {
DBG(("%s: fallback -- no room in aperture\n", __FUNCTION__));
return false;
}
@@ -1170,9 +1170,7 @@ prepare_blt_copy(struct sna *sna,
op->box = blt_composite_copy_box_with_alpha;
op->boxes = blt_composite_copy_boxes_with_alpha;
- if (!sna_blt_alpha_fixup_init(sna, &op->u.blt,
- priv->gpu_bo,
- op->dst.bo,
+ if (!sna_blt_alpha_fixup_init(sna, &op->u.blt, bo, op->dst.bo,
src->drawable.bitsPerPixel,
alpha_fixup))
return false;
@@ -1181,15 +1179,13 @@ prepare_blt_copy(struct sna *sna,
op->box = blt_composite_copy_box;
op->boxes = blt_composite_copy_boxes;
- if (!sna_blt_copy_init(sna, &op->u.blt,
- priv->gpu_bo,
- op->dst.bo,
+ if (!sna_blt_copy_init(sna, &op->u.blt, bo, op->dst.bo,
src->drawable.bitsPerPixel,
GXcopy))
return false;
}
- return begin_blt(sna, op);
+ return true;
}
fastcall static void
@@ -1434,119 +1430,33 @@ prepare_blt_put(struct sna *sna,
uint32_t alpha_fixup)
{
PixmapPtr src = op->u.blt.src_pixmap;
- struct sna_pixmap *priv;
- struct kgem_bo *src_bo;
DBG(("%s\n", __FUNCTION__));
- op->done = nop_done;
+ if (!sna_pixmap_move_to_cpu(src, MOVE_READ))
+ return false;
- src_bo = NULL;
- priv = sna_pixmap(src);
- if (priv)
- src_bo = priv->cpu_bo;
- if (src_bo) {
- if (alpha_fixup) {
- op->blt = blt_composite_copy_with_alpha;
- op->box = blt_composite_copy_box_with_alpha;
- op->boxes = blt_composite_copy_boxes_with_alpha;
-
- if (!sna_blt_alpha_fixup_init(sna, &op->u.blt,
- src_bo, op->dst.bo,
- op->dst.pixmap->drawable.bitsPerPixel,
- alpha_fixup))
- return false;
- } else {
- op->blt = blt_composite_copy;
- op->box = blt_composite_copy_box;
- op->boxes = blt_composite_copy_boxes;
-
- if (!sna_blt_copy_init(sna, &op->u.blt,
- src_bo, op->dst.bo,
- op->dst.pixmap->drawable.bitsPerPixel,
- GXcopy))
- return false;
- }
+ assert(src->devKind);
+ assert(src->devPrivate.ptr);
- return begin_blt(sna, op);
- } else {
- if (!sna_pixmap_move_to_cpu(src, MOVE_READ))
- return false;
+ if (alpha_fixup)
+ return false; /* XXX */
- assert(src->devKind);
- assert(src->devPrivate.ptr);
-
- if (alpha_fixup)
- return false; /* XXX */
-
- if (alpha_fixup) {
- op->u.blt.pixel = alpha_fixup;
- op->blt = blt_put_composite_with_alpha;
- op->box = blt_put_composite_box_with_alpha;
- op->boxes = blt_put_composite_boxes_with_alpha;
- } else {
- op->blt = blt_put_composite;
- op->box = blt_put_composite_box;
- op->boxes = blt_put_composite_boxes;
- }
+ if (alpha_fixup) {
+ op->u.blt.pixel = alpha_fixup;
+ op->blt = blt_put_composite_with_alpha;
+ op->box = blt_put_composite_box_with_alpha;
+ op->boxes = blt_put_composite_boxes_with_alpha;
+ } else {
+ op->blt = blt_put_composite;
+ op->box = blt_put_composite_box;
+ op->boxes = blt_put_composite_boxes;
}
+ op->done = nop_done;
return true;
}
-static bool
-has_gpu_area(PixmapPtr pixmap, int x, int y, int w, int h)
-{
- struct sna_pixmap *priv = sna_pixmap(pixmap);
- BoxRec area;
-
- if (!priv)
- return false;
- if (!priv->gpu_bo)
- return false;
-
- if (priv->cpu_damage == NULL)
- return true;
- if (priv->cpu_damage->mode == DAMAGE_ALL)
- return false;
-
- area.x1 = x;
- area.y1 = y;
- area.x2 = x + w;
- area.y2 = y + h;
- if (priv->gpu_damage &&
- sna_damage_contains_box__no_reduce(priv->gpu_damage, &area))
- return true;
-
- return sna_damage_contains_box(priv->cpu_damage,
- &area) == PIXMAN_REGION_OUT;
-}
-
-static bool
-has_cpu_area(PixmapPtr pixmap, int x, int y, int w, int h)
-{
- struct sna_pixmap *priv = sna_pixmap(pixmap);
- BoxRec area;
-
- if (!priv)
- return true;
- if (priv->gpu_damage == NULL)
- return true;
- if (priv->gpu_damage->mode == DAMAGE_ALL)
- return false;
-
- area.x1 = x;
- area.y1 = y;
- area.x2 = x + w;
- area.y2 = y + h;
- if (priv->cpu_damage &&
- sna_damage_contains_box__no_reduce(priv->cpu_damage, &area))
- return true;
-
- return sna_damage_contains_box(priv->gpu_damage,
- &area) == PIXMAN_REGION_OUT;
-}
-
static void
reduce_damage(struct sna_composite_op *op,
int dst_x, int dst_y,
@@ -1592,7 +1502,9 @@ sna_blt_composite(struct sna *sna,
PictFormat src_format = src->format;
PixmapPtr src_pixmap;
struct sna_pixmap *priv;
+ struct kgem_bo *bo;
int16_t tx, ty;
+ BoxRec box;
uint32_t alpha_fixup;
bool was_clear;
bool ret;
@@ -1748,13 +1660,15 @@ clear:
__FUNCTION__,
tmp->dst.x, tmp->dst.y, tmp->u.blt.sx, tmp->u.blt.sy, alpha_fixup));
- if (has_gpu_area(src_pixmap, x, y, width, height))
- ret = prepare_blt_copy(sna, tmp, alpha_fixup);
- else if (has_cpu_area(src_pixmap, x, y, width, height))
- ret = prepare_blt_put(sna, tmp, alpha_fixup);
- else if (sna_pixmap_move_to_gpu(src_pixmap, MOVE_READ))
- ret = prepare_blt_copy(sna, tmp, alpha_fixup);
- else
+ ret = false;
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + width;
+ box.y2 = y + height;
+ bo = __sna_render_pixmap_bo(sna, src_pixmap, &box, true);
+ if (bo)
+ ret = prepare_blt_copy(sna, tmp, bo, alpha_fixup);
+ if (!ret)
ret = prepare_blt_put(sna, tmp, alpha_fixup);
return ret;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index dcfab91..6fb9fe3 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -288,7 +288,7 @@ void no_render_init(struct sna *sna)
}
static struct kgem_bo *
-use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box)
+use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt)
{
struct sna_pixmap *priv;
@@ -322,24 +322,40 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box)
break;
}
- if (priv->gpu_bo->tiling != I915_TILING_NONE &&
+ if (!blt &&
+ priv->gpu_bo->tiling != I915_TILING_NONE &&
(priv->cpu_bo->vmap || priv->cpu_bo->pitch >= 4096)) {
DBG(("%s: GPU bo exists and is tiled [%d], upload\n",
__FUNCTION__, priv->gpu_bo->tiling));
return NULL;
}
+ }
+
+ if (blt) {
+ if (priv->cpu_bo->vmap && priv->source_count++ > SOURCE_BIAS) {
+ DBG(("%s: promoting snooped CPU bo due to BLT reuse\n",
+ __FUNCTION__));
+ return NULL;
+ }
} else {
int w = box->x2 - box->x1;
int h = box->y2 - box->y1;
+ if (priv->cpu_bo->pitch >= 4096) {
+ DBG(("%s: promoting snooped CPU bo due to TLB miss\n",
+ __FUNCTION__));
+ return NULL;
+ }
+
if (priv->cpu_bo->vmap && priv->source_count > SOURCE_BIAS) {
DBG(("%s: promoting snooped CPU bo due to reuse\n",
__FUNCTION__));
return NULL;
}
- if (priv->source_count++*w*h >= (int)pixmap->drawable.width * pixmap->drawable.height &&
- I915_TILING_NONE != kgem_choose_tiling(&sna->kgem, I915_TILING_Y,
+ if (priv->source_count*w*h >= (int)pixmap->drawable.width * pixmap->drawable.height &&
+ I915_TILING_NONE != kgem_choose_tiling(&sna->kgem,
+ blt ? I915_TILING_X : I915_TILING_Y,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel)) {
@@ -347,15 +363,20 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box)
__FUNCTION__, priv->cpu_bo->pitch));
return NULL;
}
+
+ ++priv->source_count;
}
DBG(("%s for box=(%d, %d), (%d, %d)\n",
__FUNCTION__, box->x1, box->y1, box->x2, box->y2));
+ if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_ASYNC_HINT))
+ return NULL;
+
return priv->cpu_bo;
}
static struct kgem_bo *
-move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
+move_to_gpu(PixmapPtr pixmap, const BoxRec *box, bool blt)
{
struct sna_pixmap *priv;
int count, w, h;
@@ -390,7 +411,7 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
if (DBG_FORCE_UPLOAD < 0) {
if (!sna_pixmap_force_to_gpu(pixmap,
- MOVE_SOURCE_HINT | MOVE_READ))
+ blt ? MOVE_READ : MOVE_SOURCE_HINT | MOVE_READ))
return NULL;
return priv->gpu_bo;
@@ -407,7 +428,7 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
box->x1, box->y1, box->x2, box->y2, priv->source_count,
migrate));
} else if (kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem,
- I915_TILING_Y, w, h,
+ blt ? I915_TILING_X : I915_TILING_Y, w, h,
pixmap->drawable.bitsPerPixel) != I915_TILING_NONE) {
count = priv->source_count++;
if ((priv->create & KGEM_CAN_CREATE_GPU) == 0)
@@ -424,7 +445,7 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
}
if (migrate && !sna_pixmap_force_to_gpu(pixmap,
- MOVE_SOURCE_HINT | MOVE_READ))
+ blt ? MOVE_READ : MOVE_SOURCE_HINT | MOVE_READ))
return NULL;
return priv->gpu_bo;
@@ -465,13 +486,11 @@ static struct kgem_bo *upload(struct sna *sna,
pixmap->devPrivate.ptr, box,
pixmap->devKind,
pixmap->drawable.bitsPerPixel);
- if (bo) {
+ if (channel && bo) {
channel->width = box->x2 - box->x1;
channel->height = box->y2 - box->y1;
channel->offset[0] -= box->x1;
channel->offset[1] -= box->y1;
- channel->scale[0] = 1.f/channel->width;
- channel->scale[1] = 1.f/channel->height;
if (priv &&
pixmap->usage_hint == 0 &&
@@ -483,6 +502,24 @@ static struct kgem_bo *upload(struct sna *sna,
return bo;
}
+struct kgem_bo *
+__sna_render_pixmap_bo(struct sna *sna,
+ PixmapPtr pixmap,
+ const BoxRec *box,
+ bool blt)
+{
+ struct kgem_bo *bo;
+
+ bo = use_cpu_bo(sna, pixmap, box, blt);
+ if (bo == NULL) {
+ bo = move_to_gpu(pixmap, box, blt);
+ if (bo == NULL)
+ return NULL;
+ }
+
+ return bo;
+}
+
int
sna_render_pixmap_bo(struct sna *sna,
struct sna_composite_channel *channel,
@@ -491,7 +528,6 @@ sna_render_pixmap_bo(struct sna *sna,
int16_t w, int16_t h,
int16_t dst_x, int16_t dst_y)
{
- struct kgem_bo *bo;
struct sna_pixmap *priv;
BoxRec box;
@@ -500,8 +536,6 @@ sna_render_pixmap_bo(struct sna *sna,
channel->width = pixmap->drawable.width;
channel->height = pixmap->drawable.height;
- channel->scale[0] = 1.f / pixmap->drawable.width;
- channel->scale[1] = 1.f / pixmap->drawable.height;
channel->offset[0] = x - dst_x;
channel->offset[1] = y - dst_y;
@@ -511,16 +545,16 @@ sna_render_pixmap_bo(struct sna *sna,
(DAMAGE_IS_ALL(priv->gpu_damage) || !priv->cpu_damage ||
priv->gpu_bo->proxy)) {
DBG(("%s: GPU all damaged\n", __FUNCTION__));
- channel->bo = kgem_bo_reference(priv->gpu_bo);
- return 1;
+ channel->bo = priv->gpu_bo;
+ goto done;
}
if (priv->cpu_bo &&
(DAMAGE_IS_ALL(priv->cpu_damage) || !priv->gpu_damage) &&
!priv->cpu_bo->vmap && priv->cpu_bo->pitch < 4096) {
DBG(("%s: CPU all damaged\n", __FUNCTION__));
- channel->bo = kgem_bo_reference(priv->cpu_bo);
- return 1;
+ channel->bo = priv->cpu_bo;
+ goto done;
}
}
@@ -572,21 +606,22 @@ sna_render_pixmap_bo(struct sna *sna,
channel->offset[0], channel->offset[1],
pixmap->drawable.width, pixmap->drawable.height));
- bo = use_cpu_bo(sna, pixmap, &box);
- if (bo) {
- bo = kgem_bo_reference(bo);
+
+ channel->bo = __sna_render_pixmap_bo(sna, pixmap, &box, false);
+ if (channel->bo == NULL) {
+ DBG(("%s: uploading CPU box (%d, %d), (%d, %d)\n",
+ __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+ channel->bo = upload(sna, channel, pixmap, &box);
+ if (channel->bo == NULL)
+ return 0;
} else {
- bo = move_to_gpu(pixmap, &box);
- if (bo == NULL) {
- DBG(("%s: uploading CPU box (%d, %d), (%d, %d)\n",
- __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
- bo = upload(sna, channel, pixmap, &box);
- } else
- bo = kgem_bo_reference(bo);
+done:
+ kgem_bo_reference(channel->bo);
}
- channel->bo = bo;
- return bo != NULL;
+ channel->scale[0] = 1.f / channel->width;
+ channel->scale[1] = 1.f / channel->height;
+ return 1;
}
static int sna_render_picture_downsample(struct sna *sna,
@@ -929,14 +964,11 @@ sna_render_picture_partial(struct sna *sna,
}
}
- if (use_cpu_bo(sna, pixmap, &box)) {
- if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
- return 0;
-
+ if (use_cpu_bo(sna, pixmap, &box, false)) {
bo = sna_pixmap(pixmap)->cpu_bo;
} else {
if (!sna_pixmap_force_to_gpu(pixmap,
- MOVE_SOURCE_HINT | MOVE_READ))
+ MOVE_READ | MOVE_SOURCE_HINT))
return 0;
bo = sna_pixmap(pixmap)->gpu_bo;
@@ -1119,12 +1151,9 @@ sna_render_picture_extract(struct sna *sna,
dst_x, dst_y);
}
- src_bo = use_cpu_bo(sna, pixmap, &box);
- if (src_bo) {
- if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
- return 0;
- } else {
- src_bo = move_to_gpu(pixmap, &box);
+ src_bo = use_cpu_bo(sna, pixmap, &box, true);
+ if (src_bo == NULL) {
+ src_bo = move_to_gpu(pixmap, &box, false);
if (src_bo == NULL) {
bo = kgem_upload_source_image(&sna->kgem,
pixmap->devPrivate.ptr,
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 7c43f61..0f96ace 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -619,6 +619,12 @@ sna_get_pixel_from_rgba(uint32_t * pixel,
return _sna_get_pixel_from_rgba(pixel, red, green, blue, alpha, format);
}
+struct kgem_bo *
+__sna_render_pixmap_bo(struct sna *sna,
+ PixmapPtr pixmap,
+ const BoxRec *box,
+ bool blt);
+
int
sna_render_pixmap_bo(struct sna *sna,
struct sna_composite_channel *channel,
commit d141a2d59007866c9eaad020c744be446e70c346
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jul 16 23:20:58 2012 +0100
sna: Disable snoopable bo for gen4
Further inspection reveals that whilst it may not hang the GPU, the
results are not pleasant or complete.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index d6ed4e0..d30b8e7 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -687,6 +687,10 @@ static bool test_has_cache_level(struct kgem *kgem)
if (DBG_NO_CACHE_LEVEL)
return false;
+ /* Incoherent blt and sampler hangs the GPU */
+ if (kgem->gen == 40)
+ return false;
+
handle = gem_create(kgem->fd, 1);
if (handle == 0)
return false;
@@ -705,6 +709,10 @@ static bool test_has_vmap(struct kgem *kgem)
if (DBG_NO_VMAP)
return false;
+ /* Incoherent blt and sampler hangs the GPU */
+ if (kgem->gen == 40)
+ return false;
+
return gem_param(kgem, I915_PARAM_HAS_VMAP) > 0;
#else
return false;
@@ -3102,6 +3110,8 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
if (bo == NULL)
return bo;
+ assert(bo->tiling == I915_TILING_NONE);
+
if (kgem_bo_map__cpu(kgem, bo) == NULL) {
kgem_bo_destroy(kgem, bo);
return NULL;
@@ -3116,6 +3126,8 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
if (bo == NULL)
return NULL;
+ assert(bo->tiling == I915_TILING_NONE);
+
bo->reusable = false;
bo->vmap = true;
if (!gem_set_cache_level(kgem->fd, bo->handle, I915_CACHE_LLC) ||
@@ -3816,8 +3828,7 @@ static struct kgem_partial_bo *partial_bo_alloc(int num_pages)
static inline bool
use_snoopable_buffer(struct kgem *kgem, uint32_t flags)
{
- if (kgem->gen == 40)
- return false;
+ assert(kgem->gen != 40);
if (kgem->gen < 30)
return flags & KGEM_BUFFER_WRITE;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index ab7fb81..dcfab91 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -301,9 +301,6 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box)
return NULL;
}
- if (sna->kgem.gen == 40) /* XXX sampler dies with snoopable memory */
- return NULL;
-
if (priv->gpu_bo) {
switch (sna_damage_contains_box(priv->cpu_damage, box)) {
case PIXMAN_REGION_OUT:
More information about the xorg-commit
mailing list