summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-11 19:51:42 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-11 19:54:12 +0000
commitc64a9d0683e047a7eb041df78db746f6dd387b5e (patch)
tree94e490ae50c8545539f723c00e05f0f71dc3527c
parentb82851e74d5010ee08938ee42fa44c29fed633b1 (diff)
sna: Choose a stride for the indirect replacement
Don't blithely assume that the incoming bytes are appropriately aligned for the destination buffer. Indeed we may be replacing the destination bo with the shadow bytes out of another,larger, pixmap, in which case we do need to create a stride that is appropriate for the upload an perform the 2D copy. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_io.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 3c17d3aa..a7d4da5f 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -820,14 +820,25 @@ indirect_replace(struct sna *sna,
&box, 1);
} else {
uint32_t cmd, br13, *b;
+ int pitch;
+
+ pitch = pixmap->drawable.width * pixmap->drawable.bitsPerPixel;
+ pitch = ALIGN(pitch, 32) >> 3;
src_bo = kgem_create_buffer(kgem,
- stride * pixmap->drawable.height,
+ pitch * pixmap->drawable.height,
KGEM_BUFFER_WRITE,
&ptr);
if (!src_bo)
return false;
+ memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel,
+ stride, pitch,
+ 0, 0,
+ 0, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
+
cmd = XY_SRC_COPY_BLT_CMD;
br13 = bo->pitch;
if (kgem->gen >= 40 && bo->tiling) {
@@ -852,8 +863,6 @@ indirect_replace(struct sna *sna,
_kgem_set_mode(kgem, KGEM_BLT);
}
- memcpy(ptr, src, stride * pixmap->drawable.height);
-
b = kgem->batch + kgem->nbatch;
b[0] = cmd;
b[1] = br13;
@@ -865,7 +874,7 @@ indirect_replace(struct sna *sna,
KGEM_RELOC_FENCED,
0);
b[5] = 0;
- b[6] = stride;
+ b[6] = pitch;
b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
I915_GEM_DOMAIN_RENDER << 16 |
KGEM_RELOC_FENCED,