xf86-video-intel: 5 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_render.c

Chris Wilson ickle at kemper.freedesktop.org
Sun May 6 06:25:19 PDT 2012


 src/sna/gen2_render.c |    8 +-
 src/sna/gen3_render.c |    8 +-
 src/sna/gen4_render.c |    8 +-
 src/sna/gen5_render.c |    8 +-
 src/sna/gen6_render.c |    8 +-
 src/sna/gen7_render.c |    8 +-
 src/sna/kgem.c        |   32 +++++++----
 src/sna/kgem.h        |    2 
 src/sna/sna.h         |    7 +-
 src/sna/sna_display.c |  141 ++++++++++++++++++++------------------------------
 src/sna/sna_dri.c     |   87 +++++++++++++++---------------
 src/sna/sna_driver.c  |    3 -
 src/sna/sna_render.c  |    2 
 13 files changed, 151 insertions(+), 171 deletions(-)

New commits:
commit c5b6741d3729c6867702ab64a6c59cb8052c0ef3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun May 6 12:40:54 2012 +0100

    sna/gen2+: Fix typo for computing redirected extents for render copy
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 0ad346e..9717aac 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -2909,14 +2909,14 @@ fallback:
 		int i;
 
 		for (i = 1; i < n; i++) {
-			if (extents.x1 < box[i].x1)
+			if (box[i].x1 < extents.x1)
 				extents.x1 = box[i].x1;
-			if (extents.y1 < box[i].y1)
+			if (box[i].y1 < extents.y1)
 				extents.y1 = box[i].y1;
 
-			if (extents.x2 > box[i].x2)
+			if (box[i].x2 > extents.x2)
 				extents.x2 = box[i].x2;
-			if (extents.y2 > box[i].y2)
+			if (box[i].y2 > extents.y2)
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 680d36f..e73c707 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -4069,14 +4069,14 @@ fallback_blt:
 		int i;
 
 		for (i = 1; i < n; i++) {
-			if (extents.x1 < box[i].x1)
+			if (box[i].x1 < extents.x1)
 				extents.x1 = box[i].x1;
-			if (extents.y1 < box[i].y1)
+			if (box[i].y1 < extents.y1)
 				extents.y1 = box[i].y1;
 
-			if (extents.x2 > box[i].x2)
+			if (box[i].x2 > extents.x2)
 				extents.x2 = box[i].x2;
-			if (extents.y2 > box[i].y2)
+			if (box[i].y2 > extents.y2)
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index b8a2459..9cad75e 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2655,14 +2655,14 @@ fallback_blt:
 		int i;
 
 		for (i = 1; i < n; i++) {
-			if (extents.x1 < box[i].x1)
+			if (box[i].x1 < extents.x1)
 				extents.x1 = box[i].x1;
-			if (extents.y1 < box[i].y1)
+			if (box[i].y1 < extents.y1)
 				extents.y1 = box[i].y1;
 
-			if (extents.x2 > box[i].x2)
+			if (box[i].x2 > extents.x2)
 				extents.x2 = box[i].x2;
-			if (extents.y2 > box[i].y2)
+			if (box[i].y2 > extents.y2)
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 1fb7f65..54d0b22 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2962,14 +2962,14 @@ fallback_blt:
 		int i;
 
 		for (i = 1; i < n; i++) {
-			if (extents.x1 < box[i].x1)
+			if (box[i].x1 < extents.x1)
 				extents.x1 = box[i].x1;
-			if (extents.y1 < box[i].y1)
+			if (box[i].y1 < extents.y1)
 				extents.y1 = box[i].y1;
 
-			if (extents.x2 > box[i].x2)
+			if (box[i].x2 > extents.x2)
 				extents.x2 = box[i].x2;
-			if (extents.y2 > box[i].y2)
+			if (box[i].y2 > extents.y2)
 				extents.y2 = box[i].y2;
 		}
 
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 38fb024..55673bf 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -3339,14 +3339,14 @@ fallback_blt:
 		int i;
 
 		for (i = 1; i < n; i++) {
-			if (extents.x1 < box[i].x1)
+			if (box[i].x1 < extents.x1)
 				extents.x1 = box[i].x1;
-			if (extents.y1 < box[i].y1)
+			if (box[i].y1 < extents.y1)
 				extents.y1 = box[i].y1;
 
-			if (extents.x2 > box[i].x2)
+			if (box[i].x2 > extents.x2)
 				extents.x2 = box[i].x2;
-			if (extents.y2 > box[i].y2)
+			if (box[i].y2 > extents.y2)
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 6c9a833..e128f5c 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -3422,14 +3422,14 @@ fallback_blt:
 		int i;
 
 		for (i = 1; i < n; i++) {
-			if (extents.x1 < box[i].x1)
+			if (box[i].x1 < extents.x1)
 				extents.x1 = box[i].x1;
-			if (extents.y1 < box[i].y1)
+			if (box[i].y1 < extents.y1)
 				extents.y1 = box[i].y1;
 
-			if (extents.x2 > box[i].x2)
+			if (box[i].x2 > extents.x2)
 				extents.x2 = box[i].x2;
-			if (extents.y2 > box[i].y2)
+			if (box[i].y2 > extents.y2)
 				extents.y2 = box[i].y2;
 		}
 		if (!sna_render_composite_redirect(sna, &tmp,
commit 771090f25db702d25ebbd3f2b44429cf0acfe8fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 4 20:56:37 2012 +0100

    sna: Add a pair of asserts to track down a NULL pointer dereference
    
    Looks like the assumption for the location of the data is invalid,
    allocation failure, perhaps?
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=47597
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index dee6608..880e173 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -460,6 +460,8 @@ static struct kgem_bo *upload(struct sna *sna,
 			priv->mapped = false;
 		}
 		if (pixmap->devPrivate.ptr == NULL) {
+			assert(priv->ptr);
+			assert(priv->stride);
 			pixmap->devPrivate.ptr = priv->ptr;
 			pixmap->devKind = priv->stride;
 		}
commit d376a960df7a081a5d449f77b81ae13223b98929
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 4 10:09:46 2012 +0100

    sna/dri: Only track a single pending flip across all pipes
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index e07a115..3e4b8ec 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -249,7 +249,7 @@ struct sna {
 	} mode;
 
 	struct sna_dri {
-		void *flip_pending[2];
+		void *flip_pending;
 	} dri;
 
 	unsigned int tiling;
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 32602d5..2b97e68 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -937,6 +937,9 @@ can_flip(struct sna * sna,
 	WindowPtr win = (WindowPtr)draw;
 	PixmapPtr pixmap;
 
+	if (!sna->scrn->vtSema)
+		return FALSE;
+
 	if (draw->type == DRAWABLE_PIXMAP)
 		return FALSE;
 
@@ -1109,7 +1112,7 @@ sna_dri_flip_continue(struct sna *sna,
 
 	info->next_front.name = 0;
 
-	sna->dri.flip_pending[info->pipe] = info;
+	sna->dri.flip_pending = info;
 
 	return TRUE;
 }
@@ -1171,8 +1174,8 @@ static void sna_dri_flip_event(struct sna *sna,
 		break;
 
 	case DRI2_FLIP_THROTTLE:
-		assert(sna->dri.flip_pending[flip->pipe] == flip);
-		sna->dri.flip_pending[flip->pipe] = NULL;
+		assert(sna->dri.flip_pending == flip);
+		sna->dri.flip_pending = NULL;
 
 		if (flip->next_front.name &&
 		    flip->drawable_id &&
@@ -1204,9 +1207,9 @@ static void sna_dri_flip_event(struct sna *sna,
 	case DRI2_ASYNC_FLIP:
 		DBG(("%s: async swap flip completed on pipe %d, pending? %d, new? %d\n",
 		     __FUNCTION__, flip->pipe,
-		     sna->dri.flip_pending[flip->pipe] != NULL,
+		     sna->dri.flip_pending != NULL,
 		     flip->front->name != flip->old_front.name));
-		assert(sna->dri.flip_pending[flip->pipe] == flip);
+		assert(sna->dri.flip_pending == flip);
 
 		if (flip->front->name != flip->next_front.name) {
 			DBG(("%s: async flip continuing\n", __FUNCTION__));
@@ -1240,7 +1243,7 @@ finish_async_flip:
 			flip->next_front.bo = NULL;
 
 			DBG(("%s: async flip completed\n", __FUNCTION__));
-			sna->dri.flip_pending[flip->pipe] = NULL;
+			sna->dri.flip_pending = NULL;
 			sna_dri_frame_event_info_free(flip);
 		}
 		break;
@@ -1326,9 +1329,9 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 		int type = DRI2_FLIP_THROTTLE;
 
 		DBG(("%s: performing immediate swap on pipe %d, pending? %d\n",
-		     __FUNCTION__, pipe, sna->dri.flip_pending[pipe] != NULL));
+		     __FUNCTION__, pipe, sna->dri.flip_pending != NULL));
 
-		info = sna->dri.flip_pending[pipe];
+		info = sna->dri.flip_pending;
 		if (info) {
 			if (info->drawable_id == draw->id) {
 				DBG(("%s: chaining flip\n", __FUNCTION__));
@@ -1382,7 +1385,7 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 				       CREATE_EXACT);
 		info->back->name = kgem_bo_flink(&sna->kgem,
 						 get_private(info->back)->bo);
-		sna->dri.flip_pending[info->pipe] = info;
+		sna->dri.flip_pending = info;
 
 		DRI2SwapComplete(info->client, draw, 0, 0, 0,
 				 DRI2_EXCHANGE_COMPLETE,
@@ -1697,16 +1700,17 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
 	struct sna *sna = to_sna_from_drawable(draw);
 	struct sna_dri_frame_event *info;
 	struct kgem_bo *bo;
-	int name, pipe;
+	int name;
 
 	DBG(("%s()\n", __FUNCTION__));
 
-	pipe = sna_dri_get_pipe(draw);
-	if (pipe == -1) {
-		PixmapPtr pixmap = get_drawable_pixmap(draw);
+	if (!sna->scrn->vtSema) {
+		PixmapPtr pixmap;
 
+exchange:
 		DBG(("%s: unattached, exchange pixmaps\n", __FUNCTION__));
 
+		pixmap = get_drawable_pixmap(draw);
 		set_bo(pixmap, get_private(back)->bo);
 		sna_dri_exchange_attachment(front, back);
 		get_private(back)->pixmap = pixmap;
@@ -1733,10 +1737,14 @@ blit:
 	bo = NULL;
 	name = 0;
 
-	info = sna->dri.flip_pending[pipe];
+	info = sna->dri.flip_pending;
 	if (info == NULL) {
-		DBG(("%s: no pending flip on pipe %d, so updating scanout\n",
-		     __FUNCTION__, pipe));
+		int pipe = sna_dri_get_pipe(draw);
+		if (pipe == -1)
+			goto exchange;
+
+		DBG(("%s: no pending flip, so updating scanout\n",
+		     __FUNCTION__));
 
 		info = calloc(1, sizeof(struct sna_dri_frame_event));
 		if (!info)
@@ -1801,7 +1809,7 @@ blit:
 	info->back->name = name;
 
 	set_bo(sna->front, get_private(info->front)->bo);
-	sna->dri.flip_pending[info->pipe] = info;
+	sna->dri.flip_pending = info;
 
 	DRI2SwapComplete(client, draw, 0, 0, 0,
 			 DRI2_EXCHANGE_COMPLETE, func, data);
commit 450592f989efd0d3bc9ef2de245fce0a180e91a2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 4 09:50:19 2012 +0100

    sna: Cache the framebuffer id
    
    Also fixup a weakness of only tracking scanout with a single bit, as we
    used to clear it forcibly after every flip.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 666a23f..6e0c3d0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1088,6 +1088,25 @@ inline static void kgem_bo_remove_from_active(struct kgem *kgem,
 	assert(list_is_empty(&bo->vma));
 }
 
+static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
+{
+	if (!bo->scanout)
+		return;
+
+	assert(bo->proxy == NULL);
+
+	DBG(("%s: handle=%d, fb=%d\n", __FUNCTION__, bo->handle, bo->delta));
+	if (bo->delta) {
+		drmModeRmFB(kgem->fd, bo->delta);
+		bo->delta = 0;
+	}
+
+	bo->scanout = false;
+	bo->needs_flush = true;
+	bo->flush = false;
+	bo->reusable = true;
+}
+
 static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 {
 	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
@@ -1096,6 +1115,7 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	assert(bo->refcnt == 0);
 
 	bo->binding.offset = 0;
+	kgem_bo_clear_scanout(kgem, bo);
 
 	if (NO_CACHE)
 		goto destroy;
@@ -4151,18 +4171,6 @@ void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
 	}
 }
 
-void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
-{
-	bo->needs_flush = true;
-	bo->flush = false;
-
-	if (!bo->scanout)
-		return;
-
-	bo->scanout = false;
-	bo->reusable = true;
-}
-
 struct kgem_bo *
 kgem_replace_bo(struct kgem *kgem,
 		struct kgem_bo *src,
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 9eac68e..186eaa0 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -509,8 +509,6 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
 bool kgem_buffer_is_inplace(struct kgem_bo *bo);
 void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo);
 
-void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo);
-
 void kgem_throttle(struct kgem *kgem);
 #define MAX_INACTIVE_TIME 10
 bool kgem_expire_cache(struct kgem *kgem);
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 5272a08..e07a115 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -318,8 +318,6 @@ extern int sna_page_flip(struct sna *sna,
 
 extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap);
 
-void sna_mode_delete_fb(struct sna *sna, uint32_t fb);
-
 constant static inline struct sna *
 to_sna(ScrnInfoPtr scrn)
 {
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5275d4a..6287cd9 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -151,6 +151,40 @@ int sna_crtc_to_plane(xf86CrtcPtr crtc)
 	return sna_crtc->plane;
 }
 
+static unsigned get_fb(struct sna *sna, struct kgem_bo *bo,
+		       int width, int height)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+	int ret;
+
+	assert(bo->proxy == NULL);
+	if (bo->delta) {
+		DBG(("%s: reusing fb=%d for handle=%d\n",
+		     __FUNCTION__, bo->delta, bo->handle));
+		return bo->delta;
+	}
+
+	DBG(("%s: create fb %dx%d@%d/%d\n",
+	     __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
+
+	assert(bo->tiling != I915_TILING_Y);
+	ret = drmModeAddFB(sna->kgem.fd,
+			   width, height,
+			   scrn->depth, scrn->bitsPerPixel,
+			   bo->pitch, bo->handle,
+			   &bo->delta);
+	if (ret < 0) {
+		ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
+		       __FUNCTION__,
+		       width, height,
+		       scrn->depth, scrn->bitsPerPixel, bo->pitch);
+		return 0;
+	}
+
+	bo->scanout = true;
+	return bo->delta;
+}
+
 static uint32_t gem_create(int fd, int size)
 {
 	struct drm_i915_gem_create create;
@@ -434,10 +468,6 @@ sna_crtc_restore(struct sna *sna)
 	if (!bo)
 		return;
 
-	assert(bo->tiling != I915_TILING_Y);
-	bo->scanout = true;
-	bo->domain = DOMAIN_NONE;
-
 	DBG(("%s: create fb %dx%d@%d/%d\n",
 	     __FUNCTION__,
 	     sna->front->drawable.width,
@@ -446,13 +476,10 @@ sna_crtc_restore(struct sna *sna)
 	     sna->front->drawable.bitsPerPixel));
 
 	sna_mode_remove_fb(sna);
-	if (drmModeAddFB(sna->kgem.fd,
-			 sna->front->drawable.width,
-			 sna->front->drawable.height,
-			 sna->front->drawable.depth,
-			 sna->front->drawable.bitsPerPixel,
-			 bo->pitch, bo->handle,
-			 &sna->mode.fb_id))
+	sna->mode.fb_id = get_fb(sna, bo,
+				 sna->front->drawable.width,
+				 sna->front->drawable.height);
+	if (sna->mode.fb_id == 0)
 		return;
 
 	DBG(("%s: handle %d attached to fb %d\n",
@@ -468,6 +495,7 @@ sna_crtc_restore(struct sna *sna)
 			return;
 	}
 
+	bo->domain = DOMAIN_NONE;
 	scrn->displayWidth = bo->pitch / sna->mode.cpp;
 	sna->mode.fb_pixmap = sna->front->drawable.serialNumber;
 }
@@ -652,28 +680,16 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		if (!bo)
 			return FALSE;
 
-		DBG(("%s: create fb %dx%d@%d/%d\n",
-		     __FUNCTION__,
-		     scrn->virtualX, scrn->virtualY,
-		     scrn->depth, scrn->bitsPerPixel));
-
-		assert(bo->tiling != I915_TILING_Y);
-		ret = drmModeAddFB(sna->kgem.fd,
-				   scrn->virtualX, scrn->virtualY,
-				   scrn->depth, scrn->bitsPerPixel,
-				   bo->pitch, bo->handle,
-				   &sna_mode->fb_id);
-		if (ret < 0) {
-			ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
-			       __FUNCTION__,
-			       scrn->virtualX, scrn->virtualY,
-			       scrn->depth, scrn->bitsPerPixel, bo->pitch);
+		/* recreate the fb in case the size has changed */
+		assert(bo->delta == 0);
+		sna_mode->fb_id = get_fb(sna, bo,
+					 scrn->virtualX, scrn->virtualY);
+		if (sna_mode->fb_id == 0)
 			return FALSE;
-		}
 
 		DBG(("%s: handle %d attached to fb %d\n",
 		     __FUNCTION__, bo->handle, sna_mode->fb_id));
-		bo->scanout = true;
+
 		bo->domain = DOMAIN_NONE;
 		sna_mode->fb_pixmap = sna->front->drawable.serialNumber;
 	}
@@ -773,22 +789,14 @@ sna_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 		return NULL;
 	}
 
-	assert(bo->tiling != I915_TILING_Y);
-	if (drmModeAddFB(sna->kgem.fd,
-			 width, height, scrn->depth, scrn->bitsPerPixel,
-			 bo->pitch, bo->handle,
-			 &sna_crtc->shadow_fb_id)) {
-		ErrorF("%s: failed to add rotate  fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
-		       __FUNCTION__,
-		       width, height,
-		       scrn->depth, scrn->bitsPerPixel, bo->pitch);
+	sna_crtc->shadow_fb_id = get_fb(sna, bo, width, height);
+	if (sna_crtc->shadow_fb_id == 0) {
 		scrn->pScreen->DestroyPixmap(shadow);
 		return NULL;
 	}
 
 	DBG(("%s: attached handle %d to fb %d\n",
 	     __FUNCTION__, bo->handle, sna_crtc->shadow_fb_id));
-	bo->scanout = true;
 	bo->domain = DOMAIN_NONE;
 	return sna_crtc->shadow = shadow;
 }
@@ -813,10 +821,8 @@ sna_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr pixmap, void *data)
 	DBG(("%s(fb=%d, handle=%d)\n", __FUNCTION__,
 	     sna_crtc->shadow_fb_id, sna_pixmap_get_bo(pixmap)->handle));
 
-	drmModeRmFB(sna->kgem.fd, sna_crtc->shadow_fb_id);
 	sna_crtc->shadow_fb_id = 0;
 
-	kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(pixmap));
 	pixmap->drawable.pScreen->DestroyPixmap(pixmap);
 	sna_crtc->shadow = NULL;
 }
@@ -1702,23 +1708,16 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
 	if (!bo)
 		goto fail;
 
-	assert(bo->tiling != I915_TILING_Y);
-	if (drmModeAddFB(sna->kgem.fd, width, height,
-			 scrn->depth, scrn->bitsPerPixel,
-			 bo->pitch, bo->handle,
-			 &mode->fb_id)) {
-		ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
-		       __FUNCTION__,
-		       width, height,
-		       scrn->depth, scrn->bitsPerPixel, bo->pitch);
+	assert(bo->delta == 0);
+
+	mode->fb_id = get_fb(sna, bo, width, height);
+	if (mode->fb_id == 0)
 		goto fail;
-	}
 
 	DBG(("%s: handle %d, pixmap serial %lu attached to fb %d\n",
 	     __FUNCTION__, bo->handle,
 	     sna->front->drawable.serialNumber, mode->fb_id));
 
-	bo->scanout = true;
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
 
@@ -1739,17 +1738,12 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
 	assert(scrn->pScreen->GetScreenPixmap(scrn->pScreen) == sna->front);
 	assert(scrn->pScreen->GetWindowPixmap(scrn->pScreen->root) == sna->front);
 
-	if (old_fb_id)
-		drmModeRmFB(sna->kgem.fd, old_fb_id);
-	kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(old_front));
 	scrn->pScreen->DestroyPixmap(old_front);
 
 	return TRUE;
 
 fail:
 	DBG(("%s: restoring original front pixmap and fb\n", __FUNCTION__));
-	if (old_fb_id != mode->fb_id)
-		drmModeRmFB(sna->kgem.fd, mode->fb_id);
 	mode->fb_id = old_fb_id;
 
 	if (sna->front)
@@ -1843,15 +1837,9 @@ sna_page_flip(struct sna *sna,
 	/*
 	 * Create a new handle for the back buffer
 	 */
-	assert(bo->tiling != I915_TILING_Y);
-	if (drmModeAddFB(sna->kgem.fd, scrn->virtualX, scrn->virtualY,
-			 scrn->depth, scrn->bitsPerPixel,
-			 bo->pitch, bo->handle,
-			 &mode->fb_id)) {
-		ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
-		       __FUNCTION__,
-		       scrn->virtualX, scrn->virtualY,
-		       scrn->depth, scrn->bitsPerPixel, bo->pitch);
+	mode->fb_id = get_fb(sna, bo, scrn->virtualX, scrn->virtualY);
+	if (mode->fb_id == 0) {
+		mode->fb_id = *old_fb;
 		return 0;
 	}
 
@@ -1871,23 +1859,14 @@ sna_page_flip(struct sna *sna,
 	 */
 	count = do_page_flip(sna, data, ref_crtc_hw_id);
 	DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count));
-	if (count) {
-		bo->scanout = true;
+	if (count)
 		bo->domain = DOMAIN_NONE;
-	} else {
-		drmModeRmFB(sna->kgem.fd, mode->fb_id);
+	else
 		mode->fb_id = *old_fb;
-	}
 
 	return count;
 }
 
-void sna_mode_delete_fb(struct sna *sna, uint32_t fb)
-{
-	if (fb)
-		drmModeRmFB(sna->kgem.fd, fb);
-}
-
 static const xf86CrtcConfigFuncsRec sna_crtc_config_funcs = {
 	sna_crtc_resize
 };
@@ -1932,11 +1911,8 @@ sna_mode_remove_fb(struct sna *sna)
 	DBG(("%s: deleting fb id %d for pixmap serial %d\n",
 	     __FUNCTION__, mode->fb_id,mode->fb_pixmap));
 
-	if (mode->fb_id) {
-		drmModeRmFB(sna->kgem.fd, mode->fb_id);
-		mode->fb_id = 0;
-		mode->fb_pixmap = 0;
-	}
+	mode->fb_id = 0;
+	mode->fb_pixmap = 0;
 }
 
 void
@@ -1957,7 +1933,6 @@ sna_mode_fini(struct sna *sna)
 #endif
 
 	sna_mode_remove_fb(sna);
-	kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(sna->front));
 
 	/* mode->shadow_fb_id should have been destroyed already */
 }
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index d5eefcb..32602d5 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -336,7 +336,6 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 		}
 
 		private->bo->flush = 0;
