sna: Use an upload buffer for large stipples
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
40e0cf32a2
commit
7d4a3e371b
|
|
@ -3519,9 +3519,7 @@ sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
|
|||
} 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] = XY_MONO_SRC_COPY | 3 << 20;
|
||||
b[0] |= ((box->x1 - x) & 7) << 17;
|
||||
b[1] = bo->pitch;
|
||||
if (sna->kgem.gen >= 40 && bo->tiling) {
|
||||
|
|
@ -3649,9 +3647,7 @@ sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
|
|||
} while (--bh);
|
||||
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
b[0] = XY_FULL_MONO_PATTERN_MONO_SRC_BLT;
|
||||
if (drawable->bitsPerPixel == 32)
|
||||
b[0] |= 3 << 20;
|
||||
b[0] = XY_FULL_MONO_PATTERN_MONO_SRC_BLT | 3 << 20;
|
||||
b[0] |= ((box->x1 - x) & 7) << 17;
|
||||
b[1] = bo->pitch;
|
||||
if (sna->kgem.gen >= 40 && bo->tiling) {
|
||||
|
|
@ -5852,9 +5848,7 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
|
|||
get_drawable_deltas(drawable, dst_pixmap, &dx, &dy);
|
||||
assert_pixmap_contains_boxes(dst_pixmap, box, n, dx, dy);
|
||||
|
||||
br00 = XY_MONO_SRC_COPY;
|
||||
if (drawable->bitsPerPixel == 32)
|
||||
br00 |= 3 << 20;
|
||||
br00 = XY_MONO_SRC_COPY | 3 << 20;
|
||||
br13 = arg->bo->pitch;
|
||||
if (sna->kgem.gen >= 40 && arg->bo->tiling) {
|
||||
br00 |= BLT_DST_TILED;
|
||||
|
|
@ -9667,9 +9661,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
|
|||
unsigned px = (0 - gc->patOrg.x - dx) & 7;
|
||||
unsigned py = (0 - gc->patOrg.y - dy) & 7;
|
||||
DBG(("%s: pat offset (%d, %d)\n", __FUNCTION__ ,px, py));
|
||||
br00 = XY_MONO_PAT | px << 12 | py << 8;
|
||||
if (drawable->bitsPerPixel == 32)
|
||||
br00 |= 3 << 20;
|
||||
br00 = XY_MONO_PAT | px << 12 | py << 8 | 3 << 20;
|
||||
|
||||
br13 = bo->pitch;
|
||||
if (sna->kgem.gen >= 40 && bo->tiling) {
|
||||
|
|
@ -10327,12 +10319,12 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
|
|||
}
|
||||
|
||||
static void
|
||||
sna_poly_fill_rect_stippled_n_box(struct sna *sna,
|
||||
struct kgem_bo *bo,
|
||||
uint32_t br00, uint32_t br13,
|
||||
GCPtr gc,
|
||||
const BoxRec *box,
|
||||
const DDXPointRec *origin)
|
||||
sna_poly_fill_rect_stippled_n_box__imm(struct sna *sna,
|
||||
struct kgem_bo *bo,
|
||||
uint32_t br00, uint32_t br13,
|
||||
const GC *gc,
|
||||
const BoxRec *box,
|
||||
const DDXPointRec *origin)
|
||||
{
|
||||
int x1, x2, y1, y2;
|
||||
uint32_t *b;
|
||||
|
|
@ -10415,6 +10407,299 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sna_poly_fill_rect_stippled_n_box(struct sna *sna,
|
||||
struct kgem_bo *bo,
|
||||
uint32_t br00, uint32_t br13,
|
||||
const GC *gc,
|
||||
const BoxRec *box,
|
||||
const DDXPointRec *origin)
|
||||
{
|
||||
int x1, x2, y1, y2;
|
||||
int w = gc->stipple->drawable.width;
|
||||
int h = gc->stipple->drawable.height;
|
||||
int stride = gc->stipple->devKind;
|
||||
uint32_t *b;
|
||||
|
||||
if ((((box->y2-box->y1) | (box->x2-box->x1)) & ~31) == 0) {
|
||||
br00 = XY_MONO_SRC_COPY_IMM |(br00 & (BLT_DST_TILED | 3 << 20));
|
||||
sna_poly_fill_rect_stippled_n_box__imm(sna, bo,
|
||||
br00, br13, gc,
|
||||
box, origin);
|
||||
return;
|
||||
}
|
||||
|
||||
for (y1 = box->y1; y1 < box->y2; y1 = y2) {
|
||||
int row, oy = (y1 - origin->y) % gc->stipple->drawable.height;
|
||||
if (oy < 0)
|
||||
oy += h;
|
||||
|
||||
y2 = box->y2;
|
||||
if (y2 - y1 > h - oy)
|
||||
y2 = y1 + h - oy;
|
||||
|
||||
row = oy * stride;
|
||||
for (x1 = box->x1; x1 < box->x2; x1 = x2) {
|
||||
int bx1, bx2, bw, bh, len, ox;
|
||||
|
||||
x2 = box->x2;
|
||||
ox = (x1 - origin->x) % w;
|
||||
if (ox < 0)
|
||||
ox += w;
|
||||
bx1 = ox & ~7;
|
||||
bx2 = ox + (x2 - x1);
|
||||
if (bx2 > w) {
|
||||
bx2 = w;
|
||||
x2 = x1 + bx2-ox;
|
||||
}
|
||||
|
||||
DBG(("%s: box((%d, %d)x(%d, %d)) origin=(%d, %d), pat=(%d, %d), up=(%d, %d), stipple=%dx%d\n",
|
||||
__FUNCTION__,
|
||||
x1, y1, x2-x1, y2-y1,
|
||||
origin->x, origin->y,
|
||||
ox, oy, bx1, bx2, w, h));
|
||||
|
||||
bw = (bx2 - bx1 + 7)/8;
|
||||
bw = ALIGN(bw, 2);
|
||||
bh = y2 - y1;
|
||||
|
||||
len = bw*bh;
|
||||
len = ALIGN(len, 8) / 4;
|
||||
if (!kgem_check_batch(&sna->kgem, 7+len) ||
|
||||
!kgem_check_bo_fenced(&sna->kgem, bo) ||
|
||||
!kgem_check_reloc(&sna->kgem, 2)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
|
||||
if (len <= 128) {
|
||||
uint8_t *dst, *src;
|
||||
|
||||
b[0] = XY_MONO_SRC_COPY_IMM;
|
||||
b[0] |= (br00 & (BLT_DST_TILED | 3 << 20));
|
||||
b[0] |= (ox & 7) << 17;
|
||||
b[0] |= (5 + len);
|
||||
b[1] = br13;
|
||||
b[2] = y1 << 16 | x1;
|
||||
b[3] = y2 << 16 | x2;
|
||||
b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
|
||||
bo,
|
||||
I915_GEM_DOMAIN_RENDER << 16 |
|
||||
I915_GEM_DOMAIN_RENDER |
|
||||
KGEM_RELOC_FENCED,
|
||||
0);
|
||||
b[5] = gc->bgPixel;
|
||||
b[6] = gc->fgPixel;
|
||||
|
||||
sna->kgem.nbatch += 7 + len;
|
||||
|
||||
dst = (uint8_t *)&b[7];
|
||||
len = gc->stipple->devKind;
|
||||
src = gc->stipple->devPrivate.ptr;
|
||||
src += oy*len + ox/8;
|
||||
len -= bw;
|
||||
do {
|
||||
int i = bw;
|
||||
do {
|
||||
*dst++ = byte_reverse(*src++);
|
||||
*dst++ = byte_reverse(*src++);
|
||||
i -= 2;
|
||||
} while (i);
|
||||
src += len;
|
||||
} while (--bh);
|
||||
} else {
|
||||
struct kgem_bo *upload;
|
||||
uint8_t *dst, *src;
|
||||
void *ptr;
|
||||
|
||||
upload = kgem_create_buffer(&sna->kgem, bw*bh,
|
||||
KGEM_BUFFER_WRITE_INPLACE,
|
||||
&ptr);
|
||||
if (!upload)
|
||||
return;
|
||||
|
||||
b = sna->kgem.batch + sna->kgem.nbatch;
|
||||
b[0] = br00 | (ox & 7) << 17;
|
||||
b[1] = br13;
|
||||
b[2] = y1 << 16 | x1;
|
||||
b[3] = y2 << 16 | x2;
|
||||
b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
|
||||
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;
|
||||
|
||||
dst = ptr;
|
||||
len = stride;
|
||||
src = gc->stipple->devPrivate.ptr;
|
||||
src += row + (ox >> 3);
|
||||
len -= bw;
|
||||
do {
|
||||
int i = bw;
|
||||
do {
|
||||
*dst++ = byte_reverse(*src++);
|
||||
*dst++ = byte_reverse(*src++);
|
||||
i -= 2;
|
||||
} while (i);
|
||||
src += len;
|
||||
} while (--bh);
|
||||
|
||||
kgem_bo_destroy(&sna->kgem, upload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
sna_poly_fill_rect_stippled_n_blt__imm(DrawablePtr drawable,
|
||||
struct kgem_bo *bo,
|
||||
struct sna_damage **damage,
|
||||
GCPtr gc, int n, xRectangle *r,
|
||||
const BoxRec *extents, unsigned clipped)
|
||||
{
|
||||
PixmapPtr pixmap = get_drawable_pixmap(drawable);
|
||||
struct sna *sna = to_sna_from_pixmap(pixmap);
|
||||
DDXPointRec origin = gc->patOrg;
|
||||
int16_t dx, dy;
|
||||
uint32_t br00, br13;
|
||||
|
||||
DBG(("%s: upload (%d, %d), (%d, %d), origin (%d, %d), clipped=%d, alu=%d, opaque=%d\n", __FUNCTION__,
|
||||
extents->x1, extents->y1,
|
||||
extents->x2, extents->y2,
|
||||
origin.x, origin.y,
|
||||
clipped, gc->alu, gc->fillStyle == FillOpaqueStippled));
|
||||
|
||||
get_drawable_deltas(drawable, pixmap, &dx, &dy);
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
|
||||
br00 = XY_MONO_SRC_COPY_IMM | 3 << 20;
|
||||
br13 = bo->pitch;
|
||||
if (sna->kgem.gen >= 40 && bo->tiling) {
|
||||
br00 |= BLT_DST_TILED;
|
||||
br13 >>= 2;
|
||||
}
|
||||
br13 |= (gc->fillStyle == FillStippled) << 29;
|
||||
br13 |= blt_depth(drawable->depth) << 24;
|
||||
br13 |= copy_ROP[gc->alu] << 16;
|
||||
|
||||
origin.x += dx + drawable->x;
|
||||
origin.y += dy + drawable->y;
|
||||
|
||||
if (!clipped) {
|
||||
dx += drawable->x;
|
||||
dy += drawable->y;
|
||||
|
||||
sna_damage_add_rectangles(damage, r, n, dx, dy);
|
||||
do {
|
||||
BoxRec box;
|
||||
|
||||
box.x1 = r->x + dx;
|
||||
box.y1 = r->y + dy;
|
||||
box.x2 = box.x1 + r->width;
|
||||
box.y2 = box.y1 + r->height;
|
||||
|
||||
sna_poly_fill_rect_stippled_n_box__imm(sna, bo,
|
||||
br00, br13, gc,
|
||||
&box, &origin);
|
||||
r++;
|
||||
} while (--n);
|
||||
} else {
|
||||
RegionRec clip;
|
||||
|
||||
region_set(&clip, extents);
|
||||
region_maybe_clip(&clip, gc->pCompositeClip);
|
||||
if (!RegionNotEmpty(&clip)) {
|
||||
DBG(("%s: all clipped\n", __FUNCTION__));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (clip.data == NULL) {
|
||||
DBG(("%s: clipped to extents ((%d, %d), (%d, %d))\n",
|
||||
__FUNCTION__,
|
||||
clip.extents.x1, clip.extents.y1,
|
||||
clip.extents.x2, clip.extents.y2));
|
||||
do {
|
||||
BoxRec box;
|
||||
|
||||
box.x1 = r->x + drawable->x;
|
||||
box.x2 = bound(box.x1, r->width);
|
||||
box.y1 = r->y + drawable->y;
|
||||
box.y2 = bound(box.y1, r->height);
|
||||
r++;
|
||||
|
||||
DBG(("%s: box (%d, %d), (%d, %d)\n",
|
||||
__FUNCTION__,
|
||||
box.x1, box.y1, box.x2, box.y2));
|
||||
if (!box_intersect(&box, &clip.extents))
|
||||
continue;
|
||||
|
||||
box.x1 += dx; box.x2 += dx;
|
||||
box.y1 += dy; box.y2 += dy;
|
||||
|
||||
sna_poly_fill_rect_stippled_n_box__imm(sna, bo,
|
||||
br00, br13, gc,
|
||||
&box, &origin);
|
||||
} while (--n);
|
||||
} else {
|
||||
const BoxRec * const clip_start = RegionBoxptr(&clip);
|
||||
const BoxRec * const clip_end = clip_start + clip.data->numRects;
|
||||
const BoxRec *c;
|
||||
|
||||
DBG(("%s: clipped to boxes: start((%d, %d), (%d, %d)); end=((%d, %d), (%d, %d))\n", __FUNCTION__,
|
||||
clip_start->x1, clip_start->y1,
|
||||
clip_start->x2, clip_start->y2,
|
||||
clip_end->x1, clip_end->y1,
|
||||
clip_end->x2, clip_end->y2));
|
||||
do {
|
||||
BoxRec unclipped;
|
||||
|
||||
unclipped.x1 = r->x + drawable->x;
|
||||
unclipped.x2 = bound(unclipped.x1, r->width);
|
||||
unclipped.y1 = r->y + drawable->y;
|
||||
unclipped.y2 = bound(unclipped.y1, 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;
|
||||
|
||||
box.x1 += dx; box.x2 += dx;
|
||||
box.y1 += dy; box.y2 += dy;
|
||||
|
||||
sna_poly_fill_rect_stippled_n_box__imm(sna, bo,
|
||||
br00, br13, gc,
|
||||
&box, &origin);
|
||||
}
|
||||
} while (--n);
|
||||
}
|
||||
}
|
||||
|
||||
assert_pixmap_damage(pixmap);
|
||||
sna->blt_state.fill_bo = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
|
||||
struct kgem_bo *bo,
|
||||
|
|
@ -10434,14 +10719,16 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
|
|||
origin.x, origin.y,
|
||||
clipped, gc->alu, gc->fillStyle == FillOpaqueStippled));
|
||||
|
||||
if (gc->stipple->drawable.width > 32 ||
|
||||
gc->stipple->drawable.height > 32)
|
||||
return false;
|
||||
if (((gc->stipple->drawable.width | gc->stipple->drawable.height) & ~31) == 0)
|
||||
return sna_poly_fill_rect_stippled_n_blt__imm(drawable,
|
||||
bo, damage,
|
||||
gc, n, r,
|
||||
extents, clipped);
|
||||
|
||||
get_drawable_deltas(drawable, pixmap, &dx, &dy);
|
||||
kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
|
||||
br00 = XY_MONO_SRC_COPY_IMM | 3 << 20;
|
||||
br00 = XY_MONO_SRC_COPY | 3 << 20;
|
||||
br13 = bo->pitch;
|
||||
if (sna->kgem.gen >= 40 && bo->tiling) {
|
||||
br00 |= BLT_DST_TILED;
|
||||
|
|
@ -12165,9 +12452,7 @@ sna_push_pixels_solid_blt(GCPtr gc,
|
|||
} 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] = XY_MONO_SRC_COPY | 3 << 20;
|
||||
b[0] |= ((box->x1 - region->extents.x1) & 7) << 17;
|
||||
b[1] = bo->pitch;
|
||||
if (sna->kgem.gen >= 40 && bo->tiling) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue