summaryrefslogtreecommitdiff
path: root/src/sna/sna_blt.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-10-19 19:26:19 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-10-19 20:20:49 +0100
commitf4346e5d255f419ee6148f7d69f02560732dd4de (patch)
tree5495ec8393bfb85af8c02fbd9f98004a7086acfd /src/sna/sna_blt.c
parentd7fb98efdcc1bcc2cca6deb54b16d425b0350196 (diff)
sna/blt: Use SCANLINE_BLT for multiple fill boxes
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_blt.c')
-rw-r--r--src/sna/sna_blt.c208
1 files changed, 163 insertions, 45 deletions
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 3b2c0b90..2343838e 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -290,8 +290,10 @@ static Bool sna_blt_copy_init(struct sna *sna,
}
kgem_set_mode(kgem, KGEM_BLT);
- if (!kgem_check_bo_fenced(kgem, src, dst, NULL))
+ if (!kgem_check_bo_fenced(kgem, src, dst, NULL)) {
_kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
sna->blt_state.fill_bo = 0;
return TRUE;
@@ -340,8 +342,10 @@ static void sna_blt_copy_one(struct sna *sna,
return;
}
- if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc(kgem, 2))
+ if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc(kgem, 2)) {
_kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
b = kgem->batch + kgem->nbatch;
b[0] = blt->cmd;
@@ -821,8 +825,10 @@ prepare_blt_copy(struct sna *sna,
if (priv->gpu_bo->tiling == I915_TILING_Y)
return FALSE;
- if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL))
+ if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL)) {
_kgem_submit(&sna->kgem);
+ _kgem_set_mode(&sna->kgem, KGEM_BLT);
+ }
DBG(("%s\n", __FUNCTION__));
@@ -1148,8 +1154,10 @@ sna_blt_composite(struct sna *sna,
if (width && height)
reduce_damage(tmp, dst_x, dst_y, width, height);
- if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL))
+ if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL)) {
_kgem_submit(&sna->kgem);
+ _kgem_set_mode(&sna->kgem, KGEM_BLT);
+ }
if (op == PictOpClear)
return prepare_blt_clear(sna, tmp);
@@ -1349,26 +1357,20 @@ bool sna_blt_copy(struct sna *sna, uint8_t alu,
return TRUE;
}
-Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
- struct kgem_bo *bo, int bpp,
- uint32_t color,
- const BoxRec *box, int nbox)
+static Bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
+ struct kgem_bo *bo, int bpp,
+ uint32_t color,
+ const BoxRec *box)
{
struct kgem *kgem = &sna->kgem;
uint32_t br13, cmd;
+ uint32_t *b;
-#if DEBUG_NO_BLT || NO_BLT_FILL_BOXES
- return FALSE;
-#endif
-
- DBG(("%s (%d, %08x, %d) x %d\n",
- __FUNCTION__, bpp, color, alu, nbox));
+ DBG(("%s: box=((%d, %d), (%d, %d))\n", __FUNCTION__,
+ box->x1, box->y1, box->x2, box->y2));
- if (bo->tiling == I915_TILING_Y) {
- DBG(("%s: fallback -- dst uses Y-tiling\n",
- __FUNCTION__));
- return FALSE;
- }
+ assert(box->x1 >= 0);
+ assert(box->y1 >= 0);
cmd = XY_COLOR_BLT_CMD;
if (bpp == 32)
@@ -1403,58 +1405,171 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
DBG(("%s: replacing last fill\n", __FUNCTION__));
kgem->batch[kgem->nbatch-5] = br13;
kgem->batch[kgem->nbatch-1] = color;
- if (--nbox == 0)
- return TRUE;
- box++;
+ return TRUE;
}
kgem_set_mode(kgem, KGEM_BLT);
if (!kgem_check_batch(kgem, 6) ||
!kgem_check_reloc(kgem, 1) ||
- !kgem_check_bo_fenced(kgem, bo, NULL))
+ !kgem_check_bo_fenced(kgem, bo, NULL)) {
+ _kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
+
+ b = kgem->batch + kgem->nbatch;
+
+ b[0] = cmd;
+ b[1] = br13;
+ b[2] = box->y1 << 16 | box->x1;
+ b[3] = box->y2 << 16 | box->x2;
+ b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4,
+ bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ I915_GEM_DOMAIN_RENDER |
+ KGEM_RELOC_FENCED,
+ 0);
+ b[5] = color;
+ kgem->nbatch += 6;
+
+ sna->blt_state.fill_bo = 0;
+ return TRUE;
+}
+
+Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
+ struct kgem_bo *bo, int bpp,
+ uint32_t pixel,
+ const BoxRec *box, int nbox)
+{
+ struct kgem *kgem = &sna->kgem;
+ uint32_t br13, cmd;
+
+#if DEBUG_NO_BLT || NO_BLT_FILL_BOXES
+ return FALSE;
+#endif
+
+ DBG(("%s (%d, %08x, %d) x %d\n",
+ __FUNCTION__, bpp, pixel, alu, nbox));
+
+ if (bo->tiling == I915_TILING_Y) {
+ DBG(("%s: fallback -- dst uses Y-tiling\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ if (nbox == 1)
+ return sna_blt_fill_box(sna, alu, bo, bpp, pixel, box);
+
+ br13 = bo->pitch;
+ cmd = XY_SCANLINE_BLT;
+ if (kgem->gen >= 40 && bo->tiling) {
+ cmd |= 1 << 11;
+ br13 >>= 2;
+ }
+ if (br13 > MAXSHORT)
+ return FALSE;
+
+ br13 |= 1<<31 | fill_ROP[alu] << 16;
+ switch (bpp) {
+ default: assert(0);
+ case 32: br13 |= 1 << 25; /* RGB8888 */
+ case 16: br13 |= 1 << 24; /* RGB565 */
+ case 8: break;
+ }
+
+ kgem_set_mode(kgem, KGEM_BLT);
+ if (!kgem_check_bo_fenced(kgem, bo, NULL) ||
+ !kgem_check_batch(kgem, 12)) {
_kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
+
+ if (sna->blt_state.fill_bo != bo->handle ||
+ sna->blt_state.fill_pixel != pixel)
+ {
+ uint32_t *b;
+
+ if (!kgem_check_reloc(kgem, 1)) {
+ _kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
+
+ b = kgem->batch + kgem->nbatch;
+ b[0] = XY_SETUP_MONO_PATTERN_SL_BLT;
+ if (bpp == 32)
+ b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+ b[1] = br13;
+ b[2] = 0;
+ b[3] = 0;
+ b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ I915_GEM_DOMAIN_RENDER |
+ KGEM_RELOC_FENCED,
+ 0);
+ b[5] = pixel;
+ b[6] = pixel;
+ b[7] = 0;
+ b[8] = 0;
+ kgem->nbatch += 9;
+
+ sna->blt_state.fill_bo = bo->handle;
+ sna->blt_state.fill_pixel = pixel;
+ }
do {
int nbox_this_time;
nbox_this_time = nbox;
- if (6*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 6;
- if (nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
- nbox_this_time = KGEM_RELOC_SIZE(kgem) - kgem->nreloc;
+ if (3*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+ nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 3;
assert(nbox_this_time);
nbox -= nbox_this_time;
do {
uint32_t *b = kgem->batch + kgem->nbatch;
- DBG(("%s: box=((%d, %d), (%d, %d))\n", __FUNCTION__,
- box->x1, box->y1, box->x2, box->y2));
+ DBG(("%s: (%d, %d), (%d, %d): %08x\n",
+ __FUNCTION__,
+ box->x1, box->y1,
+ box->x2, box->y2,
+ pixel));
assert(box->x1 >= 0);
assert(box->y1 >= 0);
+ assert(box->y2 * bo->pitch <= bo->size);
+ b = kgem->batch + kgem->nbatch;
+ kgem->nbatch += 3;
b[0] = cmd;
+ b[1] = box->y1 << 16 | box->x1;
+ b[2] = box->y2 << 16 | box->x2;
+ box++;
+ } while (--nbox_this_time);
+
+ if (nbox) {
+ uint32_t *b;
+
+ _kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+
+ b = kgem->batch + kgem->nbatch;
+ b[0] = XY_SETUP_MONO_PATTERN_SL_BLT;
+ if (bpp == 32)
+ b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
b[1] = br13;
- b[2] = box->y1 << 16 | box->x1;
- b[3] = box->y2 << 16 | box->x2;
- b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4,
- bo,
+ b[2] = 0;
+ b[3] = 0;
+ b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo,
I915_GEM_DOMAIN_RENDER << 16 |
I915_GEM_DOMAIN_RENDER |
KGEM_RELOC_FENCED,
0);
- b[5] = color;
- kgem->nbatch += 6;
- box++;
- } while (--nbox_this_time);
-
- if (nbox)
- _kgem_submit(kgem);
+ b[5] = pixel;
+ b[6] = pixel;
+ b[7] = 0;
+ b[8] = 0;
+ kgem->nbatch += 9;
+ }
} while (nbox);
- _kgem_set_mode(kgem, KGEM_BLT);
- sna->blt_state.fill_bo = 0;
return TRUE;
}
@@ -1512,8 +1627,10 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
kgem_set_mode(kgem, KGEM_BLT);
if (!kgem_check_batch(kgem, 8) ||
!kgem_check_reloc(kgem, 2) ||
- !kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL))
+ !kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL)) {
_kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
do {
int nbox_this_time;
@@ -1561,8 +1678,10 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
box++;
} while (--nbox_this_time);
- if (nbox)
+ if (nbox) {
_kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
} while (nbox);
if (kgem->gen >= 60 && kgem_check_batch(kgem, 3)) {
@@ -1572,6 +1691,5 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
kgem->nbatch += 3;
}
- _kgem_set_mode(kgem, KGEM_BLT);
return TRUE;
}