[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 configure.ac                 |    2 
 src/i915_pciids.h            |   13 ++-
 src/sna/kgem.c               |   13 +++
 src/sna/sna_damage.h         |    5 -
 src/sna/sna_display.c        |   28 ++++++
 src/sna/sna_dri2.c           |   53 +++++++++---
 src/sna/sna_video.h          |   22 +++++
 src/sna/sna_video_overlay.c  |   10 --
 src/sna/sna_video_sprite.c   |   10 --
 src/sna/sna_video_textured.c |    7 -
 tools/virtual.c              |  179 +++++++++++++++++++++++++++++++++++++++++--
 11 files changed, 296 insertions(+), 46 deletions(-)

New commits:
commit 7817949314a21293c8bc34dec214b42932b19aaf
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Jan 27 10:54:46 2016 +0000

    sna/dri2: Avoiding marking a pending-signal on a dead Drawable
    
    If the Drawable is gone, we cannot send it a frame-complete signal, and
    in particular we cannot continue the pending flip-chain.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=93844
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index f2f4908..045b12d 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -2787,6 +2787,9 @@ sna_dri2_flip_continue(struct sna_dri2_event *info)
 	info->type = info->flip_continue;
 	info->flip_continue = 0;
 
+	if (info->draw == NULL)
+		return false;
+
 	if (info->sna->mode.front_active == 0)
 		return false;
 
@@ -2801,6 +2804,7 @@ sna_dri2_flip_continue(struct sna_dri2_event *info)
 	       info->sna->dri2.flip_pending == info);
 	info->sna->dri2.flip_pending = info;
 	info->queued = true;
+	assert(info->draw);
 	info->signal = info->type == FLIP_THROTTLE;
 
 	return true;
@@ -3097,6 +3101,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 		assert(info->crtc == crtc);
 		info->event_complete = func;
 		info->event_data = data;
+		assert(info->draw);
 		info->signal = true;
 
 		info->front = sna_dri2_reference_buffer(front);
@@ -3133,6 +3138,7 @@ new_back:
 				sna_dri2_get_back(sna, draw, back);
 			DBG(("%s: fake triple buffering, unblocking client\n", __FUNCTION__));
 			frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE);
+			assert(info->draw);
 			info->signal = signal;
 			if (info->type == FLIP_ASYNC)
 				sna_dri2_event_free(info);
@@ -3156,6 +3162,7 @@ queue:
 	assert(info->crtc == crtc);
 	info->event_complete = func;
 	info->event_data = data;
+	assert(info->draw);
 	info->signal = true;
 	info->type = FLIP;
 
@@ -3312,6 +3319,7 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	assert(info->crtc == crtc);
 	info->event_complete = func;
 	info->event_data = data;
+	assert(info->draw);
 	info->signal = true;
 
 	info->front = sna_dri2_reference_buffer(front);
@@ -3391,6 +3399,7 @@ fake:
 		/* XXX Use a Timer to throttle the client? */
 		fake_swap_complete(sna, client, draw, crtc, type, func, data);
 		if (info) {
+			assert(info->draw);
 			info->signal = false;
 			sna_dri2_event_free(info);
 		}

commit bb8dc3ef37580a221a40ba3dcbde755edc59bb62
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jan 26 12:50:13 2016 +0000

    sna/video: ValidateGC before use
    
    We required the GC->pCompositeClip in order to apply the current Drawable's
    clip to video region, this requires us to call ValidateGC first.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93874
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index dfb8c0c..b278991 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -213,4 +213,26 @@ sna_window_set_port(WindowPtr window, XvPortPtr port)
 	((void **)__get_private(window, sna_window_key))[2] = port;
 }
 
+static inline int offset_and_clip(int x, int dx)
+{
+	x += dx;
+	if (x <= 0)
+		return 0;
+	if (x >= MAXSHORT)
+		return MAXSHORT;
+	return x;
+}
+
+static inline void init_video_region(RegionRec *region,
+				     DrawablePtr draw,
+				     int drw_x, int drw_y,
+				     int drw_w, int drw_h)
+{
+	region->extents.x1 = offset_and_clip(draw->x, drw_x);
+	region->extents.y1 = offset_and_clip(draw->y, drw_y);
+	region->extents.x2 = offset_and_clip(draw->x, drw_x + drw_w);
+	region->extents.y2 = offset_and_clip(draw->y, drw_y + drw_h);
+	region->data = NULL;
+}
+
 #endif /* SNA_VIDEO_H */
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index d782113..9bc5ce4 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -474,15 +474,13 @@ sna_video_overlay_put_image(ddPutImage_ARGS)
 	if (src_h >= (drw_h * 8))
 		drw_h = src_h / 7;
 
