summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-08 00:21:26 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-08 01:08:48 +0000
commit42eb9b7c4b55b620d9652ad3a54c8ab0a76fd7c2 (patch)
tree5710ab7851043b52ad445dbd99fed28f48c58e1d
parente52f0204939924181480feec6d1511259169c8f1 (diff)
sna: Trim usage of vmapping
The first, and likely only, goal is to support SHMPixmap efficiently (and without compromising SHMImage!) which we want to preserve as vmaps and never create a GPU bo. For all other use cases, we will want to create snoopable CPU bo ala the LLC buffers on SandyBridge. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c3
-rw-r--r--src/sna/sna.h29
-rw-r--r--src/sna/sna_accel.c27
-rw-r--r--src/sna/sna_blt.c4
-rw-r--r--src/sna/sna_render.c26
5 files changed, 34 insertions, 55 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 537cad9d..08d4db70 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2614,6 +2614,9 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
}
bo->reusable = false;
+ bo->vmap = true;
+ bo->sync = true;
+
DBG(("%s(ptr=%p, size=%d, read_only=%d) => handle=%d\n",
__FUNCTION__, ptr, size, read_only, handle));
return bo;
diff --git a/src/sna/sna.h b/src/sna/sna.h
index de4de5c8..6ae43102 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -578,35 +578,6 @@ static inline uint32_t pixmap_size(PixmapPtr pixmap)
pixmap->drawable.width * pixmap->drawable.bitsPerPixel/8;
}
-static inline struct kgem_bo *pixmap_vmap(struct kgem *kgem, PixmapPtr pixmap)
-{
- struct sna_pixmap *priv;
-
- if (!kgem->has_vmap)
- return NULL;
-
- if (unlikely(kgem->wedged))
- return NULL;
-
- priv = sna_pixmap_attach(pixmap);
- if (priv == NULL)
- return NULL;
-
- if (priv->cpu_bo == NULL) {
- priv->cpu_bo = kgem_create_map(kgem,
- pixmap->devPrivate.ptr,
- pixmap_size(pixmap),
- 0);
- if (priv->cpu_bo) {
- priv->cpu_bo->pitch = pixmap->devKind;
- if (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SCRATCH_HEADER)
- priv->cpu_bo->sync = true;
- }
- }
-
- return priv->cpu_bo;
-}
-
Bool sna_accel_pre_init(struct sna *sna);
Bool sna_accel_init(ScreenPtr sreen, struct sna *sna);
void sna_accel_block_handler(struct sna *sna);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index f7ed3cd0..4bd8f7a1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -436,10 +436,12 @@ struct sna_pixmap *_sna_pixmap_attach(PixmapPtr pixmap)
pixmap->usage_hint));
switch (pixmap->usage_hint) {
- case CREATE_PIXMAP_USAGE_GLYPH_PICTURE:
-#if FAKE_CREATE_PIXMAP_USAGE_SCRATCH_HEADER
case CREATE_PIXMAP_USAGE_SCRATCH_HEADER:
+#if !FAKE_CREATE_PIXMAP_USAGE_SCRATCH_HEADER
+ if (sna->kgem.has_vmap)
+ break;
#endif
+ case CREATE_PIXMAP_USAGE_GLYPH_PICTURE:
DBG(("%s: not attaching due to crazy usage: %d\n",
__FUNCTION__, pixmap->usage_hint));
return NULL;
@@ -468,6 +470,15 @@ struct sna_pixmap *_sna_pixmap_attach(PixmapPtr pixmap)
pixmap->drawable.width,
pixmap->drawable.height);
+ if (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SCRATCH_HEADER) {
+ priv->cpu_bo = kgem_create_map(&sna->kgem,
+ pixmap->devPrivate.ptr,
+ pixmap_size(pixmap),
+ 0);
+ if (priv->cpu_bo)
+ priv->cpu_bo->pitch = pixmap->devKind;
+ }
+
return priv;
}
@@ -1535,6 +1546,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
BoxPtr box;
int n;
+ assert(pixmap->usage_hint != CREATE_PIXMAP_USAGE_SCRATCH_HEADER);
+
DBG(("%s(pixmap=%ld, usage=%d)\n",
__FUNCTION__, pixmap->drawable.serialNumber, pixmap->usage_hint));
@@ -2429,9 +2442,13 @@ move_to_gpu(PixmapPtr pixmap, struct sna_pixmap *priv,
if (priv->gpu_bo)
return TRUE;
- if (priv->cpu_bo)
+ if (priv->cpu_bo) {
+ if (pixmap->usage_hint)
+ return FALSE;
+
return (priv->source_count++-SOURCE_BIAS) * w*h >=
(int)pixmap->drawable.width * pixmap->drawable.height;
+ }
if (alu != GXcopy)
return TRUE;
@@ -2689,7 +2706,9 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
&region);
RegionTranslate(&region, -dst_dx, -dst_dy);
}
- } else if (src_priv && src_priv->cpu_bo) {
+ } else if ((src_priv ||
+ (src_priv = _sna_pixmap_attach(src_pixmap))) &&
+ src_priv->cpu_bo) {
if (!sna->render.copy_boxes(sna, alu,
src_pixmap, src_priv->cpu_bo, src_dx, src_dy,
dst_pixmap, dst_priv->gpu_bo, dst_dx, dst_dy,
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 9f77f383..dfc4b434 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1350,7 +1350,7 @@ prepare_blt_put(struct sna *sna,
uint32_t alpha_fixup)
{
PixmapPtr src = op->u.blt.src_pixmap;
- struct sna_pixmap *priv = sna_pixmap(src);
+ struct sna_pixmap *priv = sna_pixmap_attach(src);
struct kgem_bo *src_bo = NULL;
struct kgem_bo *free_bo = NULL;
@@ -1358,8 +1358,6 @@ prepare_blt_put(struct sna *sna,
if (priv) {
src_bo = priv->cpu_bo;
- if (!src_bo)
- src_bo = pixmap_vmap(&sna->kgem, src);
} else {
src_bo = kgem_create_map(&sna->kgem,
src->devPrivate.ptr,
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 712e2454..96c43666 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -250,7 +250,7 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box)
{
struct sna_pixmap *priv;
- priv = sna_pixmap(pixmap);
+ priv = sna_pixmap_attach(pixmap);
if (priv == NULL || priv->cpu_bo == NULL) {
DBG(("%s: no cpu bo\n", __FUNCTION__));
return NULL;
@@ -526,24 +526,12 @@ sna_render_pixmap_bo(struct sna *sna,
pixmap->drawable.width, pixmap->drawable.height));
bo = use_cpu_bo(sna, pixmap, &box);
- if (bo == NULL && texture_is_cpu(pixmap, &box) && !move_to_gpu(pixmap, &box)) {
- /* If we are using transient data, it is better to copy
- * to an amalgamated upload buffer so that we don't
- * stall on releasing the cpu bo immediately upon
- * completion of the operation.
- */
- if (pixmap->usage_hint != CREATE_PIXMAP_USAGE_SCRATCH_HEADER &&
- w * pixmap->drawable.bitsPerPixel * h > 8*4096) {
- bo = pixmap_vmap(&sna->kgem, pixmap);
- if (bo)
- bo = kgem_bo_reference(bo);
- }
-
- if (bo == NULL) {
- DBG(("%s: uploading CPU box (%d, %d), (%d, %d)\n",
- __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
- bo = upload(sna, channel, pixmap, &box);
- }
+ if (bo == NULL &&
+ texture_is_cpu(pixmap, &box) &&
+ !move_to_gpu(pixmap, &box)) {
+ DBG(("%s: uploading CPU box (%d, %d), (%d, %d)\n",
+ __FUNCTION__, box.x1, box.y1, box.x2, box.y2));
+ bo = upload(sna, channel, pixmap, &box);
}
if (bo == NULL) {