diff --git a/src/sna/sna.h b/src/sna/sna.h
index 4651632..ce51fef 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -285,6 +285,7 @@ struct sna {
 		unsigned num_real_crtc;
 		unsigned num_real_output;
 		unsigned num_fake;
+		unsigned num_sprite;
 	} mode;
 
 	struct sna_dri {
@@ -442,9 +443,9 @@ static inline void sna_dri_close(struct sna *sna, ScreenPtr pScreen) { }
 #endif
 void sna_dri_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap);
 
-extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation);
+extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, XvPortPtr port, 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_to_sprite(xf86CrtcPtr crtc, XvPortPtr port);
 extern uint32_t sna_crtc_id(xf86CrtcPtr crtc);
 
 CARD32 sna_format_for_depth(int depth);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index de08cb9..2e05733 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -100,13 +100,19 @@ struct rotation {
 	uint32_t current;
 };
 
+struct sna_crtc_sprite {
+	uint32_t id;
+	struct rotation sprite_rotation;
+};
+
 struct sna_crtc {
 	struct drm_mode_modeinfo kmode;
 	int dpms_mode;
 	PixmapPtr scanout_pixmap;
 	struct kgem_bo *bo, *shadow_bo;
 	uint32_t cursor;
-	uint32_t sprite;
+	int num_sprite;
+	struct sna_crtc_sprite *sprite;
 	bool shadow;
 	bool fallback_shadow;
 	bool transform;
@@ -115,7 +121,6 @@ struct sna_crtc {
 
 	uint32_t rotation;
 	struct rotation primary_rotation;
-	struct rotation sprite_rotation;
 };
 
 struct sna_property {
@@ -200,9 +205,24 @@ int sna_crtc_to_pipe(xf86CrtcPtr crtc)
 	return to_sna_crtc(crtc)->pipe;
 }
 
-uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc)
+static int sna_sprite_num(XvPortPtr port)
 {
-	return to_sna_crtc(crtc)->sprite;
+	XvAdaptorPtr adaptor = port->pAdaptor;
+	int i;
+
+	for (i = 0; i < adaptor->nPorts; i++) {
+		if (port == &adaptor->pPorts[i])
+			return i;
+	}
+	return 0;
+}
+
+uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, XvPortPtr port)
+{
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	int num = sna_sprite_num(port);
+
+	return sna_crtc->sprite[num].id;
 }
 
 #ifndef NDEBUG
@@ -674,15 +694,18 @@ rotation_reset(struct rotation *r)
 	r->current = 0;
 }
 
-bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation)
+bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, XvPortPtr port, uint32_t rotation)
 {
+	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+	int num = sna_sprite_num(port);
+
 	DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
 	     __FUNCTION__,
-	     to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->sprite,
+	     sna_crtc->id, sna_crtc->pipe, sna_crtc->sprite[num].id,
 	     rotation));
 
 	return rotation_set(to_sna(crtc->scrn),
-			    &to_sna_crtc(crtc)->sprite_rotation,
+			    &sna_crtc->sprite[num].sprite_rotation,
 			    rotation);
 }
 
@@ -1717,6 +1740,7 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
 	sna_crtc_hide_cursor(crtc);
 	gem_close(to_sna(crtc->scrn)->kgem.fd, sna_crtc->cursor);
 
+	free(sna_crtc->sprite);
 	free(sna_crtc);
 	crtc->driver_private = NULL;
 }
@@ -1750,32 +1774,39 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = {
 #endif
 };
 
-static int
-sna_crtc_find_sprite(struct sna *sna, int pipe)
+static void
+sna_crtc_find_sprite(struct sna *sna, struct sna_crtc *sna_crtc, int pipe)
 {
 #ifdef DRM_IOCTL_MODE_GETPLANERESOURCES
 	struct drm_mode_get_plane_res r;
-	uint32_t *planes, id = 0;
+	uint32_t *planes, *id;
 	int i;
 
 	VG_CLEAR(r);
 	r.count_planes = 0;
 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &r))
-		return 0;
+		return;
 
 	if (!r.count_planes)
-		return 0;
+		return;
 
 	planes = malloc(sizeof(uint32_t)*r.count_planes);
-	if (planes == NULL)
-		return 0;
+	id = malloc(sizeof(uint32_t)*r.count_planes);
+	if (planes == NULL || id == NULL)
+		return;
 
 	r.plane_id_ptr = (uintptr_t)planes;
 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &r))
 		r.count_planes = 0;
 
+	if (!r.count_planes)
+		return;
+
+	sna->mode.num_sprite = r.count_planes;
+
 	VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes));
 