-	clip.extents.x1 = draw->x + drw_x;
-	clip.extents.y1 = draw->y + drw_y;
-	clip.extents.x2 = clip.extents.x1 + drw_w;
-	clip.extents.y2 = clip.extents.y1 + drw_h;
-	clip.data = NULL;
+	init_video_region(&clip, draw, drw_x, drw_y, drw_w, drw_h);
 
 	DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop));
-	if (!video->AlwaysOnTop)
+	if (!video->AlwaysOnTop) {
+		ValidateGC(draw, gc);
 		RegionIntersect(&clip, &clip, gc->pCompositeClip);
+	}
 	if (box_empty(&clip.extents))
 		goto invisible;
 
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 7c8a73f..9e85049 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -373,15 +373,13 @@ static int sna_video_sprite_put_image(ddPutImage_ARGS)
 	RegionRec clip;
 	int ret, i;
 
-	clip.extents.x1 = draw->x + drw_x;
-	clip.extents.y1 = draw->y + drw_y;
-	clip.extents.x2 = clip.extents.x1 + drw_w;
-	clip.extents.y2 = clip.extents.y1 + drw_h;
-	clip.data = NULL;
+	init_video_region(&clip, draw, drw_x, drw_y, drw_w, drw_h);
 
 	DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop));
-	if (!video->AlwaysOnTop)
+	if (!video->AlwaysOnTop) {
+		ValidateGC(draw, gc);
 		RegionIntersect(&clip, &clip, gc->pCompositeClip);
+	}
 
 	DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
 	     __FUNCTION__,
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index 3f14a59..f5b7e98 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -156,12 +156,9 @@ sna_video_textured_put_image(ddPutImage_ARGS)
 	if (wedged(sna))
 		return BadAlloc;
 
-	clip.extents.x1 = draw->x + drw_x;
-	clip.extents.y1 = draw->y + drw_y;
-	clip.extents.x2 = clip.extents.x1 + drw_w;
-	clip.extents.y2 = clip.extents.y1 + drw_h;
-	clip.data = NULL;
+	init_video_region(&clip, draw, drw_x, drw_y, drw_w, drw_h);
 
+	ValidateGC(draw, gc);
 	RegionIntersect(&clip, &clip, gc->pCompositeClip);
 	if (!RegionNotEmpty(&clip))
 		return Success;

