summaryrefslogtreecommitdiff
path: root/src/sna
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-09-06 11:38:08 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-09-06 11:43:48 +0100
commit9bdf46d6c1a29b7b9e3d35e39a2e789334c0e1be (patch)
tree9acecde0baef2d52b5639604194fde0e1b6e041b /src/sna
parent39c4be2b0be66ed83bf059d3007f4143325e340d (diff)
sna/prime: Distinguish forms of pinned pixmap
So that we can allow prime to replace the backing bo of currently exported pixmaps through DRI2. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r--src/sna/sna.h9
-rw-r--r--src/sna/sna_accel.c60
-rw-r--r--src/sna/sna_display.c4
-rw-r--r--src/sna/sna_dri.c4
-rw-r--r--src/sna/sna_glyphs.c2
5 files changed, 53 insertions, 26 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index b8760616..44e7f6e4 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -123,7 +123,10 @@ struct sna_pixmap {
#define SOURCE_BIAS 4
uint16_t source_count;
- uint8_t pinned :1;
+ uint8_t pinned :3;
+#define PIN_SCANOUT 0x1
+#define PIN_DRI 0x2
+#define PIN_PRIME 0x4
uint8_t mapped :1;
uint8_t shm :1;
uint8_t clear :1;
@@ -542,7 +545,7 @@ static inline struct kgem_bo *sna_pixmap_get_bo(PixmapPtr pixmap)
return sna_pixmap(pixmap)->gpu_bo;
}
-static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap)
+static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags)
{
struct sna_pixmap *priv;
@@ -550,7 +553,7 @@ static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap)
if (!priv)
return NULL;
- priv->pinned = 1;
+ priv->pinned |= flags;
return priv->gpu_bo;
}
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index bb0bc147..678f687d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -937,39 +937,63 @@ sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle)
if (priv == NULL)
return FALSE;
+ assert(!priv->shm);
assert(priv->gpu_bo);
assert(priv->stride);
/* XXX negotiate format and stride restrictions */
- if (priv->gpu_bo->tiling &&
- !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) {
- DBG(("%s: failed to change tiling for export\n", __FUNCTION__));
- return FALSE;
- }
-
- /* nvidia requires a minimum pitch alignment of 256 */
- if (priv->gpu_bo->pitch & 255) {
+ if (priv->gpu_bo->tiling != I915_TILING_NONE ||
+ priv->gpu_bo->pitch & 255) {
struct kgem_bo *bo;
+ BoxRec box;
- if (priv->pinned) {
- DBG(("%s: failed to change pitch for export, pinned!\n", __FUNCTION__));
+ DBG(("%s: removing tiling %d, and aligning pitch for %dx%d pixmap=%ld\n",
+ __FUNCTION__, priv->gpu_bo->tiling,
+ pixmap->drawable.width, pixmap->drawable.height,
+ pixmap->drawable.serialNumber));
+
+ if (priv->pinned & ~(PIN_DRI | PIN_PRIME)) {
+ DBG(("%s: can't convert pinned bo\n", __FUNCTION__));
return FALSE;
}
- bo = kgem_replace_bo(&sna->kgem, priv->gpu_bo,
- pixmap->drawable.width,
- pixmap->drawable.height,
- ALIGN(priv->gpu_bo->pitch, 256),
- pixmap->drawable.bitsPerPixel);
+ assert_pixmap_damage(pixmap);
+
+ bo = kgem_create_2d(&sna->kgem,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->drawable.bitsPerPixel,
+ I915_TILING_NONE,
+ CREATE_GTT_MAP | CREATE_PRIME);
if (bo == NULL) {
- DBG(("%s: failed to change pitch for export\n", __FUNCTION__));
+ DBG(("%s: allocation failed\n", __FUNCTION__));
+ return FALSE;
+ }
+
+ box.x1 = box.y1 = 0;
+ box.x2 = pixmap->drawable.width;
+ box.y2 = pixmap->drawable.height;
+
+ assert(!wedged(sna)); /* XXX */
+ if (!sna->render.copy_boxes(sna, GXcopy,
+ pixmap, priv->gpu_bo, 0, 0,
+ pixmap, bo, 0, 0,
+ &box, 1, 0)) {
+ DBG(("%s: copy failed\n", __FUNCTION__));
+ kgem_bo_destroy(&sna->kgem, bo);
return FALSE;
}
kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
priv->gpu_bo = bo;
+
+ if (priv->mapped) {
+ pixmap->devPrivate.ptr = NULL;
+ priv->mapped = false;
+ }
}
assert(priv->gpu_bo->tiling == I915_TILING_NONE);
+ assert((priv->gpu_bo->pitch & 255) == 0);
/* And export the bo->pitch via pixmap->devKind */
pixmap->devPrivate.ptr = kgem_bo_map__async(&sna->kgem, priv->gpu_bo);
@@ -983,7 +1007,7 @@ sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle)
if (fd == -1)
return FALSE;
- priv->pinned = true;
+ priv->pinned |= PIN_PRIME;
*fd_handle = (void *)(intptr_t)fd;
return TRUE;
@@ -1022,7 +1046,7 @@ sna_set_shared_pixmap_backing(PixmapPtr pixmap, void *fd_handle)
priv->stride = pixmap->devKind;
priv->gpu_bo = bo;
- priv->pinned = true;
+ priv->pinned |= PIN_DRI;
close((intptr_t)fd_handle);
return TRUE;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 59e128bc..5d906539 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -967,7 +967,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
if (!sna_crtc_enable_shadow(sna, sna_crtc))
return NULL;
- bo = sna_pixmap_pin(sna_crtc->scanout_pixmap);
+ bo = sna_pixmap_pin(sna_crtc->scanout_pixmap, PIN_SCANOUT);
if (bo == NULL)
return NULL;
@@ -1009,7 +1009,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
} else {
DBG(("%s: attaching to framebuffer\n", __FUNCTION__));
sna_crtc_disable_shadow(sna, sna_crtc);
- bo = sna_pixmap_pin(sna->front);
+ bo = sna_pixmap_pin(sna->front, PIN_SCANOUT);
if (bo == NULL)
return NULL;
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index e28ea4a5..63292469 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -188,7 +188,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
sna_accel_watch_flush(sna, 1);
/* Don't allow this named buffer to be replaced */
- priv->pinned = 1;
+ priv->pinned |= PIN_DRI;
return priv->gpu_bo;
}
@@ -368,7 +368,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
pixmap == sna->front));
list_del(&priv->list);
sna_accel_watch_flush(sna, -1);
- priv->pinned = pixmap == sna->front;
+ priv->pinned &= ~PIN_DRI;
}
sna_pixmap_set_buffer(pixmap, NULL);
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index f7331a57..7a96fab8 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -219,7 +219,7 @@ bool sna_glyphs_create(struct sna *sna)
priv = sna_pixmap(pixmap);
if (priv != NULL) {
/* Prevent the cache from ever being paged out */
- priv->pinned = true;
+ priv->pinned = PIN_SCANOUT;
component_alpha = NeedsComponent(pPictFormat->format);
picture = CreatePicture(0, &pixmap->drawable, pPictFormat,