summaryrefslogtreecommitdiff
path: root/src/sna/sna_io.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-11-30 16:28:02 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-11-02 13:50:15 +0000
commitd507b6b9825cc18f41911727ef2ba9b9593cfe21 (patch)
treee35776aa07dc8d885ae10368d555ee1985ca53a7 /src/sna/sna_io.c
parent9681b1422e4531a19e0117e1b1a97668f6b6a571 (diff)
Prepare for changes in the BLT unit on future generations
Adapt the legacy BLT commands in preparation for future changes. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_io.c')
-rw-r--r--src/sna/sna_io.c679
1 files changed, 466 insertions, 213 deletions
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 5d238f48..b5e4f376 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -461,7 +461,7 @@ fallback:
}
kgem_set_mode(kgem, KGEM_BLT, dst_bo);
- if (!kgem_check_batch(kgem, 8) ||
+ if (!kgem_check_batch(kgem, 10) ||
!kgem_check_reloc_and_exec(kgem, 2) ||
!kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) {
kgem_submit(kgem);
@@ -473,59 +473,123 @@ fallback:
tmp_nbox = nbox;
tmp_box = box;
offset = 0;
- do {
- int nbox_this_time;
-
- nbox_this_time = tmp_nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
- if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
- nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
- assert(nbox_this_time);
- tmp_nbox -= nbox_this_time;
-
- for (n = 0; n < nbox_this_time; n++) {
- int height = tmp_box[n].y2 - tmp_box[n].y1;
- int width = tmp_box[n].x2 - tmp_box[n].x1;
- int pitch = PITCH(width, cpp);
- uint32_t *b = kgem->batch + kgem->nbatch;
-
- DBG((" blt offset %x: (%d, %d) x (%d, %d), pitch=%d\n",
- offset, tmp_box[n].x1, tmp_box[n].y1,
- width, height, pitch));
-
- assert(tmp_box[n].x1 >= 0);
- assert(tmp_box[n].x2 * dst->drawable.bitsPerPixel/8 <= src_bo->pitch);
- assert(tmp_box[n].y1 >= 0);
- assert(tmp_box[n].y2 * src_bo->pitch <= kgem_bo_size(src_bo));
-
- b[0] = cmd;
- b[1] = br13 | pitch;
- b[2] = 0;
- b[3] = height << 16 | width;
- b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo,
- I915_GEM_DOMAIN_RENDER << 16 |
- I915_GEM_DOMAIN_RENDER |
- KGEM_RELOC_FENCED,
- offset);
- b[5] = tmp_box[n].y1 << 16 | tmp_box[n].x1;
- b[6] = src_pitch;
- b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
- I915_GEM_DOMAIN_RENDER << 16 |
- KGEM_RELOC_FENCED,
- 0);
- kgem->nbatch += 8;
-
- offset += pitch * height;
- }
+ if (sna->kgem.gen >= 0100) {
+ cmd |= 8;
+ do {
+ int nbox_this_time;
+
+ nbox_this_time = tmp_nbox;
+ if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+ nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
+ nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
+ assert(nbox_this_time);
+ tmp_nbox -= nbox_this_time;
+
+ assert(kgem->mode == KGEM_BLT);
+ for (n = 0; n < nbox_this_time; n++) {
+ int height = tmp_box[n].y2 - tmp_box[n].y1;
+ int width = tmp_box[n].x2 - tmp_box[n].x1;
+ int pitch = PITCH(width, cpp);
+ uint32_t *b = kgem->batch + kgem->nbatch;
+
+ DBG((" blt offset %x: (%d, %d) x (%d, %d), pitch=%d\n",
+ offset,
+ tmp_box[n].x1, tmp_box[n].y1,
+ width, height, pitch));
+
+ assert(tmp_box[n].x1 >= 0);
+ assert(tmp_box[n].x2 * dst->drawable.bitsPerPixel/8 <= src_bo->pitch);
+ assert(tmp_box[n].y1 >= 0);
+ assert(tmp_box[n].y2 * src_bo->pitch <= kgem_bo_size(src_bo));
+
+ b[0] = cmd;
+ b[1] = br13 | pitch;
+ b[2] = 0;
+ b[3] = height << 16 | width;
+ *(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,
+ offset);
+ b[6] = tmp_box[n].y1 << 16 | tmp_box[n].x1;
+ b[7] = src_pitch;
+ *(uint64_t *)(b+8) =
+ kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ KGEM_RELOC_FENCED,
+ 0);
+ kgem->nbatch += 10;
+
+ offset += pitch * height;
+ }
- _kgem_submit(kgem);
- if (!tmp_nbox)
- break;
+ _kgem_submit(kgem);
+ if (!tmp_nbox)
+ break;
- _kgem_set_mode(kgem, KGEM_BLT);
- tmp_box += nbox_this_time;
- } while (1);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ tmp_box += nbox_this_time;
+ } while (1);
+ } else {
+ cmd |= 6;
+ do {
+ int nbox_this_time;
+
+ nbox_this_time = tmp_nbox;
+ if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+ nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
+ nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
+ assert(nbox_this_time);
+ tmp_nbox -= nbox_this_time;
+
+ assert(kgem->mode == KGEM_BLT);
+ for (n = 0; n < nbox_this_time; n++) {
+ int height = tmp_box[n].y2 - tmp_box[n].y1;
+ int width = tmp_box[n].x2 - tmp_box[n].x1;
+ int pitch = PITCH(width, cpp);
+ uint32_t *b = kgem->batch + kgem->nbatch;
+
+ DBG((" blt offset %x: (%d, %d) x (%d, %d), pitch=%d\n",
+ offset,
+ tmp_box[n].x1, tmp_box[n].y1,
+ width, height, pitch));
+
+ assert(tmp_box[n].x1 >= 0);
+ assert(tmp_box[n].x2 * dst->drawable.bitsPerPixel/8 <= src_bo->pitch);
+ assert(tmp_box[n].y1 >= 0);
+ assert(tmp_box[n].y2 * src_bo->pitch <= kgem_bo_size(src_bo));
+
+ b[0] = cmd;
+ b[1] = br13 | pitch;
+ b[2] = 0;
+ b[3] = height << 16 | width;
+ b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ I915_GEM_DOMAIN_RENDER |
+ KGEM_RELOC_FENCED,
+ offset);
+ b[5] = tmp_box[n].y1 << 16 | tmp_box[n].x1;
+ b[6] = src_pitch;
+ b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ KGEM_RELOC_FENCED,
+ 0);
+ kgem->nbatch += 8;
+
+ offset += pitch * height;
+ }
+
+ _kgem_submit(kgem);
+ if (!tmp_nbox)
+ break;
+
+ _kgem_set_mode(kgem, KGEM_BLT);
+ tmp_box += nbox_this_time;
+ } while (1);
+ }
assert(offset == __kgem_buffer_size(dst_bo));
kgem_buffer_read_sync(kgem, dst_bo);
@@ -924,7 +988,7 @@ tile:
}
kgem_set_mode(kgem, KGEM_BLT, dst_bo);
- if (!kgem_check_batch(kgem, 8) ||
+ if (!kgem_check_batch(kgem, 10) ||
!kgem_check_reloc_and_exec(kgem, 2) ||
!kgem_check_bo_fenced(kgem, dst_bo)) {
kgem_submit(kgem);
@@ -933,91 +997,185 @@ tile:
_kgem_set_mode(kgem, KGEM_BLT);
}
- do {
- int nbox_this_time;
-
- nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
- if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
- nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
- assert(nbox_this_time);
- nbox -= nbox_this_time;
-
- /* Count the total number of bytes to be read and allocate a
- * single buffer large enough. Or if it is very small, combine
- * with other allocations. */
- offset = 0;
- for (n = 0; n < nbox_this_time; n++) {
- int height = box[n].y2 - box[n].y1;
- int width = box[n].x2 - box[n].x1;
- offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height;
- }
+ if (kgem->gen >= 0100) {
+ cmd |= 8;
+ do {
+ int nbox_this_time;
+
+ nbox_this_time = nbox;
+ if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+ nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
+ nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
+ assert(nbox_this_time);
+ nbox -= nbox_this_time;
+
+ /* Count the total number of bytes to be read and allocate a
+ * single buffer large enough. Or if it is very small, combine
+ * with other allocations. */
+ offset = 0;
+ for (n = 0; n < nbox_this_time; n++) {
+ int height = box[n].y2 - box[n].y1;
+ int width = box[n].x2 - box[n].x1;
+ offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height;
+ }
- src_bo = kgem_create_buffer(kgem, offset,
- KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0),
- &ptr);
- if (!src_bo)
- break;
+ src_bo = kgem_create_buffer(kgem, offset,
+ KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0),
+ &ptr);
+ 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;
- offset = 0;
+ 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 (nbox) {
+ _kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
+
+ kgem_bo_destroy(kgem, src_bo);
+ } while (nbox);
+ } else {
+ cmd |= 6;
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);
-
- 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);
- b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo,
- I915_GEM_DOMAIN_RENDER << 16 |
- I915_GEM_DOMAIN_RENDER |
- KGEM_RELOC_FENCED,
- 0);
- b[5] = 0;
- b[6] = pitch;
- b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
- I915_GEM_DOMAIN_RENDER << 16 |
- KGEM_RELOC_FENCED,
- offset);
- kgem->nbatch += 8;
+ int nbox_this_time;
+
+ nbox_this_time = nbox;
+ if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+ nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
+ nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
+ assert(nbox_this_time);
+ nbox -= nbox_this_time;
+
+ /* Count the total number of bytes to be read and allocate a
+ * single buffer large enough. Or if it is very small, combine
+ * with other allocations. */
+ offset = 0;
+ for (n = 0; n < nbox_this_time; n++) {
+ int height = box[n].y2 - box[n].y1;
+ int width = box[n].x2 - box[n].x1;
+ offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height;
+ }
- box++;
- offset += pitch * height;
- } while (--nbox_this_time);
- assert(offset == __kgem_buffer_size(src_bo));
+ src_bo = kgem_create_buffer(kgem, offset,
+ KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0),
+ &ptr);
+ if (!src_bo)
+ break;
- if (nbox) {
- _kgem_submit(kgem);
- _kgem_set_mode(kgem, KGEM_BLT);
- }
+ 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);
+ b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ I915_GEM_DOMAIN_RENDER |
+ KGEM_RELOC_FENCED,
+ 0);
+ b[5] = 0;
+ b[6] = pitch;
+ b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ KGEM_RELOC_FENCED,
+ offset);
+ kgem->nbatch += 8;
+
+ box++;
+ offset += pitch * height;
+ } while (--nbox_this_time);
+ assert(offset == __kgem_buffer_size(src_bo));
+
+ if (nbox) {
+ _kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
- kgem_bo_destroy(kgem, src_bo);
- } while (nbox);
+ kgem_bo_destroy(kgem, src_bo);
+ } while (nbox);
+ }
sna->blt_state.fill_bo = 0;
return true;
@@ -1315,7 +1473,7 @@ tile:
}
kgem_set_mode(kgem, KGEM_BLT, dst_bo);
- if (!kgem_check_batch(kgem, 8) ||
+ if (!kgem_check_batch(kgem, 10) ||
!kgem_check_reloc_and_exec(kgem, 2) ||
!kgem_check_bo_fenced(kgem, dst_bo)) {
kgem_submit(kgem);
@@ -1324,92 +1482,187 @@ tile:
_kgem_set_mode(kgem, KGEM_BLT);
}
- do {
- int nbox_this_time;
-
- nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
- if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
- nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
- assert(nbox_this_time);
- nbox -= nbox_this_time;
-
- /* Count the total number of bytes to be read and allocate a
- * single buffer large enough. Or if it is very small, combine
- * with other allocations. */
- offset = 0;
- for (n = 0; n < nbox_this_time; n++) {
- int height = box[n].y2 - box[n].y1;
- int width = box[n].x2 - box[n].x1;
- offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height;
- }
+ if (sna->kgem.gen >= 0100) {
+ cmd |= 8;
+ do {
+ int nbox_this_time;
+
+ nbox_this_time = nbox;
+ if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+ nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
+ nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
+ assert(nbox_this_time);
+ nbox -= nbox_this_time;
+
+ /* Count the total number of bytes to be read and allocate a
+ * single buffer large enough. Or if it is very small, combine
+ * with other allocations. */
+ offset = 0;
+ for (n = 0; n < nbox_this_time; n++) {
+ int height = box[n].y2 - box[n].y1;
+ int width = box[n].x2 - box[n].x1;
+ offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height;
+ }
+
+ src_bo = kgem_create_buffer(kgem, offset,
+ KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0),
+ &ptr);
+ if (!src_bo)
+ break;
- src_bo = kgem_create_buffer(kgem, offset,
- KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0),
- &ptr);
- 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;
- offset = 0;
+ 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_xor(src, (char *)ptr + offset,
+ dst->drawable.bitsPerPixel,
+ stride, pitch,
+ box->x1 + src_dx, box->y1 + src_dy,
+ 0, 0,
+ width, height,
+ and, or);
+
+ 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 (nbox) {
+ _kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
+
+ kgem_bo_destroy(kgem, src_bo);
+ } while (nbox);
+ } else {
+ cmd |= 6;
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_xor(src, (char *)ptr + offset,
- dst->drawable.bitsPerPixel,
- stride, pitch,
- box->x1 + src_dx, box->y1 + src_dy,
- 0, 0,
- width, height,
- and, or);
-
- 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);
- b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo,
- I915_GEM_DOMAIN_RENDER << 16 |
- I915_GEM_DOMAIN_RENDER |
- KGEM_RELOC_FENCED,
- 0);
- b[5] = 0;
- b[6] = pitch;
- b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
- I915_GEM_DOMAIN_RENDER << 16 |
- KGEM_RELOC_FENCED,
- offset);
- kgem->nbatch += 8;
+ int nbox_this_time;
+
+ nbox_this_time = nbox;
+ if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
+ nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
+ nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
+ assert(nbox_this_time);
+ nbox -= nbox_this_time;
+
+ /* Count the total number of bytes to be read and allocate a
+ * single buffer large enough. Or if it is very small, combine
+ * with other allocations. */
+ offset = 0;
+ for (n = 0; n < nbox_this_time; n++) {
+ int height = box[n].y2 - box[n].y1;
+ int width = box[n].x2 - box[n].x1;
+ offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height;
+ }
- box++;
- offset += pitch * height;
- } while (--nbox_this_time);
- assert(offset == __kgem_buffer_size(src_bo));
+ src_bo = kgem_create_buffer(kgem, offset,
+ KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0),
+ &ptr);
+ if (!src_bo)
+ break;
- if (nbox) {
- _kgem_submit(kgem);
- _kgem_set_mode(kgem, KGEM_BLT);
- }
+ 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_xor(src, (char *)ptr + offset,
+ dst->drawable.bitsPerPixel,
+ stride, pitch,
+ box->x1 + src_dx, box->y1 + src_dy,
+ 0, 0,
+ width, height,
+ and, or);
- kgem_bo_destroy(kgem, src_bo);
- } while (nbox);
+ 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);
+ b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ I915_GEM_DOMAIN_RENDER |
+ KGEM_RELOC_FENCED,
+ 0);
+ b[5] = 0;
+ b[6] = pitch;
+ b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
+ I915_GEM_DOMAIN_RENDER << 16 |
+ KGEM_RELOC_FENCED,
+ offset);
+ kgem->nbatch += 8;
+
+ box++;
+ offset += pitch * height;
+ } while (--nbox_this_time);
+ assert(offset == __kgem_buffer_size(src_bo));
+
+ if (nbox) {
+ _kgem_submit(kgem);
+ _kgem_set_mode(kgem, KGEM_BLT);
+ }
+
+ kgem_bo_destroy(kgem, src_bo);
+ } while (nbox);
+ }
sna->blt_state.fill_bo = 0;
return true;