diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-10-16 07:46:26 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-10-16 07:48:27 +0100 |
commit | 3812dfce175eeaef7f41632d2df6a0d88c0ae19b (patch) | |
tree | 02cc7505dbf5366da32812b7c5bae8070a099285 /src/sna/sna_render.c | |
parent | 9a5ca59d2b7b209e6f56dd3f94d4ae6f06e1ecdc (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.c | 78 |
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; +} |