File U_01-sna-Record-all-sprite-planes-reported-by-the-kernel.patch of Package xf86-video-intel.6276

From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Mon Jun 20 11:24:43 2016 +0100
Subject: [PATCH 1/5]sna: Record all sprite planes reported by the kernel
Patch-mainline: 00a3adaf43640b9aaa84b8cb98c1f2f227686689
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-intel
References: boo#984747
Signed-off-by: Max Staudt <mstaudt@suse.de>

In the following patches, we wish to expose them all to userspace. First
we have to enumerate them, and make sure they all behave as expected.

Based on a patch by Michael Hadley <michaelx.hadley@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 src/sna/sna.h              |  4 +--
 src/sna/sna_display.c      | 69 ++++++++++++++++++++++++++++++++++++----------
 src/sna/sna_video_sprite.c | 12 ++++----
 3 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 664308f..78d3e8d 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -610,8 +610,8 @@ static inline void sna_present_vblank_handler(struct drm_event_vblank *event) {
 static inline void sna_present_cancel_flip(struct sna *sna) { }
 #endif

-extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation);
-extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc);
+extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation);
+extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx);
 extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc);

 #define CRTC_VBLANK 0x3
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 867a10b..319e66e 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -220,7 +220,9 @@ struct sna_crtc {
 			uint32_t supported;
 			uint32_t current;
 		} rotation;
-	} primary, sprite;
+		struct list link;
+	} primary;
+	struct list sprites;

 	uint32_t mode_serial, flip_serial;

@@ -442,10 +444,25 @@ static inline uint32_t fb_id(struct kgem_bo *bo)
 	return bo->delta;
 }

-uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc)
+static struct plane *lookup_sprite(struct sna_crtc *crtc, unsigned idx)
 {
+	struct plane *sprite;
+
+	list_for_each_entry(sprite, &crtc->sprites, link)
+		if (idx-- == 0)
+			return sprite;
+
+	return NULL;
+}
+
+uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx)
+{
+	struct plane *sprite;
+
 	assert(to_sna_crtc(crtc));
-	return to_sna_crtc(crtc)->sprite.id;
+
+	sprite = lookup_sprite(to_sna_crtc(crtc), idx);
+	return sprite ? sprite->id : 0;
 }

 bool sna_crtc_is_transformed(xf86CrtcPtr crtc)
@@ -1243,17 +1260,23 @@ rotation_reset(struct plane *p)
 	p->rotation.current = 0;
 }

-bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation)
+bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc,
+				  unsigned idx,
+				  uint32_t rotation)
 {
+	struct plane *sprite;
 	assert(to_sna_crtc(crtc));
 	DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
 	     __FUNCTION__,
 	     sna_crtc_id(crtc), sna_crtc_pipe(crtc),
 	     to_sna_crtc(crtc)->sprite.id, rotation));

-	return rotation_set(to_sna(crtc->scrn),
-			    &to_sna_crtc(crtc)->sprite,
-			    rotation_reduce(&to_sna_crtc(crtc)->sprite, rotation));
+	sprite = lookup_sprite(to_sna_crtc(crtc), idx);
+	if (!sprite)
+		return false;
+
+	return rotation_set(to_sna(crtc->scrn), sprite,
+			    rotation_reduce(sprite, rotation));
 }

 #if HAS_DEBUG_FULL
@@ -2991,10 +3014,14 @@ static void
 sna_crtc_destroy(xf86CrtcPtr crtc)
 {
 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	struct plane *sprite, *sn;

 	if (sna_crtc == NULL)
 		return;

+	list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
+		free(sprite);
+
 	free(sna_crtc);
 	crtc->driver_private = NULL;
 }
@@ -3144,6 +3171,17 @@ static int plane_details(struct sna *sna, struct plane *p)
 	return type;
 }

+static void add_sprite_plane(struct sna_crtc *crtc,
+			     struct plane *details)
+{
+	struct plane *sprite = malloc(sizeof(*sprite));
+	if (!sprite)
+		return;
+
+	memcpy(sprite, details, sizeof(*sprite));
+	list_add(&sprite->link, &crtc->sprites);
+}
+
 static void
 sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
 {
@@ -3217,8 +3255,7 @@ sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
 			break;

 		case DRM_PLANE_TYPE_OVERLAY:
-			if (crtc->sprite.id == 0)
-				crtc->sprite = details;
+			add_sprite_plane(crtc, &details);
 			break;
 		}
 	}