+	sna_crtc->num_sprite = 0;
 	for (i = 0; i < r.count_planes; i++) {
 		struct drm_mode_get_plane p;
 
@@ -1784,35 +1815,54 @@ sna_crtc_find_sprite(struct sna *sna, int pipe)
 		p.count_format_types = 0;
 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPLANE, &p) == 0) {
 			if (p.possible_crtcs & (1 << pipe)) {
-				id = p.plane_id;
-				break;
+				id[sna_crtc->num_sprite++] = p.plane_id;
+				continue;
 			}
 		}
 	}
+
+	sna_crtc->sprite = malloc(sizeof(struct sna_crtc_sprite)*sna_crtc->num_sprite);
+	if (sna_crtc->sprite == NULL) {
+		free(planes);
+		free(id);
+		return;
+	}
+
+	for (i = 0; i < sna_crtc->num_sprite; i++)
+		sna_crtc->sprite[i].id = id[i];
+
 	free(planes);
+	free(id);
 
-	assert(id);
-	return id;
+	return;
 #else
-	return 0;
+	return;
 #endif
 }
 
 static void
 sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc)
 {
+	int i;
 	sna_crtc->rotation = RR_Rotate_0;
 	sna_crtc->primary_rotation.supported = RR_Rotate_0;
 	sna_crtc->primary_rotation.current = RR_Rotate_0;
-	sna_crtc->sprite_rotation = sna_crtc->primary_rotation;
 
 	rotation_init(sna, &sna_crtc->primary_rotation, sna_crtc->id, LOCAL_MODE_OBJECT_CRTC);
-	rotation_init(sna, &sna_crtc->sprite_rotation, sna_crtc->sprite, LOCAL_MODE_OBJECT_PLANE);
 
-	DBG(("%s: CRTC:%d [pipe=%d], primary: supported-rotations=%x, current-rotation=%x, sprite: supported-rotations=%x, current-rotation=%x\n",
+	DBG(("%s: CRTC:%d [pipe=%d], primary: supported-rotations=%x, current-rotation=%x\n",
 	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe,
-	     sna_crtc->primary_rotation.supported, sna_crtc->primary_rotation.current,
-	     sna_crtc->sprite_rotation.supported, sna_crtc->sprite_rotation.current));
+	     sna_crtc->primary_rotation.supported, sna_crtc->primary_rotation.current));
+
+	for (i = 0; i < sna_crtc->num_sprite; i++) {
+		sna_crtc->sprite[i].sprite_rotation = sna_crtc->primary_rotation;
+		rotation_init(sna, &sna_crtc->sprite[i].sprite_rotation, sna_crtc->sprite[i].id,
+			      LOCAL_MODE_OBJECT_PLANE);
+		DBG(("%s: CRTC:%d [pipe=%d], sprite[%d]: supported-rotations=%x, current-rotation=%x\n",
+		     __FUNCTION__, sna_crtc->id, sna_crtc->pipe, i,
+		     sna_crtc->sprite[i].sprite_rotation.supported,
+		     sna_crtc->sprite[i].sprite_rotation.current));
+	}
 }
 
 static bool
@@ -1842,16 +1892,18 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 		return false;
 	}
 	sna_crtc->pipe = get_pipe.pipe;
-	sna_crtc->sprite = sna_crtc_find_sprite(sna, sna_crtc->pipe);
+	sna_crtc_find_sprite(sna, sna_crtc, sna_crtc->pipe);
 
 	if (xf86IsEntityShared(scrn->entityList[0]) &&
 	    scrn->confScreen->device->screen != sna_crtc->pipe) {
+		free(sna_crtc->sprite);
 		free(sna_crtc);
 		return true;
 	}
 
 	crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs);
 	if (crtc == NULL) {
+		free(sna_crtc->sprite);
 		free(sna_crtc);
 		return false;
 	}
@@ -1860,6 +1912,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 				      sna->mode.cursor_width*sna->mode.cursor_height*4);
 	if (!sna_crtc->cursor) {
 		xf86CrtcDestroy(crtc);
+		free(sna_crtc->sprite);
 		free(sna_crtc);
 		return false;
 	}
@@ -4093,7 +4146,8 @@ void sna_mode_reset(struct sna *sna)
 
 		/* Force the rotation property to be reset on next use */
 		rotation_reset(&sna_crtc->primary_rotation);
-		rotation_reset(&sna_crtc->sprite_rotation);
+	        for (int j = 0; j < sna_crtc->num_sprite; j++)
+			rotation_reset(&sna_crtc->sprite[i].sprite_rotation);
 	}
 
 	for (i = 0; i < config->num_output; i++) {
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index f4dcb82..2d6794a 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -195,6 +195,7 @@ update_dst_box_to_crtc_coords(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox)
 
 static bool
 sna_video_sprite_show(struct sna *sna,
+		      XvPortPtr port,
 		      struct sna_video *video,
 		      struct sna_video_frame *frame,
 		      xf86CrtcPtr crtc,
@@ -205,7 +206,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, port);
 
 	update_dst_box_to_crtc_coords(sna, crtc, dstBox);
 	if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
@@ -383,13 +384,13 @@ static int sna_video_sprite_put_image(ClientPtr client,
 				   &clip))
 		goto invisible;
 