commit 8ab71cd3293ad420b0cdf487e8d5c66170ddc13c
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Mon Jan 25 21:41:57 2016 +0000

    sna/dri2: Guard signalling swap completion after a FLIP
    
    Before sending the frame swap complete signal after a FLIP, make sure
    the client didn't die in the meantime.
    
    Reported-by: Diego Viola <diego.viola@gmail.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=93844
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 5450434..f2f4908 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -2873,8 +2873,10 @@ static void sna_dri2_flip_event(struct sna_dri2_event *flip)
 	/* We assume our flips arrive in order, so we don't check the frame */
 	switch (flip->type) {
 	case FLIP:
-		DBG(("%s: swap complete, unblocking client\n", __FUNCTION__));
-		frame_swap_complete(flip, DRI2_FLIP_COMPLETE);
+		if (flip->signal) {
+			DBG(("%s: swap complete, unblocking client\n", __FUNCTION__));
+			frame_swap_complete(flip, DRI2_FLIP_COMPLETE);
+		}
 		sna_dri2_event_free(flip);
 
 		if (sna->dri2.flip_pending)

commit 7bebe12afe549af3eceab35b29415f804949f994
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Mon Jan 25 16:03:27 2016 +0000

    sna/damage: Clear all-damaged NULL pointer on destroy
    
    Remember to reset the all-damaged pointer, even if it is NULL.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 3665255..d5c727e 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -319,10 +319,11 @@ static inline void sna_damage_reduce_all(struct sna_damage **_damage,
 void __sna_damage_destroy(struct sna_damage *damage);
 static inline void sna_damage_destroy(struct sna_damage **damage)
 {
-	if (DAMAGE_PTR(*damage) == NULL)
+	if (*damage == NULL)
 		return;
 
-	__sna_damage_destroy(DAMAGE_PTR(*damage));
+	if (DAMAGE_PTR(*damage))
+		__sna_damage_destroy(DAMAGE_PTR(*damage));
 	*damage = NULL;
 }
 

commit 21fa92a9ba254527a8661ddde837c7a4c5ff5493
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Mon Jan 25 15:37:01 2016 +0000

    sna/damage: Prevent freeing a NULL damage marked as all-damage
    
    After an allocation failure, we may mark a NULL damage pointer as being
    all-damaged. This works on the whole as most places we only ask whether it
    is all or not damaged, and if we do a partial fallback we should just
    then migrate the whole pixmap. However, we tried to destroy the NULL
    damage pointer, and crashed.
    
    Reported-by: Franck Delache <franck.delache@grassvalley.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=93720
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 272e83b..3665255 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -267,7 +267,7 @@ int _sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes);
 static inline int
 sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes)
 {
-	assert(damage);
+	assert(DAMAGE_PTR(damage));
 
 	if (DAMAGE_IS_ALL(damage)) {
 		*boxes = &DAMAGE_PTR(damage)->extents;
@@ -319,7 +319,7 @@ static inline void sna_damage_reduce_all(struct sna_damage **_damage,
 void __sna_damage_destroy(struct sna_damage *damage);
 static inline void sna_damage_destroy(struct sna_damage **damage)
 {
-	if (*damage == NULL)
+	if (DAMAGE_PTR(*damage) == NULL)
 		return;
 
 	__sna_damage_destroy(DAMAGE_PTR(*damage));

commit b48d4a7917ab793526be47559becc64aacd347ae
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jan 22 20:11:31 2016 +0000

    sna/dri2: Tweak enginement placement on inherited render targets
    
    The main motivation is try and isolate from an upcoming API change in
    busy-ioctl, but is also based on the observation that we now only care
    about write-synchronisation.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 0e18456..5450434 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1110,13 +1110,12 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
 	 * The ultimate question is whether preserving the ring outweighs
 	 * the cost of the query.
 	 */
-	if (popcount(busy.busy >> 16) > 1)
-		mode = busy.busy & 0xffff ? KGEM_BLT : KGEM_RENDER;
-	else if (busy.busy & (0xfffe << 16))
+	mode = KGEM_RENDER;
+	if ((busy.busy & 0xffff) == KGEM_BLT)
 		mode = KGEM_BLT;
-	else
-		mode = KGEM_RENDER;
-	kgem_bo_mark_busy(&sna->kgem, busy.handle == src->handle ? src : dst, mode);
+	kgem_bo_mark_busy(&sna->kgem,
+			  busy.handle == src->handle ? src : dst,
+			  mode);
 	_kgem_set_mode(&sna->kgem, mode);
 }
 

commit 26cc364d2eb078085ff4a6dd2968b426bf333b4f
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Jan 20 11:06:56 2016 +0000

    sna: Allow for a Y-tiled shadow
    
    If the CRTC can use Y-tiling, why not try it for the shadow allocation
    and perhaps save a composited rotation (still requiring the copy onto the
    shadow)?
    
    Suggestd-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 1a1bebb..511aa84 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2394,6 +2394,10 @@ force_shadow:
 		}
 
 		tiling = I915_TILING_X;
+		if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270) &&
+		    sna->kgem.can_scanout_y)
+			tiling = I915_TILING_Y;
+
 		if (sna->kgem.gen == 071)
 			tiled_limit = 16 * 1024 * 8;
 		else if ((sna->kgem.gen >> 3) > 4)

commit 3a057beca9f290854dd22cd4d2c0fed01c82dd78
Author: Damien Lespiau <damien.lespiau@intel.com>
Date:   Tue Jan 12 15:01:04 2016 +0000

    Sync PCI ids with latest kernel, adding SKL GT4
    
    Syncs with:
    
      commit 15620206ae87ba9643ffa6f5ddb5471be7192006
      Author: Mika Kuoppala <mika.kuoppala@linux.intel.com>
      Date:   Fri Nov 6 14:11:16 2015 +0200
    
          drm/i915/skl: Add SKL GT4 PCI IDs
    
    Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>

