xf86-video-intel: 5 commits - src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Jul 26 07:14:24 PDT 2012


 src/sna/sna.h         |    1 
 src/sna/sna_accel.c   |   39 ++++++++++++++--------
 src/sna/sna_display.c |    2 -
 src/sna/sna_dri.c     |   88 +++++++++++++++++++++++++++++++++++++++++---------
 4 files changed, 101 insertions(+), 29 deletions(-)

New commits:
commit 8c0e3bbb0c301d0fa4652aa38edd84a9fd6b555e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 26 14:58:04 2012 +0100

    sna: Force the damage on the DRI pixmap to be flushed to the GPU
    
    Otherwise nothing will happen if we consider ourselves wedged.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index a517cc6..d1337cc 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2659,8 +2659,11 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 	BoxPtr box;
 	int n;
 
-	DBG(("%s(pixmap=%ld, usage=%d)\n",
-	     __FUNCTION__, pixmap->drawable.serialNumber, pixmap->usage_hint));
+	DBG(("%s(pixmap=%ld, usage=%d), flags=%x\n",
+	     __FUNCTION__,
+	     pixmap->drawable.serialNumber,
+	     pixmap->usage_hint,
+	     flags));
 
 	if ((flags & __MOVE_FORCE) == 0 && wedged(sna))
 		return NULL;
@@ -13278,7 +13281,8 @@ sna_accel_flush_callback(CallbackListPtr *list,
 		} else {
 			DBG(("%s: flushing DRI pixmap=%ld\n", __FUNCTION__,
 			     priv->pixmap->drawable.serialNumber));
-			ret = sna_pixmap_move_to_gpu(priv->pixmap, MOVE_READ);
+			ret = sna_pixmap_move_to_gpu(priv->pixmap,
+						     MOVE_READ | __MOVE_FORCE);
 		}
 		(void)ret;
 	}
commit f50d7b03b5d0b81b24f0acb4ae555545bbdaa179
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 26 14:47:44 2012 +0100

    sna: Only recommend not to create bo for a pixmap whilst wedged
    
    This allows us to continue to map a GPU bo and operate inplace if we are
    force to create a GPU bo for a compositor.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 16c0eed..a517cc6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -923,14 +923,6 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 	}
 	assert(width && height);
 