@@ -3233,7 +3270,6 @@ sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
 	crtc->rotation = RR_Rotate_0;
 	crtc->primary.rotation.supported = RR_Rotate_0;
 	crtc->primary.rotation.current = RR_Rotate_0;
-	crtc->sprite.rotation = crtc->primary.rotation;
 }

 static void
@@ -3285,8 +3321,8 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
 		return true;
 	}

+	list_init(&sna_crtc->sprites);
 	sna_crtc_init__rotation(sna, sna_crtc);
-
 	sna_crtc_find_planes(sna, sna_crtc);

 	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x, sprite id=%x: supported-rotations=%x, current-rotation=%x\n",
@@ -8011,6 +8047,7 @@ static bool
 sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
 {
 	struct local_mode_set_plane s;
+	struct plane *plane;

 	if (crtc->primary.id == 0)
 		return false;
@@ -8020,8 +8057,10 @@ sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 		return false;

-	s.plane_id = crtc->sprite.id;
-	(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
+	list_for_each_entry(plane, &crtc->sprites, link) {
+		s.plane_id = plane->id;
+		(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
+	}

 	__sna_crtc_disable(sna, crtc);
 	return true;
@@ -8045,12 +8084,14 @@ void sna_mode_reset(struct sna *sna)

 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
 		struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
+		struct plane *plane;

 		assert(sna_crtc != NULL);

 		/* Force the rotation property to be reset on next use */
 		rotation_reset(&sna_crtc->primary);
-		rotation_reset(&sna_crtc->sprite);
+		list_for_each_entry(plane, &sna_crtc->sprites, link)
+			rotation_reset(plane);
 	}

 	/* VT switching, likely to be fbcon so make the backlight usable */
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 1498707..17b272c 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -91,7 +91,7 @@ static int sna_video_sprite_stop(ddStopVideo_ARGS)
 			continue;

 		memset(&s, 0, sizeof(s));
-		s.plane_id = sna_crtc_to_sprite(crtc);
+		s.plane_id = sna_crtc_to_sprite(crtc, 0);
 		if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 			xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
 				   "failed to disable plane\n");
@@ -224,7 +224,7 @@ sna_video_sprite_show(struct sna *sna,
 	/* XXX handle video spanning multiple CRTC */

 	VG_CLEAR(s);
-	s.plane_id = sna_crtc_to_sprite(crtc);
+	s.plane_id = sna_crtc_to_sprite(crtc, 0);

 #define DRM_I915_SET_SPRITE_COLORKEY 0x2b
 #define LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct local_intel_sprite_colorkey)
@@ -422,7 +422,7 @@ off:
 			if (video->bo[pipe]) {
 				struct local_mode_set_plane s;
 				memset(&s, 0, sizeof(s));
-				s.plane_id = sna_crtc_to_sprite(crtc);
+				s.plane_id = sna_crtc_to_sprite(crtc, 0);
 				if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
 					xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
 						   "failed to disable plane\n");
@@ -461,8 +461,8 @@ off:

 		/* if sprite can't handle rotation natively, store it for the copy func */
 		rotation = RR_Rotate_0;
-		if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) {
-			sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0);
+		if (!sna_crtc_set_sprite_rotation(crtc, 0, crtc->rotation)) {
+			sna_crtc_set_sprite_rotation(crtc, 0, RR_Rotate_0);
 			rotation = crtc->rotation;
 		}
 		sna_video_frame_set_rotation(video, &frame, rotation);
@@ -662,7 +662,7 @@ static bool sna_video_has_sprites(struct sna *sna)
 		return false;

 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
-		if (!sna_crtc_to_sprite(config->crtc[i])) {
+		if (!sna_crtc_to_sprite(config->crtc[i], 0)) {
 			DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i])));
 			return false;
 		}
openSUSE Build Service is sponsored by