diff --git a/src/i915_pciids.h b/src/i915_pciids.h
index f1a113e..f970209 100644
--- a/src/i915_pciids.h
+++ b/src/i915_pciids.h
@@ -279,12 +279,19 @@
 #define INTEL_SKL_GT3_IDS(info) \
 	INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
 	INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
-	INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ \
+	INTEL_VGA_DEVICE(0x192A, info)  /* SRV GT3 */
 
-#define INTEL_SKL_IDS(info) \
+#define INTEL_SKL_GT4_IDS(info) \
+	INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \
+	INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */ \
+	INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \
+	INTEL_VGA_DEVICE(0x193A, info)  /* SRV GT4 */
+
+#define INTEL_SKL_IDS(info)	 \
 	INTEL_SKL_GT1_IDS(info), \
 	INTEL_SKL_GT2_IDS(info), \
-	INTEL_SKL_GT3_IDS(info)
+	INTEL_SKL_GT3_IDS(info), \
+	INTEL_SKL_GT4_IDS(info)
 
 #define INTEL_BXT_IDS(info) \
 	INTEL_VGA_DEVICE(0x0A84, info), \

commit c3dccf76b614d8bcf7fc8b0906754e187a7b7ac4
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Jan 20 10:52:19 2016 +0000

    sna: Reset CRTC if setting rotation fails
    
    If the kernel doesn't like chaning the native rotation mode with the
    output currently enabled, try disabling it before cryinc foul.
    
    Suggestd-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 8082e9f..1a1bebb 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1351,6 +1351,12 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 	sna_crtc_disable_cursor(sna, sna_crtc);
 
 	if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) {
+		memset(&arg, 0, sizeof(arg));
+		arg.crtc_id = __sna_crtc_id(sna_crtc);
+		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
+	}
+
+	if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) {
 		ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
 		     __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno));
 		sna_crtc->primary.rotation.supported &= ~sna_crtc->rotation;

