xf86-video-intel: 5 commits - src/sna/kgem.c src/sna/sna_display.c src/sna/sna_dri2.c src/sna/sna.h src/uxa/intel_dri.c

Chris Wilson ickle at kemper.freedesktop.org
Tue May 20 23:49:39 PDT 2014


 src/sna/kgem.c        |    2 
 src/sna/sna.h         |    6 ++
 src/sna/sna_display.c |   22 ++++++----
 src/sna/sna_dri2.c    |  109 +++++++++++++++++++++++++++-----------------------
 src/uxa/intel_dri.c   |    3 -
 5 files changed, 84 insertions(+), 58 deletions(-)

New commits:
commit 183a0728ba52be9d052f5a5f6e6b54c4a9ee8253
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed May 21 12:41:58 2014 +1000

    uxa: fix getmsc to not fail hard
    
    If some outputs go away we race with this call and apps
    get X errors and fall over. Do what SNA does and don't
    bother trying.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/uxa/intel_dri.c b/src/uxa/intel_dri.c
index ca58052..01209b9 100644
--- a/src/uxa/intel_dri.c
+++ b/src/uxa/intel_dri.c
@@ -1356,6 +1356,7 @@ I830DRI2GetMSC(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
 
 	/* Drawable not displayed, make up a *monotonic* value */
 	if (pipe == -1) {
+fail:
 		*ust = gettime_us();
 		*msc = 0;
 		return TRUE;
@@ -1374,7 +1375,7 @@ I830DRI2GetMSC(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
 				   strerror(errno));
 			limit--;
 		}
-		return FALSE;
+		goto fail;
 	}
 
 	*ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
commit 2dbe76c4925e02b8ec20b986069e2ff38cea5bba
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed May 21 07:38:35 2014 +0100

    sna/dri2: Tidy computation of 64bit ust
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 8cfa98a..a514181 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -463,6 +463,11 @@ extern xf86CrtcPtr sna_covering_crtc(struct sna *sna,
 extern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap,
 				  xf86CrtcPtr crtc, const BoxRec *clip);
 
+static inline uint64_t ust64(int tv_sec, int tv_usec)
+{
+	return (uint64_t)tv_sec * 1000000 + tv_usec;
+}
+
 #if HAVE_DRI2_H
 bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen);
 void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event);
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 6991c91..d86c86e 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -2402,8 +2402,8 @@ fail:
 		if (pipe < 0)
 			pipe = 0;
 		*msc = sna->dri2.last_swap[pipe].msc;
-		*ust = ((uint64_t)sna->dri2.last_swap[pipe].tv_sec * 100000 +
-			sna->dri2.last_swap[pipe].tv_usec);
+		*ust = ust64(sna->dri2.last_swap[pipe].tv_sec,
+			     sna->dri2.last_swap[pipe].tv_usec);
 		return TRUE;
 	}
 
@@ -2420,7 +2420,7 @@ fail:
 		sna->dri2.last_swap[pipe].tv_usec = vbl.reply.tval_usec;
 		sna->dri2.last_swap[pipe].msc = vbl.reply.sequence;
 
-		*ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
+		*ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec);
 		*msc = vbl.reply.sequence;
 		DBG(("%s: msc=%llu, ust=%llu\n", __FUNCTION__,
 		     (long long)*msc, (long long)*ust));
commit a82f6a7594ee13170aba5bac7fb57cd5550b27ee
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 20 12:20:38 2014 +0100

    sna/dri2: Client cannot be NULL, so drop the checks
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index af1c8b5..6991c91 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1359,7 +1359,7 @@ static void chain_swap(struct sna *sna,
 		DRI2SwapComplete(chain->client, draw,
 				 frame, tv_sec, tv_usec,
 				 DRI2_BLIT_COMPLETE,
-				 chain->client ? chain->event_complete : NULL, chain->event_data);
+				 chain->event_complete, chain->event_data);
 		sna_dri2_frame_event_info_free(sna, draw, chain);
 	} else {
 #if !XORG_CAN_TRIPLE_BUFFER
@@ -1367,7 +1367,7 @@ static void chain_swap(struct sna *sna,
 		DRI2SwapComplete(chain->client, draw,
 				 frame, tv_sec, tv_usec,
 				 DRI2_BLIT_COMPLETE,
-				 chain->client ? chain->event_complete : NULL, chain->event_data);
+				 chain->event_complete, chain->event_data);
 #else
 		DBG(("%s: setting swap limit to 2\n", __FUNCTION__));
 		DRI2SwapLimit(draw, 2);
@@ -1475,8 +1475,7 @@ void sna_dri2_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
 				 draw, event->sequence,
 				 event->tv_sec, event->tv_usec,
 				 DRI2_BLIT_COMPLETE,
-				 info->client ? info->event_complete : NULL,
-				 info->event_data);
+				 info->event_complete, info->event_data);
 		break;
 
 	case SWAP_THROTTLE:
