summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-11-02 12:17:31 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-11-02 12:17:31 +0000
commit9cdf8be55029f30b47cfc39ddd2754d40602cf2c (patch)
tree5127cce89442810b73444f42b1f1dd16c459aa7f
parent6553c9e1cbfcecf781ba106de99f9e70c6d373ba (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.c1
-rw-r--r--src/sna/sna_accel.c380
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, &region.extents) &&