xf86-video-intel: 2 commits - src/intel_dri.c src/intel_glamor.c src/intel.h src/intel_uxa.c src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_glyphs.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Sep 6 03:45:36 PDT 2012


 src/intel.h           |    5 +++-
 src/intel_dri.c       |    2 -
 src/intel_glamor.c    |    2 -
 src/intel_uxa.c       |    6 ++---
 src/sna/sna.h         |    9 +++++--
 src/sna/sna_accel.c   |   60 +++++++++++++++++++++++++++++++++++---------------
 src/sna/sna_display.c |    4 +--
 src/sna/sna_dri.c     |    4 +--
 src/sna/sna_glyphs.c  |    2 -
 9 files changed, 62 insertions(+), 32 deletions(-)

New commits:
commit 9bdf46d6c1a29b7b9e3d35e39a2e789334c0e1be
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 6 11:38:08 2012 +0100

    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 at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index b876061..44e7f6e 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 bb0bc14..678f687 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 59e128b..5d90653 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 e28ea4a..6329246 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 f7331a5..7a96fab 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,
commit 39c4be2b0be66ed83bf059d3007f4143325e340d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 6 11:28:49 2012 +0100

    uxa: Distinguish forms of pinning
    
    This allows us to replace the prime bo to meet sharing requirements, but
    still maintain the integrity with other users.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel.h b/src/intel.h
index 5b0c5df..48ec386 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -94,7 +94,10 @@ struct intel_pixmap {
 	int8_t busy :2;
 	uint8_t dirty :1;
 	uint8_t offscreen :1;
-	uint8_t pinned :1;
+	uint8_t pinned :3;
+#define PIN_SCANOUT 0x1
+#define PIN_DRI 0x2
+#define PIN_GLAMOR 0x4
 };
 
 #if HAS_DEVPRIVATEKEYREC
diff --git a/src/intel_dri.c b/src/intel_dri.c
index a1bac9a..8cab73f 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -90,7 +90,7 @@ static uint32_t pixmap_flink(PixmapPtr pixmap)
 	if (dri_bo_flink(priv->bo, &name) != 0)
 		return 0;
 
-	priv->pinned = 1;
+	priv->pinned |= PIN_DRI;
 	return name;
 }
 
diff --git a/src/intel_glamor.c b/src/intel_glamor.c
index 53043dd..55eb2de 100644
--- a/src/intel_glamor.c
+++ b/src/intel_glamor.c
@@ -128,7 +128,7 @@ intel_glamor_create_textured_pixmap(PixmapPtr pixmap)
 	if (glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle,
 					      priv->stride)) {
 		drm_intel_bo_disable_reuse(priv->bo);
-		priv->pinned = 1;
+		priv->pinned |= PIN_GLAMOR;
 		return TRUE;
 	} else
 		return FALSE;
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 2148102..6d202c7 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -1158,7 +1158,7 @@ Bool intel_uxa_create_screen_resources(ScreenPtr screen)
 
 	pixmap = screen->GetScreenPixmap(screen);
 	intel_set_pixmap_bo(pixmap, bo);
-	intel_get_pixmap_private(pixmap)->pinned = 1;
+	intel_get_pixmap_private(pixmap)->pinned |= PIN_SCANOUT;
 	screen->ModifyPixmapHeader(pixmap,
 				   scrn->virtualX,
 				   scrn->virtualY,
@@ -1191,7 +1191,7 @@ intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle
 	drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
 
 	if (tiling == I915_TILING_X) {
-		if (priv->pinned)
+		if (priv->pinned & ~PIN_DRI)
 			return FALSE;
 
 	        tiling = I915_TILING_NONE;
@@ -1215,7 +1215,7 @@ intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle
 	}
 	drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
 	drm_intel_bo_gem_export_to_prime(bo, &handle);
-	priv->pinned = 1;
+	priv->pinned |= PIN_DRI;
 
 	*fd_handle = (void *)(long)handle;
 	return TRUE;


More information about the xorg-commit mailing list