@@ -1494,8 +1493,7 @@ void sna_dri2_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
 				 draw, event->sequence,
 				 event->tv_sec, event->tv_usec,
 				 DRI2_BLIT_COMPLETE,
-				 info->client ? info->event_complete : NULL,
-				 info->event_data);
+				 info->event_complete, info->event_data);
 #endif
 		break;
 
@@ -1690,8 +1688,7 @@ sna_dri2_flip_continue(struct sna *sna, struct sna_dri2_frame_event *info)
 		DBG(("%s: fake triple buffering, unblocking client\n", __FUNCTION__));
 		fake_swap_complete(sna, info->client, info->draw,
 				   DRI2_FLIP_COMPLETE,
-				   info->client ? info->event_complete : NULL,
-				   info->event_data);
+				   info->event_complete, info->event_data);
 #endif
 	}
 
@@ -1743,7 +1740,7 @@ static void chain_flip(struct sna *sna)
 		DBG(("%s: fake triple buffering (or vblank wait failed), unblocking client\n", __FUNCTION__));
 		fake_swap_complete(sna, chain->client, chain->draw,
 				   DRI2_BLIT_COMPLETE,
-				   chain->client ? chain->event_complete : NULL, chain->event_data);
+				   chain->event_complete, chain->event_data);
 		sna_dri2_frame_event_info_free(sna, chain->draw, chain);
 	}
 }
@@ -1810,8 +1807,7 @@ static void sna_dri2_flip_event(struct sna *sna,
 					 flip->fe_tv_sec,
 					 flip->fe_tv_usec,
 					 DRI2_FLIP_COMPLETE,
-					 flip->client ? flip->event_complete : NULL,
-					 flip->event_data);
+					 flip->event_complete, flip->event_data);
 		}
 
 		sna_dri2_frame_event_info_free(sna, flip->draw, flip);
@@ -1829,8 +1825,7 @@ static void sna_dri2_flip_event(struct sna *sna,
 					 flip->fe_tv_sec,
 					 flip->fe_tv_usec,
 					 DRI2_FLIP_COMPLETE,
-					 flip->client ? flip->event_complete : NULL,
-					 flip->event_data);
+					 flip->event_complete, flip->event_data);
 		}
 	case FLIP_COMPLETE:
 		if (sna->dri2.flip_pending) {
commit c548427e6d3a3fb50acec4b405b9d0ea977d3cc9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 20 16:36:31 2014 +0100

    sna: Only mark the scanout as being busy for writes (not solitary reads)
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 7e906e8..f635150 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2486,7 +2486,7 @@ static void kgem_commit(struct kgem *kgem)
 			__kgem_bo_clear_busy(bo);
 		}
 
-		kgem->scanout_busy |= bo->scanout;
+		kgem->scanout_busy |= bo->scanout && bo->needs_flush;
 	}
 
 	if (rq == &kgem->static_request) {
commit 61df0ffc0be8d934d86ac45c67da910479998cc7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 20 12:07:50 2014 +0100

    sna/dri2: Verify that the reference pipe is still active for flipping
    
    We rely on the reference pipe to drive the event wake up. If we issue a
    deferred flip, there is a chance that the user could rearrange the
    screen on another crtc whilst otherwise preserving the screen geometry.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 0c0508b..8cfa98a 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -483,6 +483,7 @@ extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation);
 extern int sna_crtc_to_pipe(xf86CrtcPtr crtc);
 extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc);
 extern uint32_t sna_crtc_id(xf86CrtcPtr crtc);
+extern int sna_crtc_is_on(xf86CrtcPtr crtc);
 
 CARD32 sna_format_for_depth(int depth);
 CARD32 sna_render_format_for_depth(int depth);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5671db5..69d42b7 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -222,6 +222,12 @@ uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc)
 	return to_sna_crtc(crtc)->sprite;
 }
 
