summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-06-15 13:25:39 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-06-18 10:54:16 +0100
commit40329e34b9ac65d930757d53283b7d8f4066c3a2 (patch)
tree770224c89b7d7bea55d3082f1612929b48be8e31
parentabb522e07a2c3bf39e2587ddedc4bb8ac955c536 (diff)
sna: Add extra assertions to sanity check CPU access is coherent
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c4
-rw-r--r--src/sna/kgem.h1
-rw-r--r--src/sna/sna_accel.c52
-rw-r--r--src/sna/sna_io.c1
4 files changed, 50 insertions, 8 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 65d12053..66dce479 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -104,7 +104,6 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
#define MAX_CPU_VMA_CACHE INT16_MAX
#define MAP_PRESERVE_TIME 10
-#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3))
#define MAKE_CPU_MAP(ptr) ((void*)((uintptr_t)(ptr) | 1))
#define MAKE_USER_MAP(ptr) ((void*)((uintptr_t)(ptr) | 3))
#define IS_USER_MAP(ptr) ((uintptr_t)(ptr) & 2)
@@ -5659,6 +5658,7 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
bo->size.bytes -= stride;
}
+ bo->map = MAKE_CPU_MAP(*ret);
bo->pitch = stride;
bo->unique_id = kgem_get_unique_id(kgem);
return bo;
@@ -5703,7 +5703,7 @@ void kgem_proxy_bo_attach(struct kgem_bo *bo,
struct kgem_bo **ptr)
{
DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
- assert(bo->map == NULL);
+ assert(bo->map == NULL || IS_CPU_MAP(bo->map));
assert(bo->proxy);
list_add(&bo->vma, &bo->proxy->vma);
bo->map = ptr;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index ae5aafa3..33a4db08 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -58,6 +58,7 @@ struct kgem_bo {
void *map;
#define IS_CPU_MAP(ptr) ((uintptr_t)(ptr) & 1)
#define IS_GTT_MAP(ptr) (ptr && ((uintptr_t)(ptr) & 1) == 0)
+#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3))
struct kgem_bo_binding {
struct kgem_bo_binding *next;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index b848ac0f..21130ded 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1412,6 +1412,24 @@ static inline bool has_coherent_map(struct sna *sna,
return bo->domain == DOMAIN_CPU || sna->kgem.has_llc;
}
+static inline bool has_coherent_ptr(struct sna_pixmap *priv)
+{
+ if (priv == NULL)
+ return true;
+
+ if (!priv->mapped) {
+ if (!priv->cpu_bo)
+ return true;
+
+ return priv->pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map);
+ }
+
+ if (priv->cpu && !IS_CPU_MAP(priv->gpu_bo->map))
+ return false;
+
+ return priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map);
+}
+
static inline bool pixmap_inplace(struct sna *sna,
PixmapPtr pixmap,
struct sna_pixmap *priv,
@@ -2006,11 +2024,13 @@ skip_inplace_map:
pixmap, priv->cpu_bo, 0, 0,
box, n, COPY_LAST);
}
- if (!ok)
+ if (!ok) {
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
sna_read_boxes(sna,
priv->gpu_bo, 0, 0,
pixmap, 0, 0,
box, n);
+ }
}
__sna_damage_destroy(DAMAGE_PTR(priv->gpu_damage));
@@ -2068,6 +2088,7 @@ done:
assert(pixmap->devPrivate.ptr);
assert(pixmap->devKind);
assert_pixmap_damage(pixmap);
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
return true;
}
@@ -2389,11 +2410,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
pixmap, priv->cpu_bo, 0, 0,
box, n, COPY_LAST);
}
- if (!ok)
+ if (!ok) {
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
sna_read_boxes(sna,
priv->gpu_bo, 0, 0,
pixmap, 0, 0,
box, n);
+ }
}
sna_damage_destroy(&priv->gpu_damage);
}
@@ -2504,11 +2527,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
box, n, COPY_LAST);
}
- if (!ok)
+ if (!ok) {
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
sna_read_boxes(sna,
priv->gpu_bo, 0, 0,
pixmap, 0, 0,
box, n);
+ }
}
sna_damage_destroy(&priv->gpu_damage);
@@ -2529,11 +2554,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
pixmap, priv->cpu_bo, 0, 0,
box, n, COPY_LAST);
}
- if (!ok)
+ if (!ok) {
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
sna_read_boxes(sna,
priv->gpu_bo, 0, 0,
pixmap, 0, 0,
box, n);
+ }
sna_damage_subtract(&priv->gpu_damage, r);
} else {
@@ -2555,11 +2582,13 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
pixmap, priv->cpu_bo, 0, 0,
box, n, COPY_LAST);
}
- if (!ok)
+ if (!ok) {
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
sna_read_boxes(sna,
priv->gpu_bo, 0, 0,
pixmap, 0, 0,
box, n);
+ }
sna_damage_subtract(&priv->gpu_damage, r);
RegionUninit(&need);
@@ -2617,6 +2646,7 @@ out:
assert(pixmap->devPrivate.ptr);
assert(pixmap->devKind);
assert_pixmap_damage(pixmap);
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
return true;
}
@@ -3380,6 +3410,7 @@ sna_pixmap_create_upload(ScreenPtr screen,
FreePixmap(pixmap);
return NullPixmap;
}
+ priv->mapped = true;
/* Marking both the shadow and the GPU bo is a little dubious,
* but will work so long as we always check before doing the
@@ -3881,6 +3912,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
assert(box->x2 - x <= w);
assert(box->y2 - y <= h);
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
memcpy_blt(bits, pixmap->devPrivate.ptr,
pixmap->drawable.bitsPerPixel,
stride, pixmap->devKind,
@@ -4922,6 +4954,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
assert(box[i].x2 + dx <= tmp->drawable.width);
assert(box[i].y2 + dy <= tmp->drawable.height);
+ assert(has_coherent_ptr(sna_pixmap(src_pixmap)));
+ assert(has_coherent_ptr(sna_pixmap(tmp)));
memcpy_blt(src_pixmap->devPrivate.ptr,
tmp->devPrivate.ptr,
src_pixmap->drawable.bitsPerPixel,
@@ -5093,7 +5127,8 @@ fallback:
assert(box->y1 + src_dy >= 0);
assert(box->x2 + src_dx <= src_pixmap->drawable.width);
assert(box->y2 + src_dy <= src_pixmap->drawable.height);
-
+ assert(has_coherent_ptr(sna_pixmap(src_pixmap)));
+ assert(has_coherent_ptr(sna_pixmap(dst_pixmap)));
memcpy_blt(src_bits, dst_bits, bpp,
src_stride, dst_stride,
box->x1, box->y1,
@@ -10092,6 +10127,7 @@ sna_pixmap_get_source_bo(PixmapPtr pixmap)
if (upload == NULL)
return NULL;
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
memcpy_blt(pixmap->devPrivate.ptr, ptr,
pixmap->drawable.bitsPerPixel,
pixmap->devKind, upload->pitch,
@@ -10443,6 +10479,7 @@ sna_poly_fill_rect_tiled_nxm_blt(DrawablePtr drawable,
assert(tile->drawable.height && tile->drawable.height <= 8);
assert(tile->drawable.width && tile->drawable.width <= 8);
+ assert(has_coherent_ptr(sna_pixmap(tile)));
cpp = tile->drawable.bitsPerPixel/8;
for (h = 0; h < tile->drawable.height; h++) {
@@ -13993,6 +14030,7 @@ sna_get_image(DrawablePtr drawable,
region.extents.x1, region.extents.y1,
region.extents.x2, region.extents.y2));
get_drawable_deltas(drawable, pixmap, &dx, &dy);
+ assert(has_coherent_ptr(sna_pixmap(pixmap)));
memcpy_blt(pixmap->devPrivate.ptr, dst, drawable->bitsPerPixel,
pixmap->devKind, PixmapBytePad(w, drawable->depth),
region.extents.x1 + dx,
@@ -14391,6 +14429,8 @@ fallback:
assert(box->x2 <= src->drawable.width);
assert(box->y2 <= src->drawable.height);
+ assert(has_coherent_ptr(sna_pixmap(src)));
+ assert(has_coherent_ptr(sna_pixmap(dst)));
memcpy_blt(src->devPrivate.ptr,
dst->devPrivate.ptr,
src->drawable.bitsPerPixel,
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 3febc273..1ec1a60f 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -74,6 +74,7 @@ static void read_boxes_inplace(struct kgem *kgem,
if (src == NULL)
return;
+ assert(src != dst);
do {
DBG(("%s: copying box (%d, %d), (%d, %d)\n",
__FUNCTION__, box->x1, box->y1, box->x2, box->y2));