diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-11-02 12:17:31 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-11-02 12:17:31 +0000 |
commit | 9cdf8be55029f30b47cfc39ddd2754d40602cf2c (patch) | |
tree | 5127cce89442810b73444f42b1f1dd16c459aa7f | |
parent | 6553c9e1cbfcecf781ba106de99f9e70c6d373ba (diff) |
sna: Add clipped stippled upload support
For xsnow!
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 380 |
2 files changed, 298 insertions, 83 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 7770175c..e470e4d7 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1959,6 +1959,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem, DBG(("%s: size=%d, flags=%x [write=%d, last=%d]\n", __FUNCTION__, size, flags, write, flags & KGEM_BUFFER_LAST)); + assert(size); list_for_each_entry(bo, &kgem->partial, base.list) { if (flags == KGEM_BUFFER_LAST && bo->write) { diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index f70a3122..235b783b 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -6121,100 +6121,314 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable, extents->x2, extents->y2, origin->x, origin->y)); - if (clipped) { - DBG(("%s: fallback -- clipped\n", __FUNCTION__)); - return false; - } - get_drawable_deltas(drawable, pixmap, &dx, &dy); - dx += drawable->x; - dy += drawable->y; - kgem_set_mode(&sna->kgem, KGEM_BLT); - sna_damage_add_rectangles(damage, r, n, dx, dy); - do { - int bx1 = (r->x - origin->x) & ~7; - int bx2 = (r->x + r->width - origin->x + 7) & ~7; - int bw = (bx2 - bx1)/8; - int bh = r->height; - int bstride = ALIGN(bw, 2); - int src_stride; - uint8_t *dst, *src; - uint32_t *b; - struct kgem_bo *upload; - void *ptr; + if (!clipped) { + dx += drawable->x; + dy += drawable->y; - DBG(("%s: rect (%d, %d)x(%d, %d) stipple [%d,%d]\n", - __FUNCTION__, - r->x, r->y, r->width, r->height, - bx1, bx2)); + sna_damage_add_rectangles(damage, r, n, dx, dy); + do { + int bx1 = (r->x - origin->x) & ~7; + int bx2 = (r->x + r->width - origin->x + 7) & ~7; + int bw = (bx2 - bx1)/8; + int bh = r->height; + int bstride = ALIGN(bw, 2); + int src_stride; + uint8_t *dst, *src; + uint32_t *b; + struct kgem_bo *upload; + void *ptr; - if (!kgem_check_batch(&sna->kgem, 8) || - !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) || - !kgem_check_reloc(&sna->kgem, 2)) { - _kgem_submit(&sna->kgem); - _kgem_set_mode(&sna->kgem, KGEM_BLT); - } + DBG(("%s: rect (%d, %d)x(%d, %d) stipple [%d,%d]\n", + __FUNCTION__, + r->x, r->y, r->width, r->height, + bx1, bx2)); - upload = kgem_create_buffer(&sna->kgem, - bstride*bh, - KGEM_BUFFER_WRITE, - &ptr); - if (!upload) - break; + if (!kgem_check_batch(&sna->kgem, 8) || + !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) || + !kgem_check_reloc(&sna->kgem, 2)) { + _kgem_submit(&sna->kgem); + _kgem_set_mode(&sna->kgem, KGEM_BLT); + } - dst = ptr; - bstride -= bw; + upload = kgem_create_buffer(&sna->kgem, + bstride*bh, + KGEM_BUFFER_WRITE, + &ptr); + if (!upload) + break; - src_stride = stipple->devKind; - src = (uint8_t*)stipple->devPrivate.ptr; - src += (r->y - origin->y) * src_stride + bx1/8; - src_stride -= bw; - do { - int i = bw; + dst = ptr; + bstride -= bw; + + src_stride = stipple->devKind; + src = (uint8_t*)stipple->devPrivate.ptr; + src += (r->y - origin->y) * src_stride + bx1/8; + src_stride -= bw; do { - *dst++ = byte_reverse(*src++); - } while (--i); - dst += bstride; - src += src_stride; - } while (--bh); + int i = bw; + do { + *dst++ = byte_reverse(*src++); + } while (--i); + dst += bstride; + src += src_stride; + } while (--bh); - b = sna->kgem.batch + sna->kgem.nbatch; - b[0] = XY_MONO_SRC_COPY; - if (drawable->bitsPerPixel == 32) - b[0] |= 3 << 20; - b[0] |= ((r->x - origin->x) & 7) << 17; - b[1] = priv->gpu_bo->pitch; - if (sna->kgem.gen >= 40) { - if (priv->gpu_bo->tiling) - b[0] |= BLT_DST_TILED; - b[1] >>= 2; - } - b[1] |= (gc->fillStyle == FillStippled) << 29; - b[1] |= blt_depth(drawable->depth) << 24; - b[1] |= rop << 16; - b[2] = (r->y + dy) << 16 | (r->x + dx); - b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); - b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, - priv->gpu_bo, - I915_GEM_DOMAIN_RENDER << 16 | - I915_GEM_DOMAIN_RENDER | - KGEM_RELOC_FENCED, - 0); - b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, - upload, - I915_GEM_DOMAIN_RENDER << 16 | - KGEM_RELOC_FENCED, - 0); - b[6] = gc->bgPixel; - b[7] = gc->fgPixel; + b = sna->kgem.batch + sna->kgem.nbatch; + b[0] = XY_MONO_SRC_COPY; + if (drawable->bitsPerPixel == 32) + b[0] |= 3 << 20; + b[0] |= ((r->x - origin->x) & 7) << 17; + b[1] = priv->gpu_bo->pitch; + if (sna->kgem.gen >= 40) { + if (priv->gpu_bo->tiling) + b[0] |= BLT_DST_TILED; + b[1] >>= 2; + } + b[1] |= (gc->fillStyle == FillStippled) << 29; + b[1] |= blt_depth(drawable->depth) << 24; + b[1] |= rop << 16; + b[2] = (r->y + dy) << 16 | (r->x + dx); + b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); + b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, + priv->gpu_bo, + I915_GEM_DOMAIN_RENDER << 16 | + I915_GEM_DOMAIN_RENDER | + KGEM_RELOC_FENCED, + 0); + b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, + upload, + I915_GEM_DOMAIN_RENDER << 16 | + KGEM_RELOC_FENCED, + 0); + b[6] = gc->bgPixel; + b[7] = gc->fgPixel; - sna->kgem.nbatch += 8; - kgem_bo_destroy(&sna->kgem, upload); + sna->kgem.nbatch += 8; + kgem_bo_destroy(&sna->kgem, upload); - r++; - } while (--n); + r++; + } while (--n); + } else { + RegionRec clip; + DDXPointRec pat; + + region_set(&clip, extents); + region_maybe_clip(&clip, gc->pCompositeClip); + if (!RegionNotEmpty(&clip)) + return true; + + pat.x = origin->x + drawable->x; + pat.y = origin->y + drawable->y; + + if (clip.data == NULL) { + do { + BoxRec box; + int bx1, bx2, bw, bh, bstride; + int src_stride; + uint8_t *dst, *src; + uint32_t *b; + struct kgem_bo *upload; + void *ptr; + + box.x1 = r->x + drawable->x; + box.x2 = bound(r->x, r->width); + box.y1 = r->y + drawable->y; + box.y2 = bound(r->y, r->height); + r++; + + if (!box_intersect(&box, &clip.extents)) + continue; + + bx1 = (box.x1 - pat.x) & ~7; + bx2 = (box.x2 - pat.x + 7) & ~7; + bw = (bx2 - bx1)/8; + bh = box.y2 - box.y1; + bstride = ALIGN(bw, 8); + + DBG(("%s: rect (%d, %d)x(%d, %d), box (%d,%d),(%d,%d) stipple [%d,%d], pitch=%d, stride=%d\n", + __FUNCTION__, + r->x, r->y, r->width, r->height, + box.x1, box.y1, box.x2, box.y2, + bx1, bx2, bw, bstride)); + + if (!kgem_check_batch(&sna->kgem, 8) || + !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) || + !kgem_check_reloc(&sna->kgem, 2)) { + _kgem_submit(&sna->kgem); + _kgem_set_mode(&sna->kgem, KGEM_BLT); + } + + upload = kgem_create_buffer(&sna->kgem, + bstride*bh, + KGEM_BUFFER_WRITE, + &ptr); + if (!upload) + break; + + dst = ptr; + bstride -= bw; + + src_stride = stipple->devKind; + src = (uint8_t*)stipple->devPrivate.ptr; + src += (box.y1 - pat.y) * src_stride + bx1/8; + src_stride -= bw; + do { + int i = bw; + do { + *dst++ = byte_reverse(*src++); + } while (--i); + dst += bstride; + src += src_stride; + } while (--bh); + + b = sna->kgem.batch + sna->kgem.nbatch; + b[0] = XY_MONO_SRC_COPY; + if (drawable->bitsPerPixel == 32) + b[0] |= 3 << 20; + b[0] |= ((box.x1 - pat.x) & 7) << 17; + b[1] = priv->gpu_bo->pitch; + if (sna->kgem.gen >= 40) { + if (priv->gpu_bo->tiling) + b[0] |= BLT_DST_TILED; + b[1] >>= 2; + } + b[1] |= (gc->fillStyle == FillStippled) << 29; + b[1] |= blt_depth(drawable->depth) << 24; + b[1] |= rop << 16; + b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); + b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); + b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, + priv->gpu_bo, + I915_GEM_DOMAIN_RENDER << 16 | + I915_GEM_DOMAIN_RENDER | + KGEM_RELOC_FENCED, + 0); + b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, + upload, + I915_GEM_DOMAIN_RENDER << 16 | + KGEM_RELOC_FENCED, + 0); + b[6] = gc->bgPixel; + b[7] = gc->fgPixel; + + sna->kgem.nbatch += 8; + kgem_bo_destroy(&sna->kgem, upload); + } while (--n); + } else { + const BoxRec * const clip_start = RegionBoxptr(&clip); + const BoxRec * const clip_end = clip_start + clip.data->numRects; + const BoxRec *c; + + do { + BoxRec unclipped; + int bx1, bx2, bw, bh, bstride; + int src_stride; + uint8_t *dst, *src; + uint32_t *b; + struct kgem_bo *upload; + void *ptr; + + unclipped.x1 = r->x + drawable->x; + unclipped.x2 = bound(r->x, r->width); + unclipped.y1 = r->y + drawable->y; + unclipped.y2 = bound(r->y, r->height); + r++; + + c = find_clip_box_for_y(clip_start, + clip_end, + unclipped.y1); + while (c != clip_end) { + BoxRec box; + + if (unclipped.y2 <= c->y1) + break; + + box = unclipped; + if (!box_intersect(&box, c++)) + continue; + + bx1 = (box.x1 - pat.x) & ~7; + bx2 = (box.x2 - pat.x + 7) & ~7; + bw = (bx2 - bx1)/8; + bh = box.y2 - box.y1; + bstride = ALIGN(bw, 8); + + DBG(("%s: rect (%d, %d)x(%d, %d), box (%d,%d),(%d,%d) stipple [%d,%d]\n", + __FUNCTION__, + r->x, r->y, r->width, r->height, + box.x1, box.y1, box.x2, box.y2, + bx1, bx2)); + + if (!kgem_check_batch(&sna->kgem, 8) || + !kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL) || + !kgem_check_reloc(&sna->kgem, 2)) { + _kgem_submit(&sna->kgem); + _kgem_set_mode(&sna->kgem, KGEM_BLT); + } + + upload = kgem_create_buffer(&sna->kgem, + bstride*bh, + KGEM_BUFFER_WRITE, + &ptr); + if (!upload) + break; + + dst = ptr; + bstride -= bw; + + src_stride = stipple->devKind; + src = (uint8_t*)stipple->devPrivate.ptr; + src += (box.y1 - pat.y) * src_stride + bx1/8; + src_stride -= bw; + do { + int i = bw; + do { + *dst++ = byte_reverse(*src++); + } while (--i); + dst += bstride; + src += src_stride; + } while (--bh); + + b = sna->kgem.batch + sna->kgem.nbatch; + b[0] = XY_MONO_SRC_COPY; + if (drawable->bitsPerPixel == 32) + b[0] |= 3 << 20; + b[0] |= ((box.x1 - pat.x) & 7) << 17; + b[1] = priv->gpu_bo->pitch; + if (sna->kgem.gen >= 40) { + if (priv->gpu_bo->tiling) + b[0] |= BLT_DST_TILED; + b[1] >>= 2; + } + b[1] |= (gc->fillStyle == FillStippled) << 29; + b[1] |= blt_depth(drawable->depth) << 24; + b[1] |= rop << 16; + b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); + b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); + b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, + priv->gpu_bo, + I915_GEM_DOMAIN_RENDER << 16 | + I915_GEM_DOMAIN_RENDER | + KGEM_RELOC_FENCED, + 0); + b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, + upload, + I915_GEM_DOMAIN_RENDER << 16 | + KGEM_RELOC_FENCED, + 0); + b[6] = gc->bgPixel; + b[7] = gc->fgPixel; + + sna->kgem.nbatch += 8; + kgem_bo_destroy(&sna->kgem, upload); + } + } while (--n); + + } + } sna->blt_state.fill_bo = 0; return true; @@ -6322,7 +6536,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) struct sna_pixmap *priv = sna_pixmap_from_drawable(draw); uint32_t color = gc->fillStyle == FillTiled ? gc->tile.pixel : gc->fgPixel; - DBG(("%s: solid fill [%08lx], testing for blt\n", + DBG(("%s: solid fill [%08x], testing for blt\n", __FUNCTION__, color)); if (sna_drawable_use_gpu_bo(draw, ®ion.extents) && |