-	if (wedged(sna)) {
-		if (usage == SNA_CREATE_FB) {
-			flags = KGEM_CAN_CREATE_GPU;
-			goto force_create;
-		}
-		goto fallback;
-	}
-
 	flags = kgem_can_create_2d(&sna->kgem, width, height, depth);
 	if (flags == 0) {
 		DBG(("%s: can not use GPU, just creating shadow\n",
@@ -938,6 +930,9 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 		goto fallback;
 	}
 
+	if (wedged(sna))
+		flags = 0;
+
 	if (usage == CREATE_PIXMAP_USAGE_SCRATCH) {
 		if (flags & KGEM_CAN_CREATE_GPU)
 			return sna_pixmap_create_scratch(screen,
commit 49403ddd1bd9a23e1b32a10e7d0757ae2897a579
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 26 14:44:14 2012 +0100

    sna/dri: Mark a flush required for any new DRI already on exec/dirty lists
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 062ccfe..16c0eed 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1153,8 +1153,10 @@ static inline bool operate_inplace(struct sna_pixmap *priv, unsigned flags)
 
 static inline void add_flush_pixmap(struct sna *sna, struct sna_pixmap *priv)
 {
+	DBG(("%s: marking pixmap=%ld for flushing\n",
+	     __FUNCTION__, priv->pixmap->drawable.serialNumber));
 	list_move(&priv->list, &sna->flush_pixmaps);
-	sna->kgem.flush |= 1;
+	sna->kgem.flush = true;
 }
 
 bool
@@ -13261,6 +13263,7 @@ sna_accel_flush_callback(CallbackListPtr *list,
 	 * by checking for outgoing damage events or sync replies. Tricky,
 	 * and doesn't appear to mitigate the performance loss.
 	 */
+	DBG(("%s: flush?=%d\n", __FUNCTION__, sna->kgem.flush));
 	if (!sna->kgem.flush)
 		return;
 
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 1812267..6a4a454 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -189,6 +189,13 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 	/* Don't allow this named buffer to be replaced */
 	priv->pinned = 1;
 
+	if (priv->gpu_bo->exec || priv->cpu_damage) {
+		DBG(("%s: marking pixmap=%ld for flushing\n",
+		     __FUNCTION__, pixmap->drawable.serialNumber));
+		list_move(&priv->list, &sna->flush_pixmaps);
+		sna->kgem.flush = true;
+	}
+
 	return priv->gpu_bo;
 }
 
commit efe3c8ff48738f2a274e1d4514d32499fc4aadbc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 26 14:43:33 2012 +0100

    sna: Allow DRI to force allocation of a GPU bo and backing pixmap
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 51a8206..0db6861 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -425,6 +425,7 @@ void sna_pixmap_destroy(PixmapPtr pixmap);
 #define MOVE_SOURCE_HINT 0x10
 #define MOVE_WHOLE_HINT 0x20
 #define __MOVE_FORCE 0x40
+#define __MOVE_DRI 0x80
 
 struct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags);
 static inline struct sna_pixmap *
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 4d30c5c..062ccfe 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2671,7 +2671,18 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 	priv = sna_pixmap(pixmap);
 	if (priv == NULL) {
 		DBG(("%s: not attached\n", __FUNCTION__));
-		return NULL;
+		if ((flags & __MOVE_DRI) == 0)
+			return NULL;
+
+		DBG(("%s: forcing the creation on the GPU\n", __FUNCTION__));
+
+		priv = sna_pixmap_attach(pixmap);
+		if (priv == NULL)
+			return NULL;
+
+		sna_damage_all(&priv->cpu_damage,
+			       pixmap->drawable.width,
+			       pixmap->drawable.height);
 	}
 
 	if (sna_damage_is_all(&priv->gpu_damage,
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index bdd1f22..1812267 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -154,13 +154,21 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 	struct sna_pixmap *priv;
 	int tiling;
 
+	DBG(("%s: attaching DRI client to pixmap=%ld\n",
+	     __FUNCTION__, pixmap->drawable.serialNumber));
+
 	priv = sna_pixmap(pixmap);
-	if (priv == NULL || priv->shm)
+	if (priv != NULL && priv->shm) {
+		DBG(("%s: SHM Pixmap, BadAlloc\n", __FUNCTION__));
 		return NULL;
+	}
 
-	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
-	if (priv == NULL)
+	priv = sna_pixmap_move_to_gpu(pixmap,
+				      MOVE_READ | MOVE_WRITE | __MOVE_FORCE | __MOVE_DRI);
+	if (priv == NULL) {
+		DBG(("%s: failed to move to GPU, BadAlloc\n", __FUNCTION__));
 		return NULL;
+	}
 
 	if (priv->flush++)
 		return priv->gpu_bo;
commit 2069384f9f06d3ef9dbb0c3f2c64cac4b24e10fc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 26 14:15:45 2012 +0100

    sna/dri: Implement fallback handling for CopyRegion whilst wedged
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index a908596..37a5e9f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2419,7 +2419,7 @@ sna_covering_crtc(ScrnInfoPtr scrn,
 	int best_coverage, c;
 
 	/* If we do not own the VT, we do not own the CRTC either */
-	if (!scrn->vtSema)
+	if (!scrn->vtSema || wedged(to_sna(scrn)))
 		return NULL;
 
 	DBG(("%s for box=(%d, %d), (%d, %d)\n",
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 9698247..bdd1f22 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -477,6 +477,28 @@ static void sna_dri_select_mode(struct sna *sna, struct kgem_bo *src, bool sync)
 	_kgem_set_mode(&sna->kgem, mode);
 }
 
+static void
+sna_dri_copy_fallback(struct sna *sna, int bpp,
+		      struct kgem_bo *src_bo, int sx, int sy,
+		      struct kgem_bo *dst_bo, int dx, int dy,
+		      const BoxRec *box, int n)
+{
+	void *dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
+	void *src = kgem_bo_map__gtt(&sna->kgem, src_bo);
+
+	DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
+	     __FUNCTION__, sx, sy, dx, dy, n));
+
+	do {
+		memcpy_blt(src, dst, bpp,
+			   src_bo->pitch, dst_bo->pitch,
+			   box->x1 + sx, box->y1 + sy,
+			   box->x1 + dx, box->y1 + dy,
+			   box->x2 - box->x1, box->y2 - box->y1);
+		box++;
+	} while (--n);
+}
+
 static struct kgem_bo *
 sna_dri_copy_to_front(struct sna *sna, DrawablePtr draw, RegionPtr region,
 		      struct kgem_bo *dst_bo, struct kgem_bo *src_bo,
@@ -553,10 +575,17 @@ sna_dri_copy_to_front(struct sna *sna, DrawablePtr draw, RegionPtr region,
 		boxes = &clip.extents;
 		n = 1;
 	}
-	sna->render.copy_boxes(sna, GXcopy,
-			       (PixmapPtr)draw, src_bo, -draw->x, -draw->y,
-			       pixmap, dst_bo, dx, dy,
-			       boxes, n, COPY_LAST);
+	if (wedged(sna)) {
+		sna_dri_copy_fallback(sna, draw->bitsPerPixel,
+				      src_bo, -draw->x, -draw->y,
+				      dst_bo, dx, dy,
+				      boxes, n);
+	} else {
+		sna->render.copy_boxes(sna, GXcopy,
+				       (PixmapPtr)draw, src_bo, -draw->x, -draw->y,
+				       pixmap, dst_bo, dx, dy,
+				       boxes, n, COPY_LAST);
+	}
 
 	DBG(("%s: flushing? %d\n", __FUNCTION__, flush));
 	if (flush) { /* STAT! */
@@ -638,10 +667,17 @@ sna_dri_copy_from_front(struct sna *sna, DrawablePtr draw, RegionPtr region,
 		boxes = &box;
 		n = 1;
 	}
-	sna->render.copy_boxes(sna, GXcopy,
-			       pixmap, src_bo, dx, dy,
-			       (PixmapPtr)draw, dst_bo, -draw->x, -draw->y,
-			       boxes, n, COPY_LAST);
+	if (wedged(sna)) {
+		sna_dri_copy_fallback(sna, draw->bitsPerPixel,
+				      src_bo, dx, dy,
+				      dst_bo, -draw->x, -draw->y,
+				      boxes, n);
+	} else {
+		sna->render.copy_boxes(sna, GXcopy,
+				       pixmap, src_bo, dx, dy,
+				       (PixmapPtr)draw, dst_bo, -draw->x, -draw->y,
+				       boxes, n, COPY_LAST);
+	}
 
 	if (region == &clip)
 		pixman_region_fini(&clip);
@@ -681,10 +717,17 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
 
 	sna_dri_select_mode(sna, src_bo, false);
 
-	sna->render.copy_boxes(sna, GXcopy,
-			       (PixmapPtr)draw, src_bo, 0, 0,
-			       (PixmapPtr)draw, dst_bo, 0, 0,
-			       boxes, n, COPY_LAST);
+	if (wedged(sna)) {
+		sna_dri_copy_fallback(sna, draw->bitsPerPixel,
+				      src_bo, 0, 0,
+				      dst_bo, 0, 0,
+				      boxes, n);
+	} else {
+		sna->render.copy_boxes(sna, GXcopy,
+				       (PixmapPtr)draw, src_bo, 0, 0,
+				       (PixmapPtr)draw, dst_bo, 0, 0,
+				       boxes, n, COPY_LAST);
+	}
 
 	if (region == &clip)
 		pixman_region_fini(&clip);


More information about the xorg-commit mailing list