sna: Do not undo a bo if we may fallback

If we undo the pending operations to a bo, then fallback we cause
corruption. For example, see wine and its 1-bit rendering.

Fixes regression from
commit 07a4400fff [2.21.7]
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri May 10 11:59:59 2013 +0100

    sna: Attempt to discard overwritten operations before CopyArea

Also we need to be more careful and consider alu when marking the
operation as 'replaces'.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-05-24 12:43:16 +01:00
parent 818702d3dc
commit f6c35e58c1
1 changed files with 24 additions and 9 deletions

View File

@ -4600,6 +4600,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
src_dx, src_dy);
replaces = n == 1 &&
alu_overwrites(alu) &&
box->x1 <= 0 &&
box->y1 <= 0 &&
box->x2 >= dst_pixmap->drawable.width &&
@ -4649,13 +4650,13 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
bo = sna_drawable_use_bo(&dst_pixmap->drawable, hint,
&region->extents, &damage);
if (bo) {
if (replaces)
kgem_bo_undo(&sna->kgem, bo);
if (src_priv && src_priv->clear) {
DBG(("%s: applying src clear[%08x] to dst\n",
__FUNCTION__, src_priv->clear_color));
if (n == 1) {
if (replaces)
kgem_bo_undo(&sna->kgem, bo);
if (!sna->render.fill_one(sna,
dst_pixmap, bo,
src_priv->clear_color,
@ -4666,6 +4667,16 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
__FUNCTION__));
goto fallback;
}
if (replaces && bo == dst_priv->gpu_bo) {
dst_priv->clear = true;
dst_priv->clear_color = src_priv->clear_color;
sna_damage_all(&dst_priv->gpu_damage,
dst_pixmap->drawable.width,
dst_pixmap->drawable.height);
sna_damage_destroy(&dst_priv->cpu_damage);
list_del(&dst_priv->flush_list);
}
} else {
struct sna_fill_op fill;
@ -4681,11 +4692,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
fill.done(sna, &fill);
}
if (replaces && bo == dst_priv->gpu_bo) {
dst_priv->clear = true;
dst_priv->clear_color = src_priv->clear_color;
}
if (damage)
sna_damage_add(damage, region);
return;
@ -4696,7 +4702,10 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
sna_pixmap_move_to_gpu(src_pixmap, MOVE_READ | MOVE_ASYNC_HINT)) {
DBG(("%s: move whole src_pixmap to GPU and copy\n",
__FUNCTION__));
if (replaces &&
if (replaces)
kgem_bo_undo(&sna->kgem, bo);
if (replaces && alu == GXcopy &&
src_pixmap->drawable.width == dst_pixmap->drawable.width &&
src_pixmap->drawable.height == dst_pixmap->drawable.height) {
assert(src_pixmap->drawable.depth == dst_pixmap->drawable.depth);
@ -4745,6 +4754,9 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
MOVE_READ | MOVE_ASYNC_HINT))
goto fallback;
if (replaces)
kgem_bo_undo(&sna->kgem, bo);
if (!sna->render.copy_boxes(sna, alu,
src_pixmap, src_priv->gpu_bo, src_dx, src_dy,
dst_pixmap, bo, 0, 0,
@ -4778,6 +4790,9 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
if (!ret)
goto fallback;
if (replaces)
kgem_bo_undo(&sna->kgem, bo);
if (src_priv->shm) {
assert(!src_priv->flush);
sna_add_flush_pixmap(sna, src_priv, src_priv->cpu_bo);