summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-06-20 11:24:43 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2016-06-20 11:58:17 +0100
commit00a3adaf43640b9aaa84b8cb98c1f2f227686689 (patch)
treee4d214be86457bc0a24500cb796d50e83a88b350
parentb617f80ca5d386c1c248bab64276a9f283173a21 (diff)
sna: Record all sprite planes reported by the kernel
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>
-rw-r--r--src/sna/sna.h4
-rw-r--r--src/sna/sna_display.c69
-rw-r--r--src/sna/sna_video_sprite.c12
3 files changed, 63 insertions, 22 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index fdfefe17..033781e1 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -611,8 +611,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 0cf2bdbf..2f54ff12 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -221,7 +221,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;
@@ -443,10 +445,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)
@@ -1253,17 +1270,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
@@ -3005,10 +3028,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;
}
@@ -3158,6 +3185,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)
{
@@ -3231,8 +3269,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;
}
}
@@ -3247,7 +3284,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
@@ -3299,8 +3335,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",
@@ -8084,6 +8120,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;
@@ -8093,8 +8130,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;
@@ -8118,12 +8157,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 1498707d..17b272ca 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;
}