From 08d8a47e7c8b9bcb5bb317be4623161e58e0e0cc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 3 Nov 2013 19:51:56 +0000 Subject: [PATCH] sna: Wrap staging buffer access with sigtrap handler Signed-off-by: Chris Wilson --- src/sna/sna_io.c | 392 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 217 insertions(+), 175 deletions(-) diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index db56f56..bad6052 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -225,7 +225,6 @@ void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo, BoxRec extents; const BoxRec *tmp_box; int tmp_nbox; - char *src; void *ptr; int src_pitch, cpp, offset; int n, cmd, br13; @@ -375,14 +374,17 @@ fallback: kgem_bo_submit(&sna->kgem, dst_bo); kgem_buffer_read_sync(kgem, dst_bo); - while (c-- != clipped) { - memcpy_blt(ptr, dst->devPrivate.ptr, tmp.drawable.bitsPerPixel, - dst_bo->pitch, dst->devKind, - c->x1 - tile.x1, - c->y1 - tile.y1, - c->x1, c->y1, - c->x2 - c->x1, - c->y2 - c->y1); + if (sigtrap_get() == 0) { + while (c-- != clipped) { + memcpy_blt(ptr, dst->devPrivate.ptr, tmp.drawable.bitsPerPixel, + dst_bo->pitch, dst->devKind, + c->x1 - tile.x1, + c->y1 - tile.y1, + c->x1, c->y1, + c->x2 - c->x1, + c->y2 - c->y1); + } + sigtrap_put(); } kgem_bo_destroy(&sna->kgem, dst_bo); @@ -412,14 +414,17 @@ fallback: kgem_bo_submit(&sna->kgem, dst_bo); kgem_buffer_read_sync(kgem, dst_bo); - for (n = 0; n < nbox; n++) { - memcpy_blt(ptr, dst->devPrivate.ptr, tmp.drawable.bitsPerPixel, - dst_bo->pitch, dst->devKind, - box[n].x1 - extents.x1, - box[n].y1 - extents.y1, - box[n].x1, box[n].y1, - box[n].x2 - box[n].x1, - box[n].y2 - box[n].y1); + if (sigtrap_get() == 0) { + for (n = 0; n < nbox; n++) { + memcpy_blt(ptr, dst->devPrivate.ptr, tmp.drawable.bitsPerPixel, + dst_bo->pitch, dst->devKind, + box[n].x1 - extents.x1, + box[n].y1 - extents.y1, + box[n].x1, box[n].y1, + box[n].x2 - box[n].x1, + box[n].y2 - box[n].y1); + } + sigtrap_put(); } kgem_bo_destroy(&sna->kgem, dst_bo); @@ -594,34 +599,37 @@ fallback: kgem_buffer_read_sync(kgem, dst_bo); - src = ptr; - do { - int height = box->y2 - box->y1; - int width = box->x2 - box->x1; - int pitch = PITCH(width, cpp); - - DBG((" copy offset %lx [%08x...%08x...%08x]: (%d, %d) x (%d, %d), src pitch=%d, dst pitch=%d, bpp=%d\n", - (long)((char *)src - (char *)ptr), - *(uint32_t*)src, *(uint32_t*)(src+pitch*height/2 + pitch/2 - 4), *(uint32_t*)(src+pitch*height - 4), - box->x1, box->y1, - width, height, - pitch, dst->devKind, cpp*8)); - - assert(box->x1 >= 0); - assert(box->x2 <= dst->drawable.width); - assert(box->y1 >= 0); - assert(box->y2 <= dst->drawable.height); - - memcpy_blt(src, dst->devPrivate.ptr, cpp*8, - pitch, dst->devKind, - 0, 0, - box->x1, box->y1, - width, height); - box++; + if (sigtrap_get() == 0) { + char *src = ptr; + do { + int height = box->y2 - box->y1; + int width = box->x2 - box->x1; + int pitch = PITCH(width, cpp); + + DBG((" copy offset %lx [%08x...%08x...%08x]: (%d, %d) x (%d, %d), src pitch=%d, dst pitch=%d, bpp=%d\n", + (long)((char *)src - (char *)ptr), + *(uint32_t*)src, *(uint32_t*)(src+pitch*height/2 + pitch/2 - 4), *(uint32_t*)(src+pitch*height - 4), + box->x1, box->y1, + width, height, + pitch, dst->devKind, cpp*8)); + + assert(box->x1 >= 0); + assert(box->x2 <= dst->drawable.width); + assert(box->y1 >= 0); + assert(box->y2 <= dst->drawable.height); + + memcpy_blt(src, dst->devPrivate.ptr, cpp*8, + pitch, dst->devKind, + 0, 0, + box->x1, box->y1, + width, height); + box++; - src += pitch * height; - } while (--nbox); - assert(src - (char *)ptr == __kgem_buffer_size(dst_bo)); + src += pitch * height; + } while (--nbox); + assert(src - (char *)ptr == __kgem_buffer_size(dst_bo)); + sigtrap_put(); + } kgem_bo_destroy(kgem, dst_bo); sna->blt_state.fill_bo = 0; } @@ -831,7 +839,7 @@ bool sna_write_boxes(struct sna *sna, PixmapPtr dst, tmp.drawable.width, tmp.drawable.height, sna->render.max_3d_size, sna->render.max_3d_size)); if (must_tile(sna, tmp.drawable.width, tmp.drawable.height)) { - BoxRec tile, stack[64], *clipped, *c; + BoxRec tile, stack[64], *clipped; int cpp, step; tile: @@ -883,7 +891,7 @@ tile: } if (sigtrap_get() == 0) { - c = clipped; + BoxRec *c = clipped; for (n = 0; n < nbox; n++) { *c = box[n]; if (!box_intersect(c, &tile)) @@ -940,28 +948,32 @@ tile: if (!src_bo) goto fallback; - for (n = 0; n < nbox; n++) { - DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", - __FUNCTION__, - box[n].x1, box[n].y1, - box[n].x2, box[n].y2, - src_dx, src_dy, - box[n].x1 - extents.x1, - box[n].y1 - extents.y1)); - memcpy_blt(src, ptr, tmp.drawable.bitsPerPixel, - stride, src_bo->pitch, - box[n].x1 + src_dx, - box[n].y1 + src_dy, - box[n].x1 - extents.x1, - box[n].y1 - extents.y1, - box[n].x2 - box[n].x1, - box[n].y2 - box[n].y1); - } + if (sigtrap_get() == 0) { + for (n = 0; n < nbox; n++) { + DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", + __FUNCTION__, + box[n].x1, box[n].y1, + box[n].x2, box[n].y2, + src_dx, src_dy, + box[n].x1 - extents.x1, + box[n].y1 - extents.y1)); + memcpy_blt(src, ptr, tmp.drawable.bitsPerPixel, + stride, src_bo->pitch, + box[n].x1 + src_dx, + box[n].y1 + src_dy, + box[n].x1 - extents.x1, + box[n].y1 - extents.y1, + box[n].x2 - box[n].x1, + box[n].y2 - box[n].y1); + } - n = sna->render.copy_boxes(sna, GXcopy, - &tmp, src_bo, -extents.x1, -extents.y1, - dst, dst_bo, dst_dx, dst_dy, - box, nbox, 0); + n = sna->render.copy_boxes(sna, GXcopy, + &tmp, src_bo, -extents.x1, -extents.y1, + dst, dst_bo, dst_dx, dst_dy, + box, nbox, 0); + sigtrap_put(); + } else + n = 0; kgem_bo_destroy(&sna->kgem, src_bo); @@ -1026,59 +1038,62 @@ tile: if (!src_bo) break; - offset = 0; - do { - int height = box->y2 - box->y1; - int width = box->x2 - box->x1; - int pitch = PITCH(width, dst->drawable.bitsPerPixel >> 3); - uint32_t *b; - - DBG((" %s: box src=(%d, %d), dst=(%d, %d) size=(%d, %d), dst offset=%d, dst pitch=%d\n", - __FUNCTION__, - box->x1 + src_dx, box->y1 + src_dy, - box->x1 + dst_dx, box->y1 + dst_dy, - width, height, - offset, pitch)); - - assert(box->x1 + src_dx >= 0); - assert((box->x2 + src_dx)*dst->drawable.bitsPerPixel <= 8*stride); - assert(box->y1 + src_dy >= 0); - - assert(box->x1 + dst_dx >= 0); - assert(box->y1 + dst_dy >= 0); - - memcpy_blt(src, (char *)ptr + offset, - dst->drawable.bitsPerPixel, - stride, pitch, - box->x1 + src_dx, box->y1 + src_dy, - 0, 0, - width, height); - - assert(kgem->mode == KGEM_BLT); - b = kgem->batch + kgem->nbatch; - b[0] = cmd; - b[1] = br13; - b[2] = (box->y1 + dst_dy) << 16 | (box->x1 + dst_dx); - b[3] = (box->y2 + dst_dy) << 16 | (box->x2 + dst_dx); - *(uint64_t *)(b+4) = - kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, - I915_GEM_DOMAIN_RENDER << 16 | - I915_GEM_DOMAIN_RENDER | - KGEM_RELOC_FENCED, - 0); - b[6] = 0; - b[7] = pitch; - *(uint64_t *)(b+8) = - kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, - I915_GEM_DOMAIN_RENDER << 16 | - KGEM_RELOC_FENCED, - offset); - kgem->nbatch += 10; - - box++; - offset += pitch * height; - } while (--nbox_this_time); - assert(offset == __kgem_buffer_size(src_bo)); + if (sigtrap_get() == 0) { + offset = 0; + do { + int height = box->y2 - box->y1; + int width = box->x2 - box->x1; + int pitch = PITCH(width, dst->drawable.bitsPerPixel >> 3); + uint32_t *b; + + DBG((" %s: box src=(%d, %d), dst=(%d, %d) size=(%d, %d), dst offset=%d, dst pitch=%d\n", + __FUNCTION__, + box->x1 + src_dx, box->y1 + src_dy, + box->x1 + dst_dx, box->y1 + dst_dy, + width, height, + offset, pitch)); + + assert(box->x1 + src_dx >= 0); + assert((box->x2 + src_dx)*dst->drawable.bitsPerPixel <= 8*stride); + assert(box->y1 + src_dy >= 0); + + assert(box->x1 + dst_dx >= 0); + assert(box->y1 + dst_dy >= 0); + + memcpy_blt(src, (char *)ptr + offset, + dst->drawable.bitsPerPixel, + stride, pitch, + box->x1 + src_dx, box->y1 + src_dy, + 0, 0, + width, height); + + assert(kgem->mode == KGEM_BLT); + b = kgem->batch + kgem->nbatch; + b[0] = cmd; + b[1] = br13; + b[2] = (box->y1 + dst_dy) << 16 | (box->x1 + dst_dx); + b[3] = (box->y2 + dst_dy) << 16 | (box->x2 + dst_dx); + *(uint64_t *)(b+4) = + kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, + I915_GEM_DOMAIN_RENDER << 16 | + I915_GEM_DOMAIN_RENDER | + KGEM_RELOC_FENCED, + 0); + b[6] = 0; + b[7] = pitch; + *(uint64_t *)(b+8) = + kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, + I915_GEM_DOMAIN_RENDER << 16 | + KGEM_RELOC_FENCED, + offset); + kgem->nbatch += 10; + + box++; + offset += pitch * height; + } while (--nbox_this_time); + assert(offset == __kgem_buffer_size(src_bo)); + sigtrap_put(); + } if (nbox) { _kgem_submit(kgem); @@ -1116,6 +1131,11 @@ tile: if (!src_bo) break; + if (sigtrap_get()) { + kgem_bo_destroy(kgem, src_bo); + goto fallback; + } + offset = 0; do { int height = box->y2 - box->y1; @@ -1167,6 +1187,7 @@ tile: offset += pitch * height; } while (--nbox_this_time); assert(offset == __kgem_buffer_size(src_bo)); + sigtrap_put(); if (nbox) { _kgem_submit(kgem); @@ -1322,7 +1343,7 @@ bool sna_write_boxes__xor(struct sna *sna, PixmapPtr dst, tmp.drawable.width, tmp.drawable.height, sna->render.max_3d_size, sna->render.max_3d_size)); if (must_tile(sna, tmp.drawable.width, tmp.drawable.height)) { - BoxRec tile, stack[64], *clipped, *c; + BoxRec tile, stack[64], *clipped; int step; tile: @@ -1369,38 +1390,43 @@ tile: goto fallback; } - c = clipped; - for (n = 0; n < nbox; n++) { - *c = box[n]; - if (!box_intersect(c, &tile)) - continue; + if (sigtrap_get() == 0) { + BoxRec *c = clipped; + for (n = 0; n < nbox; n++) { + *c = box[n]; + if (!box_intersect(c, &tile)) + continue; - DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", - __FUNCTION__, - c->x1, c->y1, - c->x2, c->y2, - src_dx, src_dy, - c->x1 - tile.x1, - c->y1 - tile.y1)); - memcpy_xor(src, ptr, tmp.drawable.bitsPerPixel, - stride, src_bo->pitch, - c->x1 + src_dx, - c->y1 + src_dy, - c->x1 - tile.x1, - c->y1 - tile.y1, - c->x2 - c->x1, - c->y2 - c->y1, - and, or); - c++; - } + DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", + __FUNCTION__, + c->x1, c->y1, + c->x2, c->y2, + src_dx, src_dy, + c->x1 - tile.x1, + c->y1 - tile.y1)); + memcpy_xor(src, ptr, tmp.drawable.bitsPerPixel, + stride, src_bo->pitch, + c->x1 + src_dx, + c->y1 + src_dy, + c->x1 - tile.x1, + c->y1 - tile.y1, + c->x2 - c->x1, + c->y2 - c->y1, + and, or); + c++; + } + + if (c != clipped) + n = sna->render.copy_boxes(sna, GXcopy, + &tmp, src_bo, -tile.x1, -tile.y1, + dst, dst_bo, dst_dx, dst_dy, + clipped, c - clipped, 0); + else + n = 1; - if (c != clipped) - n = sna->render.copy_boxes(sna, GXcopy, - &tmp, src_bo, -tile.x1, -tile.y1, - dst, dst_bo, dst_dx, dst_dy, - clipped, c - clipped, 0); - else - n = 1; + sigtrap_put(); + } else + n = 0; kgem_bo_destroy(&sna->kgem, src_bo); @@ -1424,29 +1450,33 @@ tile: if (!src_bo) goto fallback; - for (n = 0; n < nbox; n++) { - DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", - __FUNCTION__, - box[n].x1, box[n].y1, - box[n].x2, box[n].y2, - src_dx, src_dy, - box[n].x1 - extents.x1, - box[n].y1 - extents.y1)); - memcpy_xor(src, ptr, tmp.drawable.bitsPerPixel, - stride, src_bo->pitch, - box[n].x1 + src_dx, - box[n].y1 + src_dy, - box[n].x1 - extents.x1, - box[n].y1 - extents.y1, - box[n].x2 - box[n].x1, - box[n].y2 - box[n].y1, - and, or); - } + if (sigtrap_get() == 0) { + for (n = 0; n < nbox; n++) { + DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", + __FUNCTION__, + box[n].x1, box[n].y1, + box[n].x2, box[n].y2, + src_dx, src_dy, + box[n].x1 - extents.x1, + box[n].y1 - extents.y1)); + memcpy_xor(src, ptr, tmp.drawable.bitsPerPixel, + stride, src_bo->pitch, + box[n].x1 + src_dx, + box[n].y1 + src_dy, + box[n].x1 - extents.x1, + box[n].y1 - extents.y1, + box[n].x2 - box[n].x1, + box[n].y2 - box[n].y1, + and, or); + } - n = sna->render.copy_boxes(sna, GXcopy, - &tmp, src_bo, -extents.x1, -extents.y1, - dst, dst_bo, dst_dx, dst_dy, - box, nbox, 0); + n = sna->render.copy_boxes(sna, GXcopy, + &tmp, src_bo, -extents.x1, -extents.y1, + dst, dst_bo, dst_dx, dst_dy, + box, nbox, 0); + sigtrap_put(); + } else + n = 0; kgem_bo_destroy(&sna->kgem, src_bo); @@ -1509,7 +1539,12 @@ tile: KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0), &ptr); if (!src_bo) - break; + goto fallback; + + if (sigtrap_get()) { + kgem_bo_destroy(kgem, src_bo); + goto fallback; + } offset = 0; do { @@ -1565,6 +1600,7 @@ tile: offset += pitch * height; } while (--nbox_this_time); assert(offset == __kgem_buffer_size(src_bo)); + sigtrap_put(); if (nbox) { _kgem_submit(kgem); @@ -1600,7 +1636,12 @@ tile: KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0), &ptr); if (!src_bo) - break; + goto fallback; + + if (sigtrap_get()) { + kgem_bo_destroy(kgem, src_bo); + goto fallback; + } offset = 0; do { @@ -1654,6 +1695,7 @@ tile: offset += pitch * height; } while (--nbox_this_time); assert(offset == __kgem_buffer_size(src_bo)); + sigtrap_put(); if (nbox) { _kgem_submit(kgem); -- 2.7.4