commit 928050d4e4b0ee958be897d148b60328e9207228
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jan 19 08:49:18 2016 +0000

    sna/dri2: Catch setting signal=true when we have no drawable
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 63c4932..0e18456 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1507,6 +1507,7 @@ draw_current_msc(DrawablePtr draw, xf86CrtcPtr crtc, uint64_t msc)
 {
 	struct dri2_window *priv;
 
+	assert(draw);
 	if (draw->type != DRAWABLE_WINDOW)
 		return msc;
 
@@ -1595,6 +1596,8 @@ static void fake_swap_complete(struct sna *sna, ClientPtr client,
 {
 	const struct ust_msc *swap;
 
+	assert(draw);
+
 	swap = sna_crtc_last_swap(crtc);
 	DBG(("%s(type=%d): draw=%ld, pipe=%d, frame=%lld [msc %lld], tv=%d.%06d\n",
 	     __FUNCTION__, type, (long)draw->id, crtc ? sna_crtc_pipe(crtc) : -1,
@@ -1716,6 +1719,8 @@ sna_dri2_client_gone(CallbackListPtr *list, void *closure, void *data)
 
 		event->client = NULL;
 		event->draw = NULL;
+		event->keepalive = 1;
+		assert(!event->signal);
 
 		if (!event->queued)
 			sna_dri2_event_free(event);
@@ -1751,6 +1756,7 @@ sna_dri2_add_event(struct sna *sna,
 	struct dri2_window *priv;
 	struct sna_dri2_event *info, *chain;
 
+	assert(draw != NULL);
 	assert(draw->type == DRAWABLE_WINDOW);
 	DBG(("%s: adding event to window %ld)\n",
 	     __FUNCTION__, (long)draw->id));
@@ -1852,6 +1858,8 @@ void sna_dri2_destroy_window(WindowPtr win)
 
 			info->signal = false;
 			info->draw = NULL;
+			info->keepalive = 1;
+			assert(!info->signal);
 			list_del(&info->link);
 
 			chain = info->chain;
@@ -2636,8 +2644,10 @@ void sna_dri2_vblank_handler(struct drm_event_vblank *event)
 			else
 				__sna_dri2_copy_event(info, info->sync | DRI2_BO);
 
-			info->keepalive++;
-			info->signal = true;
+			if (info->draw) {
+				info->keepalive++;
+				info->signal = true;
+			}
 		}
 
 		if (--info->keepalive) {
@@ -2729,6 +2739,7 @@ sna_dri2_immediate_blit(struct sna *sna,
 			bool signal = chain->signal;
 
 			DBG(("%s: swap elision, unblocking client\n", __FUNCTION__));
+			assert(chain->draw);
 			chain->signal = true;
 			frame_swap_complete(chain, DRI2_EXCHANGE_COMPLETE);
 			chain->signal = signal;
@@ -3072,6 +3083,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 			} else {
 				info->flip_continue = FLIP_COMPLETE;
 				signal = info->signal;
+				assert(info->draw);
 				info->signal = true;
 				goto new_back;
 			}
@@ -3363,6 +3375,7 @@ skip:
 		info->type = SWAP_COMPLETE;
 		info->event_complete = func;
 		info->event_data = data;
+		assert(info->draw);
 		info->signal = true;
 
 		info->front = sna_dri2_reference_buffer(front);

commit d04e3f63f98eab02614119d59f5df6767bbbf11a
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jan 12 09:28:34 2016 +0000

    sna: Setup the GTT domain on the new cursors
    
    We should not rely on first-fault setting the domain for us.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 60bc42b..8082e9f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -657,6 +657,7 @@ static uint32_t gem_create(int fd, int size)
 static void *gem_mmap(int fd, int handle, int size)
 {
 	struct drm_i915_gem_mmap_gtt mmap_arg;
+	struct drm_i915_gem_set_domain set_domain;
 	void *ptr;
 
 	VG_CLEAR(mmap_arg);
@@ -668,6 +669,15 @@ static void *gem_mmap(int fd, int handle, int size)
 	if (ptr == MAP_FAILED)
 		return NULL;
 
+	VG_CLEAR(set_domain);
+	set_domain.handle = handle;
+	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
+	set_domain.write_domain = I915_GEM_DOMAIN_GTT;
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
+		munmap(ptr, size);
+		return NULL;
+	}
+
 	return ptr;
 }
 

commit 371219c34a54707a0d568c51defae478079fbf71
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jan 8 09:17:19 2016 +0000

    intel-virtual-output: Virtual heads are numbered from index 1
    
    When checking for VIRTUAL support on the xserver, it helps to check for
    the right name.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 6b6d977..77e6a58 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -994,14 +994,14 @@ static int check_virtual(struct display *display)
 		if (output == NULL)
 			continue;
 
-		if (strcmp(output->name, "VIRTUAL0") == 0)
+		if (strcmp(output->name, "VIRTUAL1") == 0)
 			found = 0;
 
 		XRRFreeOutputInfo(output);
 	}
 	XRRFreeScreenResources(res);
 
-	DBG(XRR, ("%s(%s): has VIRTUAL0? %d\n",
+	DBG(XRR, ("%s(%s): has VIRTUAL1? %d\n",
 		  __func__, DisplayString(display->dpy), found));
 	return found;
 }

commit 9083d2ed5876f1891727b512da57766d8d11af56
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Jan 6 14:09:40 2016 +0000

    intel-virtual-output: Print more helpful error when run on the wrong server
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index bcbcb42..6b6d977 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -977,6 +977,35 @@ out:
 	return rr_output;
 }
 
+static int check_virtual(struct display *display)
+{
+	XRRScreenResources *res;
+	int found = -ENOENT;
+	int i;
+
+	res = _XRRGetScreenResourcesCurrent(display->dpy, display->root);
+	if (res == NULL)
+		return -ENOMEM;
+
+	for (i = 0; found == -ENOENT && i < res->noutput; i++) {
+		XRROutputInfo *output;
+
+		output = XRRGetOutputInfo(display->dpy, res, res->outputs[i]);
+		if (output == NULL)
+			continue;
+
+		if (strcmp(output->name, "VIRTUAL0") == 0)
+			found = 0;
+
+		XRRFreeOutputInfo(output);
+	}
+	XRRFreeScreenResources(res);
+
+	DBG(XRR, ("%s(%s): has VIRTUAL0? %d\n",
+		  __func__, DisplayString(display->dpy), found));
+	return found;
+}
+
 static int stride_for_depth(int width, int depth)
 {
 	if (depth == 24)
@@ -3419,6 +3448,13 @@ int main(int argc, char **argv)
 		goto out;
 	}
 
+	ret = check_virtual(ctx.display);
+	if (ret) {
+		fprintf(stderr, "No VIRTUAL outputs on \"%s\".\n",
+			DisplayString(ctx.display->dpy));
+		goto out;
+	}
+
 	if (singleton) {
 		XSelectInput(ctx.display->dpy, ctx.display->root, PropertyChangeMask);
 		if (first_display_has_singleton(&ctx)) {

commit 5c735befdcc40f94bd740be9fc0df54ad53aa174
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Jan 6 10:00:19 2016 +0000

    sna/dri2: Ignore pending SwapComplete events when the window is destroyed
    
    Since we need the drawable to call DRI2SwapComplete/DRI2WakeClient, if
    the window is destroyed that becomes inoperable (as we are called late
    in the chain). Let's hope the client isn't blocked.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 33cf3d9..63c4932 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1837,20 +1837,20 @@ void sna_dri2_destroy_window(WindowPtr win)
 
 		chain = priv->chain;
 		while ((info = chain)) {
+			DBG(("%s: freeing event, pending signal? %d, pending swap? handle=%d\n",
+			     __FUNCTION__, info->signal,
+			     info->pending.bo ? info->pending.bo->handle : 0));
 			assert(info->draw == &win->drawable);
-			if (info->signal)
-				frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE);
+
 			if (info->pending.bo) {
 				assert(info->pending.bo->active_scanout > 0);
 				info->pending.bo->active_scanout--;
 
-				info->signal = true;
-				frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE);
-
 				kgem_bo_destroy(&sna->kgem, info->pending.bo);
 				info->pending.bo = NULL;
 			}
 
+			info->signal = false;
 			info->draw = NULL;
 			list_del(&info->link);
 

commit 8e987511f0f190115e2587a94922b766d4f8719a
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Jan 2 21:29:58 2016 +0000

    tools/intel-virtual-output: Propagate screen blanking
    
    When attaching to a target display, disable the builtin screen blanking
    (equivalent to xset -d :8 s off, or setting
    	Option          "BlankTime"     "0"
    	Option          "StandbyTime"   "0"
    	Option          "SuspendTime"   "0"
    	Option          "OffTime"       "0"
    in the target xorg.conf). Then listen to the ScreenSaver notify events
    on the host and forward the activations/resets to the targets. This
    should then keep all the screen blanking in sync.
    
    Reported-by: Raffael Herzog <herzog@raffael.ch>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93562
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index 9aa7d97..c18ad96 100644
--- a/configure.ac
+++ b/configure.ac
@@ -291,7 +291,7 @@ if test "x$shm" != "xyes"; then
 	tools="no"
 fi
 if test "x$tools" != "xno"; then
-	ivo_requires="xrandr xdamage xfixes xcursor xtst xrender xext x11 pixman-1"
+	ivo_requires="xrandr xdamage xfixes xcursor xtst xrender xscrnsaver xext x11 pixman-1"
 	extra_cflags=""
 
 	ignore="xinerama"
diff --git a/tools/virtual.c b/tools/virtual.c
index 7bf6ee8..bcbcb42 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -31,6 +31,7 @@
 
 #include <X11/Xlibint.h>
 #include <X11/extensions/record.h>
+#include <X11/extensions/scrnsaver.h>
 #include <X11/extensions/XShm.h>
 #if HAVE_X11_EXTENSIONS_SHMPROTO_H
 #include <X11/extensions/shmproto.h>
@@ -79,13 +80,15 @@ static int verbose;
 #define DRAW 0x8
 #define DAMAGE 0x10
 #define CURSOR 0x20
-#define POLL 0x40
+#define SCREEN 0x40
+#define POLL 0x80
 
 struct display {
 	Display *dpy;
 	struct clone *clone;
 	struct context *ctx;
 
+	int saver_event, saver_error, saver_active;
 	int damage_event, damage_error;
 	int xfixes_event, xfixes_error;
 	int rr_event, rr_error, rr_active;
@@ -98,6 +101,7 @@ struct display {
 	int width;
 	int height;
 	int depth;
+	int active;
 
 	XRenderPictFormat *root_format;
 	XRenderPictFormat *rgb16_format;
@@ -123,6 +127,13 @@ struct display {
 	int send;
 	int skip_clone;
 	int skip_frame;
+
+	struct {
+		int timeout;
+		int interval;
+		int prefer_blank;
+		int allow_exp;
+	} saver;
 };
 
 struct output {
@@ -1249,6 +1260,56 @@ static void clone_update(struct clone *clone)
 	clone->rr_update = 0;
 }
 
+static void screensaver_save(struct display *display)
+{
+	display->saver_active =
+		XScreenSaverQueryExtension(display->dpy,
+					   &display->saver_event,
+					   &display->saver_error);
+	DBG(SCREEN,
+	    ("%s screen saver active? %d [event=%d, error=%d]\n",
+	     DisplayString(display->dpy),
+	     display->saver_active,
+	     display->saver_event,
+	     display->saver_error));
+
+	XGetScreenSaver(display->dpy,
+			&display->saver.timeout,
+			&display->saver.interval,
+			&display->saver.prefer_blank,
+			&display->saver.allow_exp);
+
+	DBG(SCREEN,
+	    ("%s saving screen saver defaults: timeout=%d interval=%d prefer_blank=%d allow_exp=%d\n",
+	     DisplayString(display->dpy),
+	     display->saver.timeout,
+	     display->saver.interval,
+	     display->saver.prefer_blank,
+	     display->saver.allow_exp));
+}
+
+static void screensaver_disable(struct display *display)
+{
+	DBG(SCREEN,
+	    ("%s disabling screen saver\n", DisplayString(display->dpy)));
+
+	XSetScreenSaver(display->dpy, 0, 0, DefaultBlanking, DefaultExposures);
+	display_mark_flush(display);
+}
+
+static void screensaver_restore(struct display *display)
+{
+	DBG(SCREEN,
+	    ("%s restoring screen saver\n", DisplayString(display->dpy)));
+
+	XSetScreenSaver(display->dpy,
+			display->saver.timeout,
+			display->saver.interval,
+			display->saver.prefer_blank,
+			display->saver.allow_exp);
+	display_mark_flush(display);
+}
+
 static int context_update(struct context *ctx)
 {
 	Display *dpy = ctx->display->dpy;
@@ -1605,6 +1666,13 @@ ungrab:
 		XUngrabServer(display->dpy);
 	}
 
+	for (n = 1; n < ctx->ndisplay; n++) {
+		struct display *display = &ctx->display[n];
+
+		display->active = 0;
+		screensaver_restore(display);
+	}
+
 	ctx->active = NULL;
 	for (n = 0; n < ctx->nclone; n++) {
 		struct clone *clone = &ctx->clones[n];
@@ -1615,7 +1683,10 @@ ungrab:
 			continue;
 
 		DBG(XRR, ("%s-%s: added to active list\n",
-		     DisplayString(clone->dst.display->dpy), clone->dst.name));
+			  DisplayString(clone->dst.display->dpy), clone->dst.name));
+
+		if (clone->dst.display->active++ == 0)
+			screensaver_disable(clone->dst.display);
 
 		clone->active = ctx->active;
 		ctx->active = clone;
@@ -2396,6 +2467,8 @@ static int add_display(struct context *ctx, Display *dpy)
 	     display->shm_opcode,
 	     display->has_shm_pixmap));
 
+	screensaver_save(display);
+
 	display->rr_active = XRRQueryExtension(dpy, &display->rr_event, &display->rr_error);
 	DBG(X11, ("%s: randr_active?=%d, event=%d, error=%d\n",
 	     DisplayString(dpy),
@@ -3400,6 +3473,11 @@ int main(int argc, char **argv)
 	if (ret)
 		goto out;
 
+	if (ctx.display->saver_active)
+		XScreenSaverSelectInput(ctx.display->dpy,
+					ctx.display->root,
+					ScreenSaverNotifyMask);
+
 	if ((ctx.display->rr_event | ctx.display->rr_error) == 0) {
 		fprintf(stderr, "RandR extension not supported by %s\n", DisplayString(ctx.display->dpy));
 		ret = EINVAL;
@@ -3476,7 +3554,32 @@ int main(int argc, char **argv)
 			do {
 				XNextEvent(ctx.display->dpy, &e);
 
-				if (e.type == ctx.display->damage_event + XDamageNotify ) {
+				DBG(POLL, ("%s received event %d\n", DisplayString(ctx.display[0].dpy), e.type));
+
+				if (e.type == ctx.display->saver_event + ScreenSaverNotify) {
+					const XScreenSaverNotifyEvent *se = (const XScreenSaverNotifyEvent *)&e;
+					DBG(SCREEN,
+					    ("%s screen saver: state=%d, kind=%d, forced=%d\n",
+					     DisplayString(ctx.display->dpy),
+					     se->state, se->kind, se->forced));
+					for (i = 1; i < ctx.ndisplay; i++) {
+						struct display *display = &ctx.display[i];
+
+						if (!display->active)
+							continue;
+
+						DBG(SCREEN,
+						    ("%s %s screen saver\n",
+						     DisplayString(display->dpy),
+						     se->state == ScreenSaverOn ? "activating" : "resetting\n"));
+
+						if (se->state == ScreenSaverOn)
+							XActivateScreenSaver(display->dpy);
+						else
+							XResetScreenSaver(display->dpy);
+						XFlush(display->dpy);
+					}
+				} else if (e.type == ctx.display->damage_event + XDamageNotify) {
 					const XDamageNotifyEvent *de = (const XDamageNotifyEvent *)&e;
 					struct clone *clone;
 
@@ -3530,7 +3633,7 @@ int main(int argc, char **argv)
 
 				DBG(POLL, ("%s received event %d\n", DisplayString(ctx.display[i].dpy), e.type));
 				if (e.type == Expose) {
-					XExposeEvent *xe = (XExposeEvent *)&e;
+					const XExposeEvent *xe = (XExposeEvent *)&e;
 					struct clone *clone;
 					int damaged = 0;
 
@@ -3555,7 +3658,7 @@ int main(int argc, char **argv)
 					if (damaged)
 						context_enable_timer(&ctx);
 				} else if (ctx.display[i].rr_active && e.type == ctx.display[i].rr_event + RRNotify) {
-					XRRNotifyEvent *re = (XRRNotifyEvent *)&e;
+					const XRRNotifyEvent *re = (XRRNotifyEvent *)&e;
 
 					DBG(XRR, ("%s received RRNotify, type %d\n", DisplayString(ctx.display[i].dpy), re->subtype));
 					if (re->subtype == RRNotify_OutputChange) {

commit 082a57e6eb3b364aad681f137364a34988c4af5d
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Jan 2 21:29:58 2016 +0000

    tools/intel-virtual-output: Respond to expose events on target displays
    
    If the destination screen is exposed (for example screensavers), we need
    to redraw. So enable the ExposeEvent on the target and synthesize
    damage to any clones on that display in order to trigger a redraw.
    
    Reported-by: Raffael Herzog <herzog@raffael.ch>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=93562
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index ffda54a..7bf6ee8 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -2037,8 +2037,9 @@ static void clone_damage(struct clone *c, const XRectangle *rec)
 	if ((v = (int)rec->y + rec->height) > c->damaged.y2)
 		c->damaged.y2 = v;
 
-	DBG(DAMAGE, ("%s-%s damaged: (%d, %d), (%d, %d)\n",
+	DBG(DAMAGE, ("%s-%s damaged: +(%d,%d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
 	     DisplayString(c->dst.display->dpy), c->dst.name,
+	     rec->x, rec->y, rec->width, rec->height,
 	     c->damaged.x1, c->damaged.y1,
 	     c->damaged.x2, c->damaged.y2));
 }
@@ -2382,6 +2383,8 @@ static int add_display(struct context *ctx, Display *dpy)
 	display->depth = DefaultDepth(dpy, DefaultScreen(dpy));
 	display->visual = DefaultVisual(dpy, DefaultScreen(dpy));
 
+	XSelectInput(dpy, display->root, ExposureMask);
+
 	display->has_shm = can_use_shm(dpy, display->root,
 				       &display->shm_event,
 				       &display->shm_opcode,
@@ -3526,7 +3529,32 @@ int main(int argc, char **argv)
 				XNextEvent(ctx.display[i].dpy, &e);
 
 				DBG(POLL, ("%s received event %d\n", DisplayString(ctx.display[i].dpy), e.type));
-				if (ctx.display[i].rr_active && e.type == ctx.display[i].rr_event + RRNotify) {
+				if (e.type == Expose) {
+					XExposeEvent *xe = (XExposeEvent *)&e;
+					struct clone *clone;
+					int damaged = 0;
+
+					DBG(DAMAGE, ("%s exposed: (%d, %d)x(%d, %d)\n",
+					     DisplayString(ctx.display[i].dpy),


Reply to: