summaryrefslogtreecommitdiff
path: root/src/sna/sna_render.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-10-16 07:46:26 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-10-16 07:48:27 +0100
commit3812dfce175eeaef7f41632d2df6a0d88c0ae19b (patch)
tree02cc7505dbf5366da32812b7c5bae8070a099285 /src/sna/sna_render.c
parent9a5ca59d2b7b209e6f56dd3f94d4ae6f06e1ecdc (diff)
sna: Replace GPU render operations with CPU callbacks after wedged
If we find the GPU is wedged, replace some of the lowlevel render operations with CPU equivalents to simplify some fallbacks that still need to operate on GPU bo (such as copying DRI buffers). References: https://bugs.freedesktop.org/show_bug.cgi?id=85058 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_render.c')
-rw-r--r--src/sna/sna_render.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 8cc63a0d..22bc4910 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -2297,3 +2297,81 @@ cleanup_boxes:
return ret;
}
+
+static bool can_copy_cpu(struct sna *sna,
+ struct kgem_bo *src,
+ struct kgem_bo *dst)
+{
+ if (src->tiling != dst->tiling)
+ return false;
+
+ if (src->pitch != dst->pitch)
+ return false;
+
+ if (!kgem_bo_can_map__cpu(&sna->kgem, src, false))
+ return false;
+
+ if (!kgem_bo_can_map__cpu(&sna->kgem, dst, true))
+ return false;
+
+ DBG(("%s -- yes, src handle=%d, dst handle=%d\n", __FUNCTION__, src->handle, dst->handle));
+ return true;
+}
+
+bool
+memcpy_copy_boxes(struct sna *sna, uint8_t op,
+ const DrawableRec *src_draw, struct kgem_bo *src_bo, int16_t sx, int16_t sy,
+ const DrawableRec *dst_draw, struct kgem_bo *dst_bo, int16_t dx, int16_t dy,
+ const BoxRec *box, int n, unsigned flags)
+{
+ void *dst, *src;
+ bool clipped;
+
+ if (op != GXcopy)
+ return false;
+
+ clipped = (n > 1 ||
+ box->x1 + dx > 0 ||
+ box->y1 + dy > 0 ||
+ box->x2 + dx < dst_draw->width ||
+ box->y2 + dy < dst_draw->height);
+
+ dst = src = NULL;
+ if (!clipped && can_copy_cpu(sna, src_bo, dst_bo)) {
+ dst = kgem_bo_map__cpu(&sna->kgem, dst_bo);
+ src = kgem_bo_map__cpu(&sna->kgem, src_bo);
+ }
+
+ if (dst == NULL || src == NULL) {
+ dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
+ src = kgem_bo_map__gtt(&sna->kgem, src_bo);
+ if (dst == NULL || src == NULL)
+ return false;
+ } else {
+ kgem_bo_sync__cpu_full(&sna->kgem, dst_bo, true);
+ kgem_bo_sync__cpu_full(&sna->kgem, src_bo, false);
+ }
+
+ DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
+ __FUNCTION__, sx, sy, dx, dy, n));
+
+ if (sigtrap_get() == 0) {
+ do {
+ memcpy_blt(src, dst, dst_draw->bitsPerPixel,
+ src_bo->pitch, dst_bo->pitch,
+ box->x1 + sx, box->y1 + sy,
+ box->x1 + dx, box->y1 + dy,
+ box->x2 - box->x1, box->y2 - box->y1);
+ box++;
+ } while (--n);
+ sigtrap_put();
+ }
+
+ return true;
+}
+
+void
+sna_render_mark_wedged(struct sna *sna)
+{
+ sna->render.copy_boxes = memcpy_copy_boxes;
+}