diff --git a/src/sna/kgem.c b/src/sna/kgem.c index a6aa2757..234d1d06 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -282,6 +282,13 @@ static void assert_bo_retired(struct kgem_bo *bo) #define assert_bo_retired(bo) #endif +static void +__kgem_set_wedged(struct kgem *kgem) +{ + kgem->wedged = true; + sna_render_mark_wedged(container_of(kgem, struct sna, kgem)); +} + static void kgem_sna_reset(struct kgem *kgem) { struct sna *sna = container_of(kgem, struct sna, kgem); @@ -3343,7 +3350,7 @@ void _kgem_submit(struct kgem *kgem) if (!kgem->wedged) { xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR, "Failed to submit rendering commands, disabling acceleration.\n"); - kgem->wedged = true; + __kgem_set_wedged(kgem); } #if !NDEBUG @@ -3451,8 +3458,7 @@ void kgem_throttle(struct kgem *kgem) if (kgem->wedged) return; - kgem->wedged = __kgem_throttle(kgem, true); - if (kgem->wedged) { + if (__kgem_throttle(kgem, true)) { static int once; char path[128]; @@ -3465,6 +3471,7 @@ void kgem_throttle(struct kgem *kgem) once = 1; } + __kgem_set_wedged(kgem); kgem->need_throttle = false; } } diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 04ba786e..784caee8 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -862,74 +862,6 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg _kgem_set_mode(&sna->kgem, mode); } -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; -} - -static void -sna_dri2_copy_fallback(struct sna *sna, - const DrawableRec *draw, - struct kgem_bo *src_bo, int sx, int sy, - struct kgem_bo *dst_bo, int dx, int dy, - const BoxRec *box, int n) -{ - void *dst, *src; - bool clipped; - - clipped = (n > 1 || - box->x1 + sx > 0 || - box->y1 + sy > 0 || - box->x2 + sx < draw->width || - box->y2 + sy < 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; - } 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, 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(); - } -} - static bool is_front(int attachment) { return attachment == DRI2BufferFrontLeft; @@ -950,6 +882,7 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, struct kgem_bo *dst_bo; const BoxRec *boxes; int16_t dx, dy, sx, sy; + unsigned flags; int n; /* To hide a stale DRI2Buffer, one may choose to substitute @@ -1071,7 +1004,6 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, assert(dst_bo->refcnt); if (is_front(dst->attachment)) { struct sna_pixmap *priv; - unsigned int flags; flags = MOVE_WRITE | __MOVE_FORCE; if (clip.data) @@ -1135,38 +1067,32 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, } DamageRegionAppend(&pixmap->drawable, region); - if (wedged(sna)) { -fallback: - sna_dri2_copy_fallback(sna, src_draw, - src_bo, sx, sy, - dst_bo, dx, dy, - boxes, n); - } else { - unsigned flags; - DBG(("%s: copying [(%d, %d), (%d, %d)]x%d src=(%d, %d), dst=(%d, %d)\n", - __FUNCTION__, - boxes[0].x1, boxes[0].y1, - boxes[0].x2, boxes[0].y2, - n, sx, sy, dx, dy)); + DBG(("%s: copying [(%d, %d), (%d, %d)]x%d src=(%d, %d), dst=(%d, %d)\n", + __FUNCTION__, + boxes[0].x1, boxes[0].y1, + boxes[0].x2, boxes[0].y2, + n, sx, sy, dx, dy)); - flags = COPY_LAST; - if (sync) - flags |= COPY_SYNC; - if (!sna->render.copy_boxes(sna, GXcopy, - src_draw, src_bo, sx, sy, - dst_draw, dst_bo, dx, dy, - boxes, n, flags)) - goto fallback; + flags = COPY_LAST; + if (sync) + flags |= COPY_SYNC; + if (!sna->render.copy_boxes(sna, GXcopy, + src_draw, src_bo, sx, sy, + dst_draw, dst_bo, dx, dy, + boxes, n, flags)) + memcpy_copy_boxes(sna, GXcopy, + src_draw, src_bo, sx, sy, + dst_draw, dst_bo, dx, dy, + boxes, n, flags); - DBG(("%s: flushing? %d\n", __FUNCTION__, sync)); - if (sync) { /* STAT! */ - struct kgem_request *rq = sna->kgem.next_request; - kgem_submit(&sna->kgem); - if (rq->bo) { - bo = ref(rq->bo); - DBG(("%s: recording sync fence handle=%d\n", __FUNCTION__, bo->handle)); - } + DBG(("%s: flushing? %d\n", __FUNCTION__, sync)); + if (sync) { /* STAT! */ + struct kgem_request *rq = sna->kgem.next_request; + kgem_submit(&sna->kgem); + if (rq->bo) { + bo = ref(rq->bo); + DBG(("%s: recording sync fence handle=%d\n", __FUNCTION__, bo->handle)); } } 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; +} diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index 8b839de0..823b86cc 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -620,6 +620,8 @@ const char *gen6_render_init(struct sna *sna, const char *backend); const char *gen7_render_init(struct sna *sna, const char *backend); const char *gen8_render_init(struct sna *sna, const char *backend); +void sna_render_mark_wedged(struct sna *sna); + bool sna_tiling_composite(uint32_t op, PicturePtr src, PicturePtr mask, @@ -707,6 +709,11 @@ bool sna_blt_copy_boxes_fallback(struct sna *sna, uint8_t alu, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int nbox); +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); + bool _sna_get_pixel_from_rgba(uint32_t *pixel, uint16_t red, uint16_t green,