-		kgem_bo_clear_scanout(&sna->kgem, private->bo); /* paranoia */
 		kgem_bo_destroy(&sna->kgem, private->bo);
 
 		free(buffer);
@@ -392,7 +391,6 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
 	sna_damage_destroy(&priv->cpu_damage);
 	priv->undamaged = false;
 
-	kgem_bo_clear_scanout(&sna->kgem, priv->gpu_bo); /* paranoia */
 	kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
 	priv->gpu_bo = ref(bo);
 }
@@ -860,18 +858,10 @@ sna_dri_add_frame_event(struct sna_dri_frame_event *info)
 static void
 sna_dri_frame_event_release_bo(struct kgem *kgem, struct kgem_bo *bo)
 {
-	kgem_bo_clear_scanout(kgem, bo);
 	kgem_bo_destroy(kgem, bo);
 }
 
 static void
-sna_dri_frame_event_finish(struct sna_dri_frame_event *info)
-{
-	sna_mode_delete_fb(info->sna, info->old_fb);
-	kgem_bo_clear_scanout(&info->sna->kgem, info->old_front.bo);
-}
-
-static void
 sna_dri_frame_event_info_free(struct sna_dri_frame_event *info)
 {
 	DBG(("%s: del[%p] (%p, %ld)\n", __FUNCTION__,
@@ -1177,13 +1167,10 @@ static void sna_dri_flip_event(struct sna *sna,
 					 flip->event_data);
 		}
 
-		sna_dri_frame_event_finish(flip);
 		sna_dri_frame_event_info_free(flip);
 		break;
 
 	case DRI2_FLIP_THROTTLE:
-		sna_dri_frame_event_finish(flip);
-
 		assert(sna->dri.flip_pending[flip->pipe] == flip);
 		sna->dri.flip_pending[flip->pipe] = NULL;
 
@@ -1221,8 +1208,6 @@ static void sna_dri_flip_event(struct sna *sna,
 		     flip->front->name != flip->old_front.name));
 		assert(sna->dri.flip_pending[flip->pipe] == flip);
 
-		sna_dri_frame_event_finish(flip);
-
 		if (flip->front->name != flip->next_front.name) {
 			DBG(("%s: async flip continuing\n", __FUNCTION__));
 
@@ -1801,7 +1786,6 @@ blit:
 		}
 		info->front->name = info->back->name;
 		get_private(info->front)->bo = get_private(info->back)->bo;
-		__kgem_flush(&sna->kgem, get_private(info->back)->bo);
 	}
 
 	if (bo == NULL) {
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 7b3cfce..150e973 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -784,9 +784,6 @@ static Bool sna_close_screen(int scrnIndex, ScreenPtr screen)
 
 	sna_mode_remove_fb(sna);
 	if (sna->front) {
-		struct kgem_bo *bo = sna_pixmap_get_bo(sna->front);
-		if (bo)
-			kgem_bo_clear_scanout(&sna->kgem, bo); /* valgrind */
 		screen->DestroyPixmap(sna->front);
 		sna->front = NULL;
 	}
commit 29d035279b2fe98d5ba9cf01125faea34d36fb76
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 4 09:11:31 2012 +0100

    sna/dri: pageflip unref debugging
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 956a038..5272a08 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -130,6 +130,8 @@ struct sna_pixmap {
 	uint32_t stride;
 	uint32_t clear_color;
 
+	uint32_t flush;
+
 #define SOURCE_BIAS 4
 	uint16_t source_count;
 	uint8_t pinned :1;
@@ -138,7 +140,6 @@ struct sna_pixmap {
 	uint8_t undamaged :1;
 	uint8_t create :3;
 	uint8_t header :1;
-	uint8_t flush :1;
 };
 
 struct sna_glyph {
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 1ad2ff1..d5eefcb 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -163,7 +163,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 	if (priv == NULL)
 		return NULL;
 
-	if (priv->flush)
+	if (priv->flush++)
 		return priv->gpu_bo;
 
 	tiling = color_tiling(sna, &pixmap->drawable);
@@ -181,7 +181,6 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 
 	/* Don't allow this named buffer to be replaced */
 	priv->pinned = 1;
-	priv->flush = true;
 
 	return priv->gpu_bo;
 }
@@ -317,17 +316,21 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 	if (buffer == NULL)
 		return;
 
+	DBG(("%s: %p [handle=%d] -- refcnt=%d, pixmap=%d\n",
+	     __FUNCTION__, buffer, private->bo->handle, private->refcnt,
+	     private->pixmap ? private->pixmap->drawable.serialNumber : 0));
+
 	if (--private->refcnt == 0) {
 		if (private->pixmap) {
 			ScreenPtr screen = private->pixmap->drawable.pScreen;
 			struct sna_pixmap *priv = sna_pixmap(private->pixmap);
 
 			/* Undo the DRI markings on this pixmap */
-			assert(priv->flush);
-			list_del(&priv->list);
-			sna_accel_watch_flush(sna, -1);
-			priv->pinned = private->pixmap == sna->front;
-			priv->flush = false;
+			if (priv->flush && --priv->flush == 0) {
+				list_del(&priv->list);
+				sna_accel_watch_flush(sna, -1);
+				priv->pinned = private->pixmap == sna->front;
+			}
 
 			screen->DestroyPixmap(private->pixmap);
 		}
@@ -1238,6 +1241,8 @@ static void sna_dri_flip_event(struct sna *sna,
 			flip->next_front.name = flip->front->name;
 			flip->off_delay = 5;
 		} else if (--flip->off_delay) {
+			DBG(("%s: queuing no-flip [delay=%d]\n",
+			     __FUNCTION__, flip->off_delay));
 			/* Just queue a no-op flip to trigger another event */
 			flip->count = sna_page_flip(sna,
 						    get_private(flip->front)->bo,
@@ -1765,6 +1770,13 @@ blit:
 			goto blit;
 		}
 
+		DBG(("%s: referencing (%p:%d, %p:%d)\n",
+		     __FUNCTION__,
+		     front, get_private(front)->refcnt,
+		     back, get_private(back)->refcnt));
+		sna_dri_reference_buffer(front);
+		sna_dri_reference_buffer(back);
+
 		if (!sna_dri_page_flip(sna, info)) {
 			sna_dri_frame_event_info_free(info);
 			goto blit;
@@ -1773,9 +1785,6 @@ blit:
 		info->next_front.name = info->front->name;
 		info->next_front.bo = get_private(info->front)->bo;
 		info->off_delay = 5;
-
-		sna_dri_reference_buffer(front);
-		sna_dri_reference_buffer(back);
 	} else if (info->type != DRI2_ASYNC_FLIP) {
 		/* A normal vsync'ed client is finishing, wait for it
 		 * to unpin the old framebuffer before taking over.


More information about the xorg-commit mailing list