summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sna/sna.h4
-rw-r--r--src/sna/sna_accel.c33
-rw-r--r--src/sna/sna_io.c196
3 files changed, 119 insertions, 114 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7fe73597..2f14fad5 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -802,9 +802,7 @@ void sna_glyphs__shared(CARD8 op,
void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
void sna_glyphs_close(struct sna *sna);
-void sna_read_boxes(struct sna *sna,
- struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
- PixmapPtr dst, int16_t dst_dx, int16_t dst_dy,
+void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo,
const BoxRec *box, int n);
bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index dfa33560..a51e289f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -138,10 +138,7 @@ static void __sna_fallback_flush(DrawablePtr d)
0);
DBG(("%s: comparing with direct read...\n", __FUNCTION__));
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- tmp, 0, 0,
- &box, 1);
+ sna_read_boxes(sna, tmp, priv->gpu_bo, &box, 1);
src = pixmap->devPrivate.ptr;
dst = tmp->devPrivate.ptr;
@@ -2054,9 +2051,7 @@ skip_inplace_map:
}
if (!ok) {
assert(has_coherent_ptr(sna_pixmap(pixmap)));
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
+ sna_read_boxes(sna, pixmap, priv->gpu_bo,
box, n);
}
}
@@ -2491,9 +2486,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
}
if (!ok) {
assert(has_coherent_ptr(sna_pixmap(pixmap)));
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
+ sna_read_boxes(sna, pixmap, priv->gpu_bo,
box, n);
}
}
@@ -2515,9 +2508,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
region->extents.y2 - region->extents.y1 == 1) {
/* Often associated with synchronisation, KISS */
DBG(("%s: single pixel read\n", __FUNCTION__));
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
+ sna_read_boxes(sna, pixmap, priv->gpu_bo,
&region->extents, 1);
goto done;
}
@@ -2542,9 +2533,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if ((flags & MOVE_WRITE) == 0 &&
region->extents.x2 - region->extents.x1 == 1 &&
region->extents.y2 - region->extents.y1 == 1) {
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
+ sna_read_boxes(sna, pixmap, priv->gpu_bo,
&region->extents, 1);
goto done;
}
@@ -2608,9 +2597,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (!ok) {
assert(has_coherent_ptr(sna_pixmap(pixmap)));
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
+ sna_read_boxes(sna, pixmap, priv->gpu_bo,
box, n);
}
}
@@ -2635,9 +2622,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
}
if (!ok) {
assert(has_coherent_ptr(sna_pixmap(pixmap)));
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
+ sna_read_boxes(sna, pixmap, priv->gpu_bo,
box, n);
}
@@ -2663,9 +2648,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
}
if (!ok) {
assert(has_coherent_ptr(sna_pixmap(pixmap)));
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
+ sna_read_boxes(sna, pixmap, priv->gpu_bo,
box, n);
}
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index a4932b8d..78614622 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -53,55 +53,91 @@ static inline bool must_tile(struct sna *sna, int width, int height)
upload_too_large(sna, width, height));
}
-static bool bo_inplace_tiled(struct kgem *kgem, struct kgem_bo *bo, bool write)
+static bool download_inplace__cpu(struct kgem *kgem,
+ PixmapPtr p, struct kgem_bo *bo,
+ const BoxRec *box, int nbox)
{
- if (bo->tiling != I915_TILING_X)
- return false;
+ BoxRec extents;
- return kgem_bo_can_map__cpu(kgem, bo, write);
-}
+ switch (bo->tiling) {
+ case I915_TILING_X:
+ if (!kgem->memcpy_from_tiled_x)
+ return false;
+ case I915_TILING_NONE:
+ break;
+ default:
+ return false;
+ }
-static bool download_inplace__tiled(struct kgem *kgem, struct kgem_bo *bo)
-{
- if (!kgem->memcpy_from_tiled_x)
+ if (!kgem_bo_can_map__cpu(kgem, bo, false))
return false;
- return bo_inplace_tiled(kgem, bo, false);
+ if (kgem->has_llc)
+ return true;
+
+ extents = *box;
+ while (--nbox) {
+ ++box;
+ if (box->x1 < extents.x1)
+ extents.x1 = box->x1;
+ if (box->x2 > extents.x2)
+ extents.x2 = box->x2;
+ extents.y2 = box->y2;
+ }
+
+ if (extents.x2 - extents.x1 == p->drawable.width &&
+ extents.y2 - extents.y1 == p->drawable.height)
+ return true;
+
+ return __kgem_bo_size(bo) <= PAGE_SIZE;
}
static bool
-read_boxes_inplace__tiled(struct kgem *kgem,
- struct kgem_bo *bo, int16_t src_dx, int16_t src_dy,
- PixmapPtr pixmap, int16_t dst_dx, int16_t dst_dy,
- const BoxRec *box, int n)
+read_boxes_inplace__cpu(struct kgem *kgem,
+ PixmapPtr pixmap, struct kgem_bo *bo,
+ const BoxRec *box, int n)
{
int bpp = pixmap->drawable.bitsPerPixel;
void *src, *dst = pixmap->devPrivate.ptr;
int src_pitch = bo->pitch;
int dst_pitch = pixmap->devKind;
- assert(bo->tiling == I915_TILING_X);
+ if (!download_inplace__cpu(kgem, dst, bo, box, n))
+ return false;
+
+ assert(kgem_bo_can_map__cpu(kgem, bo, false));
+ assert(bo->tiling != I915_TILING_Y);
src = __kgem_bo_map__cpu(kgem, bo);
if (src == NULL)
return false;
kgem_bo_sync__cpu_full(kgem, bo, 0);
- do {
- memcpy_from_tiled_x(kgem, src, dst, bpp, src_pitch, dst_pitch,
- box->x1 + src_dx, box->y1 + src_dy,
- box->x1 + dst_dx, box->y1 + dst_dy,
- box->x2 - box->x1, box->y2 - box->y1);
- box++;
- } while (--n);
+ if (bo->tiling == I915_TILING_X) {
+ assert(kgem->memcpy_from_tiled_x);
+ do {
+ memcpy_from_tiled_x(kgem, src, dst, bpp, src_pitch, dst_pitch,
+ box->x1, box->y1,
+ box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
+ box++;
+ } while (--n);
+ } else {
+ do {
+ memcpy_blt(src, dst, bpp, src_pitch, dst_pitch,
+ box->x1, box->y1,
+ box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
+ box++;
+ } while (--n);
+ }
__kgem_bo_unmap__cpu(kgem, bo, src);
return true;
}
static void read_boxes_inplace(struct kgem *kgem,
- struct kgem_bo *bo, int16_t src_dx, int16_t src_dy,
- PixmapPtr pixmap, int16_t dst_dx, int16_t dst_dy,
+ PixmapPtr pixmap, struct kgem_bo *bo,
const BoxRec *box, int n)
{
int bpp = pixmap->drawable.bitsPerPixel;
@@ -109,10 +145,7 @@ static void read_boxes_inplace(struct kgem *kgem,
int src_pitch = bo->pitch;
int dst_pitch = pixmap->devKind;
- if (download_inplace__tiled(kgem, bo) &&
- read_boxes_inplace__tiled(kgem, bo, src_dx, src_dy,
- pixmap, dst_dx, dst_dy,
- box, n))
+ if (read_boxes_inplace__cpu(kgem, pixmap, bo, box, n))
return;
DBG(("%s x %d, tiling=%d\n", __FUNCTION__, n, bo->tiling));
@@ -134,31 +167,36 @@ static void read_boxes_inplace(struct kgem *kgem,
assert(box->x2 > box->x1);
assert(box->y2 > box->y1);
- assert(box->x1 + src_dx >= 0);
- assert(box->y1 + src_dy >= 0);
- assert(box->x2 + src_dx <= pixmap->drawable.width);
- assert(box->y2 + src_dy <= pixmap->drawable.height);
+ assert(box->x1 >= 0);
+ assert(box->y1 >= 0);
+ assert(box->x2 <= pixmap->drawable.width);
+ assert(box->y2 <= pixmap->drawable.height);
- assert(box->x1 + dst_dx >= 0);
- assert(box->y1 + dst_dy >= 0);
- assert(box->x2 + dst_dx <= pixmap->drawable.width);
- assert(box->y2 + dst_dy <= pixmap->drawable.height);
+ assert(box->x1 >= 0);
+ assert(box->y1 >= 0);
+ assert(box->x2 <= pixmap->drawable.width);
+ assert(box->y2 <= pixmap->drawable.height);
memcpy_blt(src, dst, bpp,
src_pitch, dst_pitch,
- box->x1 + src_dx, box->y1 + src_dy,
- box->x1 + dst_dx, box->y1 + dst_dy,
+ box->x1, box->y1,
+ box->x1, box->y1,
box->x2 - box->x1, box->y2 - box->y1);
box++;
} while (--n);
}
-static bool download_inplace(struct kgem *kgem, struct kgem_bo *bo)
+static bool download_inplace(struct kgem *kgem,
+ PixmapPtr p, struct kgem_bo *bo,
+ const BoxRec *box, int nbox)
{
+ bool cpu;
+
if (unlikely(kgem->wedged))
return true;
- if (!kgem_bo_can_map(kgem, bo) && !download_inplace__tiled(kgem, bo))
+ cpu = download_inplace__cpu(kgem, p, bo, box, nbox);
+ if (!cpu && !kgem_bo_can_map(kgem, bo))
return false;
if (FORCE_INPLACE)
@@ -167,14 +205,10 @@ static bool download_inplace(struct kgem *kgem, struct kgem_bo *bo)
if (kgem->can_blt_cpu && kgem->max_cpu_size)
return false;
- return !__kgem_bo_is_busy(kgem, bo) ||
- bo->tiling == I915_TILING_NONE ||
- download_inplace__tiled(kgem, bo);
+ return !__kgem_bo_is_busy(kgem, bo) || cpu;
}
-void sna_read_boxes(struct sna *sna,
- struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
- PixmapPtr dst, int16_t dst_dx, int16_t dst_dy,
+void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo,
const BoxRec *box, int nbox)
{
struct kgem *kgem = &sna->kgem;
@@ -188,20 +222,19 @@ void sna_read_boxes(struct sna *sna,
int n, cmd, br13;
bool can_blt;
- DBG(("%s x %d, src=(handle=%d, offset=(%d,%d)), dst=(size=(%d, %d), offset=(%d,%d))\n",
- __FUNCTION__, nbox, src_bo->handle, src_dx, src_dy,
- dst->drawable.width, dst->drawable.height, dst_dx, dst_dy));
+ DBG(("%s x %d, src=(handle=%d), dst=(size=(%d, %d)\n",
+ __FUNCTION__, nbox, src_bo->handle, src_dy,
+ dst->drawable.width, dst->drawable.height));
#ifndef NDEBUG
for (n = 0; n < nbox; n++) {
- if (box[n].x1 + src_dx < 0 || box[n].y1 + src_dy < 0 ||
- (box[n].x2 + src_dx) * dst->drawable.bitsPerPixel/8 > src_bo->pitch ||
- (box[n].y2 + src_dy) * src_bo->pitch > kgem_bo_size(src_bo))
+ if (box[n].x1 < 0 || box[n].y1 < 0 ||
+ box[n].x2 * dst->drawable.bitsPerPixel/8 > src_bo->pitch ||
+ box[n].y2 * src_bo->pitch > kgem_bo_size(src_bo))
{
- FatalError("source out-of-bounds box[%d]=(%d, %d), (%d, %d) + (%d, %d), pitch=%d, size=%d\n", n,
+ FatalError("source out-of-bounds box[%d]=(%d, %d), (%d, %d), pitch=%d, size=%d\n", n,
box[n].x1, box[n].y1,
box[n].x2, box[n].y2,
- src_dx, src_dy,
src_bo->pitch, kgem_bo_size(src_bo));
}
}
@@ -213,12 +246,9 @@ void sna_read_boxes(struct sna *sna,
* this path.
*/
- if (download_inplace(kgem, src_bo)) {
+ if (download_inplace(kgem, dst, src_bo, box ,nbox)) {
fallback:
- read_boxes_inplace(kgem,
- src_bo, src_dx, src_dy,
- dst, dst_dx, dst_dy,
- box, nbox);
+ read_boxes_inplace(kgem, dst, src_bo, box, nbox);
return;
}
@@ -297,11 +327,10 @@ fallback:
if (!box_intersect(c, &tile))
continue;
- DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n",
+ DBG(("%s: box(%d, %d), (%d, %d),, dst=(%d, %d)\n",
__FUNCTION__,
c->x1, c->y1,
c->x2, c->y2,
- src_dx, src_dy,
c->x1 - tile.x1,
c->y1 - tile.y1));
c++;
@@ -322,7 +351,7 @@ fallback:
}
if (!sna->render.copy_boxes(sna, GXcopy,
- dst, src_bo, src_dx, src_dy,
+ dst, src_bo, 0, 0,
&tmp, dst_bo, -tile.x1, -tile.y1,
clipped, c-clipped, COPY_LAST)) {
kgem_bo_destroy(&sna->kgem, dst_bo);
@@ -339,8 +368,7 @@ fallback:
dst_bo->pitch, dst->devKind,
c->x1 - tile.x1,
c->y1 - tile.y1,
- c->x1 + dst_dx,
- c->y1 + dst_dy,
+ c->x1, c->y1,
c->x2 - c->x1,
c->y2 - c->y1);
}
@@ -362,7 +390,7 @@ fallback:
goto fallback;
if (!sna->render.copy_boxes(sna, GXcopy,
- dst, src_bo, src_dx, src_dy,
+ dst, src_bo, 0, 0,
&tmp, dst_bo, -extents.x1, -extents.y1,
box, nbox, COPY_LAST)) {
kgem_bo_destroy(&sna->kgem, dst_bo);
@@ -377,8 +405,7 @@ fallback:
dst_bo->pitch, dst->devKind,
box[n].x1 - extents.x1,
box[n].y1 - extents.y1,
- box[n].x1 + dst_dx,
- box[n].y1 + dst_dy,
+ box[n].x1, box[n].y1,
box[n].x2 - box[n].x1,
box[n].y2 - box[n].y1);
}
@@ -401,10 +428,7 @@ fallback:
dst_bo = kgem_create_buffer(kgem, offset, KGEM_BUFFER_LAST, &ptr);
if (!dst_bo) {
- read_boxes_inplace(kgem,
- src_bo, src_dx, src_dy,
- dst, dst_dx, dst_dy,
- box, nbox);
+ read_boxes_inplace(kgem, dst, src_bo, box, nbox);
return;
}
@@ -455,15 +479,13 @@ fallback:
uint32_t *b = kgem->batch + kgem->nbatch;
DBG((" blt offset %x: (%d, %d) x (%d, %d), pitch=%d\n",
- offset,
- tmp_box[n].x1 + src_dx,
- tmp_box[n].y1 + src_dy,
+ offset, tmp_box[n].x1, tmp_box[n].y1,
width, height, pitch));
- assert(tmp_box[n].x1 + src_dx >= 0);
- assert((tmp_box[n].x2 + src_dx) * dst->drawable.bitsPerPixel/8 <= src_bo->pitch);
- assert(tmp_box[n].y1 + src_dy >= 0);
- assert((tmp_box[n].y2 + src_dy) * src_bo->pitch <= kgem_bo_size(src_bo));
+ 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;
@@ -474,7 +496,7 @@ fallback:
I915_GEM_DOMAIN_RENDER |
KGEM_RELOC_FENCED,
offset);
- b[5] = (tmp_box[n].y1 + src_dy) << 16 | (tmp_box[n].x1 + src_dx);
+ 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 |
@@ -505,20 +527,19 @@ fallback:
DBG((" copy offset %lx [%08x...%08x...%08x]: (%d, %d) x (%d, %d), src pitch=%d, dst pitch=%d, bpp=%d\n",
(long)((char *)src - (char *)ptr),
*(uint32_t*)src, *(uint32_t*)(src+pitch*height/2 + pitch/2 - 4), *(uint32_t*)(src+pitch*height - 4),
- box->x1 + dst_dx,
- box->y1 + dst_dy,
+ box->x1, box->y1,
width, height,
pitch, dst->devKind, cpp*8));
- assert(box->x1 + dst_dx >= 0);
- assert(box->x2 + dst_dx <= dst->drawable.width);
- assert(box->y1 + dst_dy >= 0);
- assert(box->y2 + dst_dy <= dst->drawable.height);
+ assert(box->x1 >= 0);
+ assert(box->x2 <= dst->drawable.width);
+ assert(box->y1 >= 0);
+ assert(box->y2 <= dst->drawable.height);
memcpy_blt(src, dst->devPrivate.ptr, cpp*8,
pitch, dst->devKind,
0, 0,
- box->x1 + dst_dx, box->y1 + dst_dy,
+ box->x1, box->y1,
width, height);
box++;
@@ -534,7 +555,10 @@ static bool upload_inplace__tiled(struct kgem *kgem, struct kgem_bo *bo)
if (!kgem->memcpy_to_tiled_x)
return false;
- return bo_inplace_tiled(kgem, bo, true);
+ if (bo->tiling != I915_TILING_X)
+ return false;
+
+ return kgem_bo_can_map__cpu(kgem, bo, true);
}
static bool