+int sna_crtc_is_on(xf86CrtcPtr crtc)
+{
+	assert(to_sna_crtc(crtc));
+	return to_sna_crtc(crtc)->bo != NULL;
+}
+
 #ifndef NDEBUG
 static void gem_close(int fd, uint32_t handle);
 static void assert_scanout(struct kgem *kgem, struct kgem_bo *bo,
@@ -4009,7 +4015,7 @@ sna_cursors_fini(struct sna *sna)
 }
 
 static int do_page_flip(struct sna *sna, struct kgem_bo *bo,
-			void *data, int ref_crtc_hw_id)
+			void *data, int pipe)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
 	int width = sna->scrn->virtualX;
@@ -4032,8 +4038,10 @@ static int do_page_flip(struct sna *sna, struct kgem_bo *bo,
 
 		DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n",
 		     __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo != NULL));
-		if (crtc->bo == NULL)
+		if (crtc->bo == NULL) {
+			assert(crtc->pipe != pipe);
 			continue;
+		}
 
 		arg.crtc_id = crtc->id;
 		arg.fb_id = get_fb(sna, bo, width, height);
@@ -4044,16 +4052,16 @@ static int do_page_flip(struct sna *sna, struct kgem_bo *bo,
 		 * completion event. All other crtc's events will be discarded.
 		 */
 		arg.user_data = (uintptr_t)data;
-		arg.user_data |= crtc->pipe == ref_crtc_hw_id;
+		arg.user_data |= crtc->pipe == pipe;
 		arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
 		arg.reserved = 0;
 
 		DBG(("%s: crtc %d id=%d, pipe=%d, [ref? %d] --> fb %d\n",
 		     __FUNCTION__, i, crtc->id, crtc->pipe,
-		     crtc->pipe == ref_crtc_hw_id, arg.fb_id));
+		     crtc->pipe == pipe, arg.fb_id));
 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
 			DBG(("%s: flip [fb=%d] on crtc %d id=%d failed - %d\n",
-			     __FUNCTION__, arg.fb_id, i, crtc->id, crtc->pipe errno));
+			     __FUNCTION__, arg.fb_id, i, crtc->id, crtc->pipe, errno));
 disable:
 			if (count == 0)
 				return 0;