-	if (!crtc || sna_crtc_to_sprite(crtc) == 0)
+	if (!crtc || sna_crtc_to_sprite(crtc, port) == 0)
 		goto invisible;
 
 	/* if sprite can't handle rotation natively, store it for the copy func */
 	video->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, port, crtc->rotation)) {
+		sna_crtc_set_sprite_rotation(crtc, port, RR_Rotate_0);
 		video->rotation = crtc->rotation;
 	}
 
@@ -429,7 +430,7 @@ static int sna_video_sprite_put_image(ClientPtr client,
 	}
 
 	ret = Success;
-	if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst_box)) {
+	if (!sna_video_sprite_show(sna, port, video, &frame, crtc, &dst_box)) {
 		DBG(("%s: failed to show video frame\n", __FUNCTION__));
 		ret = BadAlloc;
 	} else {
@@ -525,7 +526,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 	XvAdaptorPtr adaptor;
 	struct drm_mode_get_plane_res r;
 	struct sna_video *video;
-	XvPortPtr port;
+	int sprite_per_crtc, i;
 
 	if (sna->flags & SNA_IS_HOSTED)
 		return;
@@ -542,11 +543,13 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 	if (!adaptor)
 		return;
 
-	video = calloc(1, sizeof(*video));
-	port = calloc(1, sizeof(*port));
-	if (video == NULL || port == NULL) {
+	sprite_per_crtc = sna->mode.num_sprite / sna->mode.kmode->count_crtcs;
+
+	video = calloc(sprite_per_crtc, sizeof(struct sna_video));
+	adaptor->pPorts = calloc(sprite_per_crtc, sizeof(XvPortRec));
+	if (video == NULL || adaptor->pPorts == NULL) {
 		free(video);
-		free(port);
+		free(adaptor->pPorts);
 		sna->xv.num_adaptors--;
 		return;
 	}
@@ -586,35 +589,41 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 	adaptor->ddPutImage = sna_video_sprite_put_image;
 	adaptor->ddQueryImageAttributes = sna_video_sprite_query;
 
-	adaptor->nPorts = 1;
-	adaptor->pPorts = port;
-
-	adaptor->base_id = port->id = FakeClientID(0);
-	AddResource(port->id, XvGetRTPort(), port);
-	port->pAdaptor = adaptor;
-	port->pNotify =  NULL;
-	port->pDraw =  NULL;
-	port->client =  NULL;
-	port->grab.client =  NULL;
-	port->time = currentTime;
-	port->devPriv.ptr = video;
-
-	video->sna = sna;
-	video->alignment = 64;
-	video->color_key = sna_video_sprite_color_key(sna);
-	video->color_key_changed = true;
-	video->brightness = -19;	/* (255/219) * -16 */
-	video->contrast = 75;	/* 255/219 * 64 */
-	video->saturation = 146;	/* 128/112 * 128 */
-	video->desired_crtc = NULL;
-	video->gamma5 = 0xc0c0c0;
-	video->gamma4 = 0x808080;
-	video->gamma3 = 0x404040;
-	video->gamma2 = 0x202020;
-	video->gamma1 = 0x101010;
-	video->gamma0 = 0x080808;
-	video->rotation = RR_Rotate_0;
-	RegionNull(&video->clip);
+	for (i = 0; i < sprite_per_crtc; i++) {
+		struct sna_video *v = &video[i];
+		XvPortPtr port = &adaptor->pPorts[i];
+
+		port->id = FakeClientID(0);
+		AddResource(port->id, XvGetRTPort(), port);
+
+		port->pAdaptor = adaptor;
+		port->pNotify =  NULL;
+		port->pDraw =  NULL;
+		port->client =  NULL;
+		port->grab.client =  NULL;
+		port->time = currentTime;
+		port->devPriv.ptr = v;
+
+		v->sna = sna;
+		v->alignment = 64;
+		v->color_key = sna_video_sprite_color_key(sna);
+		v->color_key_changed = true;
+		v->brightness = -19;	/* (255/219) * -16 */
+		v->contrast = 75;	/* 255/219 * 64 */
+		v->saturation = 146;	/* 128/112 * 128 */
+		v->desired_crtc = NULL;
+		v->gamma5 = 0xc0c0c0;
+		v->gamma4 = 0x808080;
+		v->gamma3 = 0x404040;
+		v->gamma2 = 0x202020;
+		v->gamma1 = 0x101010;
+		v->gamma0 = 0x080808;
+		v->rotation = RR_Rotate_0;
+		RegionNull(&v->clip);
+	}
+
+	adaptor->base_id = adaptor->pPorts[0].id;
+	adaptor->nPorts = sprite_per_crtc;
 
 	xvColorKey = MAKE_ATOM("XV_COLORKEY");
 	xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