@@ -4080,7 +4088,7 @@ int
 sna_page_flip(struct sna *sna,
 	      struct kgem_bo *bo,
 	      void *data,
-	      int ref_crtc_hw_id)
+	      int pipe)
 {
 	int count;
 
@@ -4099,7 +4107,7 @@ sna_page_flip(struct sna *sna,
 	 * Also, flips queued on disabled or incorrectly configured displays
 	 * may never complete; this is a configuration error.
 	 */
-	count = do_page_flip(sna, bo, data, ref_crtc_hw_id);
+	count = do_page_flip(sna, bo, data, pipe);
 	DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count));
 
 	return count;
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 68299b7..af1c8b5 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -877,6 +877,7 @@ inline static uint32_t pipe_select(int pipe)
 static inline int sna_wait_vblank(struct sna *sna, drmVBlank *vbl, int pipe)
 {
 	DBG(("%s(pipe=%d)\n", __FUNCTION__, pipe));
+	assert(pipe != -1);
 
 	vbl->request.type |= pipe_select(pipe);
 	return drmIoctl(sna->kgem.fd, DRM_IOCTL_WAIT_VBLANK, vbl);
@@ -894,6 +895,7 @@ struct sna_dri2_frame_event {
 	DrawablePtr draw;
 	ClientPtr client;
 	enum frame_event_type type;
+	xf86CrtcPtr crtc;
 	int pipe;
 	int count;
 
@@ -926,33 +928,22 @@ to_frame_event(uintptr_t  data)
 	 return (struct sna_dri2_frame_event *)(data & ~1);
 }
 
-static int
-sna_dri2_get_pipe(DrawablePtr draw)
+static xf86CrtcPtr
+sna_dri2_get_crtc(DrawablePtr draw)
 {
 	struct sna *sna = to_sna_from_drawable(draw);
-	xf86CrtcPtr crtc;
 	BoxRec box;
-	int pipe;
 
 	if (draw->type == DRAWABLE_PIXMAP)
-		return -1;
+		return NULL;
 
 	box.x1 = draw->x;
 	box.y1 = draw->y;
 	box.x2 = box.x1 + draw->width;
 	box.y2 = box.y1 + draw->height;
 
-	crtc = sna_covering_crtc(sna, &box, NULL);
-
 	/* Make sure the CRTC is valid and this is the real front buffer */
-	pipe = -1;
-	if (crtc != NULL)
-		pipe = sna_crtc_to_pipe(crtc);
-
-	DBG(("%s(box=((%d, %d), (%d, %d)), pipe=%d)\n",
-	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2, pipe));
-
-	return pipe;
+	return sna_covering_crtc(sna, &box, NULL);
 }
 
 static struct sna_dri2_frame_event *
@@ -1134,7 +1125,8 @@ static bool
 can_flip(struct sna * sna,
 	 DrawablePtr draw,
 	 DRI2BufferPtr front,
-	 DRI2BufferPtr back)
+	 DRI2BufferPtr back,
+	 xf86CrtcPtr crtc)
 {
 	WindowPtr win = (WindowPtr)draw;
 	PixmapPtr pixmap;
@@ -1173,6 +1165,11 @@ can_flip(struct sna * sna,
 		return false;
 	}
 
+	if (!sna_crtc_is_on(crtc)) {
+		DBG(("%s: ref-pipe=%d is disabled\n", __FUNCTION__, sna_crtc_to_pipe(crtc)));
+		return false;
+	}
+
 	pixmap = get_window_pixmap(win);
 	if (pixmap != sna->front) {
 		DBG(("%s: no, window (pixmap=%ld) is not attached to the front buffer (pixmap=%ld)\n",
@@ -1426,6 +1423,7 @@ void sna_dri2_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
 	drmVBlank vbl;
 
 	DBG(("%s(type=%d, sequence=%d)\n", __FUNCTION__, info->type, event->sequence));
+	assert((unsigned)info->pipe < MAX_PIPES);
 	sna->dri2.last_swap[info->pipe].msc = event->sequence;
 	sna->dri2.last_swap[info->pipe].tv_sec = event->tv_sec;
 	sna->dri2.last_swap[info->pipe].tv_usec = event->tv_usec;
@@ -1439,7 +1437,7 @@ void sna_dri2_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
 	switch (info->type) {
 	case FLIP:
 		/* If we can still flip... */
-		if (can_flip(sna, draw, info->front, info->back) &&
+		if (can_flip(sna, draw, info->front, info->back, info->crtc) &&
 		    sna_dri2_page_flip(sna, info))
 			return;
 
@@ -1680,7 +1678,7 @@ sna_dri2_flip_continue(struct sna *sna, struct sna_dri2_frame_event *info)
 		if (!info->draw)
 			return false;
 
-		if (!can_flip(sna, info->draw, info->front, info->back))
+		if (!can_flip(sna, info->draw, info->front, info->back, info->crtc))
 			return false;
 
 		assert(sna_pixmap_get_buffer(get_drawable_pixmap(info->draw)) == info->front);
@@ -1717,7 +1715,7 @@ static void chain_flip(struct sna *sna)
 	assert(chain == sna_dri2_window_get_chain((WindowPtr)chain->draw));
 
 	if (chain->type == FLIP &&
-	    can_flip(sna, chain->draw, chain->front, chain->back) &&
+	    can_flip(sna, chain->draw, chain->front, chain->back, chain->crtc) &&
 	    sna_dri2_page_flip(sna, chain)) {
 		DBG(("%s: performing chained flip\n", __FUNCTION__));
 	} else {
@@ -1872,7 +1870,7 @@ static void sna_dri2_flip_event(struct sna *sna,
 
 void
 sna_dri2_page_flip_handler(struct sna *sna,
-			  struct drm_event_vblank *event)
+			   struct drm_event_vblank *event)
 {
 	struct sna_dri2_frame_event *info = to_frame_event(event->user_data);
 
@@ -1993,13 +1991,14 @@ static bool immediate_swap(struct sna *sna,
 }
 
 static bool
-sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw,
-		      DRI2BufferPtr front, DRI2BufferPtr back, int pipe,
+sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
+		      DRI2BufferPtr front, DRI2BufferPtr back,
 		      CARD64 *target_msc, CARD64 divisor, CARD64 remainder,
 		      DRI2SwapEventPtr func, void *data)
 {
 	struct sna *sna = to_sna_from_drawable(draw);
 	struct sna_dri2_frame_event *info;
+	int pipe = sna_crtc_to_pipe(crtc);
 	drmVBlank vbl;
 	CARD64 current_msc;
 
@@ -2045,6 +2044,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw,
 		info->event_data = data;
 		info->front = front;
 		info->back = back;
+		info->crtc = crtc;
 		info->pipe = pipe;
 
 		info->scanout[0].bo = ref(get_private(front)->bo);
@@ -2102,6 +2102,7 @@ out:
 	info->event_data = data;
 	info->front = front;
 	info->back = back;
+	info->crtc = crtc;
 	info->pipe = pipe;
 	info->type = FLIP;
 
@@ -2135,16 +2136,19 @@ out:
 		     (int)divisor));
 		vbl.request.sequence = *target_msc - 1;
 	} else {
-		DBG(("%s: missed target, queueing event for next: current=%d, target=%d, divisor=%d\n",
+		DBG(("%s: missed target, queueing event for next: current=%d, target=%d, divisor=%d, remainder=%d\n",
 		     __FUNCTION__,
 		     (int)current_msc,
 		     (int)*target_msc,
-		     (int)divisor));
+		     (int)divisor,
+		     (int)remainder));
 
 		vbl.request.sequence = current_msc;
 		if (divisor)
 			vbl.request.sequence += remainder - current_msc % divisor;
 
+		DBG(("%s: initial sequence = %d\n", __FUNCTION__, vbl.request.sequence));
+
 		/*
 		 * If the calculated deadline vbl.request.sequence is
 		 * smaller than or equal to current_msc, it means
@@ -2160,6 +2164,8 @@ out:
 		if (vbl.request.sequence <= current_msc)
 			vbl.request.sequence += divisor;
 
+		DBG(("%s: flip adjusted sequence = %d\n", __FUNCTION__, vbl.request.sequence));
+
 		/* Adjust returned value for 1 frame pageflip offset */
 		*target_msc = vbl.reply.sequence;
 	}
@@ -2206,7 +2212,7 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 {
 	struct sna *sna = to_sna_from_drawable(draw);
 	drmVBlank vbl;
-	int pipe;
+	xf86CrtcPtr crtc;
 	struct sna_dri2_frame_event *info = NULL;
 	CARD64 current_msc;
 
@@ -2249,16 +2255,16 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	assert(sna_pixmap_from_drawable(draw)->flush);
 
 	/* Drawable not displayed... just complete the swap */
-	pipe = -1;
+	crtc = NULL;
 	if ((sna->flags & SNA_NO_WAIT) == 0)
-		pipe = sna_dri2_get_pipe(draw);
-	if (pipe == -1) {
+		crtc = sna_dri2_get_crtc(draw);
+	if (crtc == NULL) {
 		DBG(("%s: off-screen, immediate update\n", __FUNCTION__));
 		goto blit;
 	}
 
-	if (can_flip(sna, draw, front, back) &&
-	    sna_dri2_schedule_flip(client, draw, front, back, pipe,
+	if (can_flip(sna, draw, front, back, crtc) &&
+	    sna_dri2_schedule_flip(client, draw, crtc, front, back,
 				  target_msc, divisor, remainder,
 				  func, data))
 		return TRUE;
@@ -2276,7 +2282,8 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	info->event_data = data;
 	info->front = front;
 	info->back = back;
-	info->pipe = pipe;
+	info->crtc = crtc;
+	info->pipe = sna_crtc_to_pipe(crtc);
 
 	sna_dri2_add_frame_event(draw, info);
 	sna_dri2_reference_buffer(front);
@@ -2284,7 +2291,7 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 
 	info->type = SWAP;
 
-	if (immediate_swap(sna, *target_msc, divisor, pipe, &current_msc)) {
+	if (immediate_swap(sna, *target_msc, divisor, info->pipe, &current_msc)) {
 		bool sync = current_msc < *target_msc;
 		if (!sna_dri2_immediate_blit(sna, info, sync, true))
 			sna_dri2_frame_event_info_free(sna, draw, info);
@@ -2354,7 +2361,7 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 		}
 	}
 
-	if (sna_wait_vblank(sna, &vbl, pipe))
+	if (sna_wait_vblank(sna, &vbl, info->pipe))
 		goto blit;
 
 	return TRUE;
@@ -2371,6 +2378,15 @@ skip:
 	return TRUE;
 }
 
+static int sna_dri2_get_pipe(DrawablePtr draw)
+{
+	int pipe = -1;
+	xf86CrtcPtr crtc = sna_dri2_get_crtc(draw);
+	if (crtc)
+		pipe = sna_crtc_to_pipe(crtc);
+	return pipe;
+}
+
 /*
  * Get current frame count and frame count timestamp, based on drawable's
  * crtc.


More information about the xorg-commit mailing list