debian/changelog | 11 debian/patches/01-support-native-rotations.diff | 269 ++++ debian/patches/02-extend-native-rotation-to-sprites.diff | 407 +++++++ debian/patches/03-reorganise-native-rotation.diff | 245 ++++ debian/patches/04-inherit-native-rotation.diff | 21 debian/patches/05-clear-transform-on-disable.diff | 33 debian/patches/06-set-color-key-once.diff | 79 + debian/patches/07-show-sprites-on-all-outputs.diff | 730 ++++++++++++ debian/patches/08-rewrite-rotation-universal-planes.diff | 856 +++++++++++++++ debian/patches/09-reduce-reflections-onto-rotations.diff | 90 + debian/patches/10-handle-rotated-slaves.diff | 410 +++++++ debian/patches/series | 11 12 files changed, 3158 insertions(+), 4 deletions(-)
New commits: commit dc762db1e2d7b45b080889131fb362aead003e87 Author: Maarten Lankhorst <maarten.lankho...@ubuntu.com> Date: Wed Oct 29 16:14:32 2014 +0100 add patch series for rotation support diff --git a/debian/changelog b/debian/changelog index 7fa7a26..dfa91b4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,9 @@ -xserver-xorg-video-intel (2:2.99.910-0ubuntu1.2) UNRELEASED; urgency=low +xserver-xorg-video-intel (2:2.99.910-0ubuntu1.2) UNRELEASED; urgency=medium * Fix black screen with SNA. (LP: #1365695) + * Prevent crash when using SNA with fglrx. + - disable-outputs-when-slaved.patch + * Backport support for rotation with SNA. (LP: #1386620) -- Maarten Lankhorst <maarten.lankho...@ubuntu.com> Mon, 22 Sep 2014 11:26:22 +0200 diff --git a/debian/patches/01-support-native-rotations.diff b/debian/patches/01-support-native-rotations.diff new file mode 100644 index 0000000..99b5144 --- /dev/null +++ b/debian/patches/01-support-native-rotations.diff @@ -0,0 +1,269 @@ +commit 607737cc47788e2a8896fddfece907a3cfb24f7f +Author: Chris Wilson <ch...@chris-wilson.co.uk> +Date: Wed Feb 12 11:33:45 2014 +0000 + + sna: Support native primary plane rotations + + Use the display hardware for simple rotations, when exported through the + rotation property on the CRTC. + + As the kernel support is not yet merged upstream, the feature is hidden + behind --enable-rotation. + + Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> + +diff --git a/configure.ac b/configure.ac +index ea7473e..4f73ba4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -578,6 +578,17 @@ if test "x$CREATE2" = "xyes"; then + xp_msg="$xp_msg create2" + fi + ++AC_ARG_ENABLE(rotation, ++ AS_HELP_STRING([--enable-rotation], ++ [Enable use of native rotations (experimental) [default=no]]), ++ [ROTATION="$enableval"], ++ [ROTATION="no"]) ++AM_CONDITIONAL(USE_ROTATION, test "x$ROTATION" = "xyes") ++if test "x$ROTATION" = "xyes"; then ++ AC_DEFINE(USE_ROTATION,1,[Assume "rotation" support]) ++ xp_msg="$xp_msg rotation" ++fi ++ + AC_ARG_ENABLE(userptr, + AS_HELP_STRING([--enable-userptr], + [Enable use of userptr (experimental) [default=no]]), +diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c +index a89d31a..c5ccaac 100644 +--- a/src/sna/gen5_render.c ++++ b/src/sna/gen5_render.c +@@ -1537,6 +1537,25 @@ gen5_composite_picture(struct sna *sna, + return sna_render_picture_extract(sna, picture, channel, + x, y, w, h, dst_x, dst_y); + ++ DBG(("%s: pixmap, repeat=%d, filter=%d, transform?=%d [affine? %d], format=%08x\n", ++ __FUNCTION__, ++ channel->repeat, channel->filter, ++ channel->transform != NULL, channel->is_affine, ++ channel->pict_format)); ++ if (channel->transform) { ++ DBG(("%s: transform=[%f %f %f, %f %f %f, %f %f %f]\n", ++ __FUNCTION__, ++ channel->transform->matrix[0][0] / 65536., ++ channel->transform->matrix[0][1] / 65536., ++ channel->transform->matrix[0][2] / 65536., ++ channel->transform->matrix[1][0] / 65536., ++ channel->transform->matrix[1][1] / 65536., ++ channel->transform->matrix[1][2] / 65536., ++ channel->transform->matrix[2][0] / 65536., ++ channel->transform->matrix[2][1] / 65536., ++ channel->transform->matrix[2][2] / 65536.)); ++ } ++ + return sna_render_pixmap_bo(sna, channel, pixmap, + x, y, w, h, dst_x, dst_y); + } +diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c +index a6e6f68..9b05f74 100644 +--- a/src/sna/sna_display.c ++++ b/src/sna/sna_display.c +@@ -105,6 +105,10 @@ struct sna_crtc { + uint8_t id; + uint8_t pipe; + uint8_t plane; ++ ++ uint32_t rotation_id; ++ uint32_t supported_rotations; ++ uint32_t rotation, last_rotation; + }; + + struct sna_property { +@@ -842,10 +846,35 @@ sna_crtc_apply(xf86CrtcPtr crtc) + int output_count = 0; + int i; + +- DBG(("%s\n", __FUNCTION__)); ++ DBG(("%s CRTC:%d [pipe=%d]\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe)); + + assert(config->num_output < ARRAY_SIZE(output_ids)); + ++ if (sna_crtc->rotation != sna_crtc->last_rotation) { ++ assert(sna_crtc->rotation_id); ++ ++ DBG(("%s: disabling CRTC:%d [pipe=%d] before changing rotation from %x to %x\n", ++ __FUNCTION__, sna_crtc->id, sna_crtc->pipe, ++ sna_crtc->last_rotation, sna_crtc->rotation)); ++ ++ memset(&arg, 0, sizeof(arg)); ++ arg.crtc_id = sna_crtc->id; ++ (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); ++ ++ if (drmModeObjectSetProperty(sna->kgem.fd, sna_crtc->id, ++ DRM_MODE_OBJECT_CRTC, ++ sna_crtc->rotation_id, ++ sna_crtc->rotation)) { ++ ERR(("%s: set-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n", ++ __FUNCTION__, sna_crtc->rotation_id, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno)); ++ return false; ++ } ++ ++ sna_crtc->last_rotation = sna_crtc->rotation; ++ DBG(("%s: CRTC:%d [pipe=%d] rotation set to %x\n", ++ __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation)); ++ } ++ + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + +@@ -1101,6 +1130,15 @@ sna_crtc_disable(xf86CrtcPtr crtc) + arg.crtc_id = sna_crtc->id; + (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); + ++ if (sna_crtc->last_rotation != RR_Rotate_0) { ++ assert(sna_crtc->rotation_id); ++ (void)drmModeObjectSetProperty(sna->kgem.fd, sna_crtc->id, ++ DRM_MODE_OBJECT_CRTC, ++ sna_crtc->rotation_id, ++ RR_Rotate_0); ++ sna_crtc->last_rotation = RR_Rotate_0; ++ } ++ + sna_crtc_disable_shadow(sna, sna_crtc); + + if (sna_crtc->bo) { +@@ -1333,8 +1371,19 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc) + &crtc_to_fb, + &f_crtc_to_fb, + &f_fb_to_crtc)) { +- DBG(("%s: RandR transform present\n", __FUNCTION__)); +- return true; ++ bool needs_transform = true; ++ DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n", ++ __FUNCTION__, crtc->rotation, to_sna_crtc(crtc)->supported_rotations, ++ !!(crtc->rotation & to_sna_crtc(crtc)->supported_rotations))); ++ if (to_sna_crtc(crtc)->supported_rotations & crtc->rotation) ++ needs_transform = RRTransformCompute(crtc->x, crtc->y, ++ crtc->mode.HDisplay, crtc->mode.VDisplay, ++ RR_Rotate_0, transform, ++ NULL, NULL, NULL); ++ if (needs_transform) { ++ DBG(("%s: RandR transform present\n", __FUNCTION__)); ++ return true; ++ } + } + + /* And finally check that it is entirely visible */ +@@ -1365,6 +1414,8 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) + struct kgem_bo *bo; + + sna_crtc->transform = false; ++ sna_crtc->rotation = RR_Rotate_0; ++ + if (sna_crtc->scanout_pixmap) { + DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__)); + +@@ -1468,6 +1519,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) + return NULL; + + assert(!sna_crtc->shadow); ++ sna_crtc->rotation = crtc->rotation; + return kgem_bo_reference(bo); + } + } +@@ -1913,6 +1965,77 @@ sna_crtc_find_plane(struct sna *sna, int pipe) + #endif + } + ++static void ++sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc) ++{ ++ drmModeObjectPropertiesPtr props; ++ ++ sna_crtc->supported_rotations = RR_Rotate_0; ++ sna_crtc->rotation = sna_crtc->last_rotation = RR_Rotate_0; ++ ++#if USE_ROTATION ++ props = drmModeObjectGetProperties(sna->kgem.fd, ++ sna_crtc->id, ++ DRM_MODE_OBJECT_CRTC); ++ if (props) { ++ int i, j; ++ ++ DBG(("%s: CRTC:%d has %d props\n", __FUNCTION__, sna_crtc->id, props->count_props)); ++ ++ for (i = 0; i < props->count_props; i++) { ++ struct drm_mode_get_property prop; ++ struct drm_mode_property_enum *enums; ++ ++ memset(&prop, 0, sizeof(prop)); ++ prop.prop_id = props->props[i]; ++ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) ++ continue; ++ ++ DBG(("%s: prop[%d] .id=%d, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, ++ props->props[i], prop.name, prop.flags, props->prop_values[i])); ++ if ((prop.flags & DRM_MODE_PROP_BITMASK) == 0) ++ continue; ++ ++ if (strcmp(prop.name, "rotation")) ++ continue; ++ ++ /* Note that this property only controls the primary ++ * plane, not the cursor or sprite planes. ++ */ ++ sna_crtc->rotation_id = props->props[i]; ++ sna_crtc->rotation = sna_crtc->last_rotation = props->prop_values[i]; ++ ++ DBG(("%s: found rotation property .id=%d, num_enums=%d\n", ++ __FUNCTION__, prop.prop_id, prop.count_enum_blobs)); ++ enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); ++ if (enums != NULL) { ++ prop.count_values = 0; ++ prop.enum_blob_ptr = (uintptr_t)enums; ++ ++ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { ++ /* XXX we assume that the mapping between kernel enum and ++ * RandR remains fixed for our lifetimes. ++ */ ++ for (j = 0; j < prop.count_enum_blobs; j++) { ++ DBG(("%s: CRTC:%d rotation[%d] = %s [%x]\n", __FUNCTION__, sna_crtc->id, j, ++ enums[j].name, enums[j].value)); ++ sna_crtc->supported_rotations |= 1 << enums[j].value; ++ } ++ } ++ ++ free(enums); ++ } ++ ++ break; ++ } ++ ++ drmModeFreeObjectProperties(props); ++ } ++#endif ++ DBG(("%s: CRTC:%d [pipe=%d], supported-rotations=%x, current-rotation=%x\n", ++ __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->supported_rotations, sna_crtc->last_rotation)); ++} ++ + static bool + sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num) + { +@@ -1921,7 +2044,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num) + struct sna_crtc *sna_crtc; + struct drm_i915_get_pipe_from_crtc_id get_pipe; + +- DBG(("%s\n", __FUNCTION__)); ++ DBG(("%s(%d)\n", __FUNCTION__, num)); + + sna_crtc = calloc(sizeof(struct sna_crtc), 1); + if (sna_crtc == NULL) +@@ -1963,6 +2086,8 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num) + DBG(("%s: created handle=%d for cursor on CRTC:%d\n", + __FUNCTION__, sna_crtc->cursor, sna_crtc->id)); + ++ sna_crtc_init__rotation(sna, sna_crtc); ++ + crtc->driver_private = sna_crtc; + DBG(("%s: attached crtc[%d] id=%d, pipe=%d\n", + __FUNCTION__, num, sna_crtc->id, sna_crtc->pipe)); diff --git a/debian/patches/02-extend-native-rotation-to-sprites.diff b/debian/patches/02-extend-native-rotation-to-sprites.diff new file mode 100644 index 0000000..87ab2d5 --- /dev/null +++ b/debian/patches/02-extend-native-rotation-to-sprites.diff @@ -0,0 +1,407 @@ +commit 135da294106f7158bb68eeeb9e6c171bcddd94f3 +Author: Chris Wilson <ch...@chris-wilson.co.uk> +Date: Thu Feb 13 11:58:15 2014 +0000 + + sna: Extend native rotation support to sprites + + The sprite plane can be independently rotated to the CRTC primary plane. + To rotate the sprite plane, we just set a property on the plane similar + to how we rotate the CRTC, so we can refactor them together to use the + same routines. + + Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> + +diff --git a/src/sna/sna.h b/src/sna/sna.h +index 7833095..7dc5067 100644 +--- a/src/sna/sna.h ++++ b/src/sna/sna.h +@@ -439,8 +439,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 int sna_crtc_to_pipe(xf86CrtcPtr crtc); +-extern uint32_t sna_crtc_to_plane(xf86CrtcPtr crtc); ++extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc); + 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 5c0a5a3..e123f48 100644 +--- a/src/sna/sna_display.c ++++ b/src/sna/sna_display.c +@@ -93,22 +93,29 @@ union compat_mode_get_connector{ + + extern XF86ConfigPtr xf86configptr; + ++struct rotation { ++ uint32_t obj_id, obj_type; ++ uint32_t prop_id; ++ uint32_t supported; ++ uint32_t current; ++}; ++ + 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; + bool shadow; + bool fallback_shadow; + bool transform; + uint8_t id; + uint8_t pipe; +- uint8_t plane; + +- uint32_t rotation_id; +- uint32_t supported_rotations; +- uint32_t rotation, last_rotation; ++ uint32_t rotation; ++ struct rotation primary_rotation; ++ struct rotation sprite_rotation; + }; + + struct sna_property { +@@ -199,9 +206,9 @@ int sna_crtc_to_pipe(xf86CrtcPtr crtc) + return to_sna_crtc(crtc)->pipe; + } + +-uint32_t sna_crtc_to_plane(xf86CrtcPtr crtc) ++uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc) + { +- return to_sna_crtc(crtc)->plane; ++ return to_sna_crtc(crtc)->sprite; + } + + #ifndef NDEBUG +@@ -862,6 +869,43 @@ sna_crtc_force_outputs_off(xf86CrtcPtr crtc) + } + + static bool ++rotation_set(struct sna *sna, struct rotation *r, uint32_t desired) ++{ ++ if (desired == r->current) ++ return true; ++ ++ if ((desired & r->supported) == 0) ++ return false; ++ ++ DBG(("%s: obj=%d, type=%u set-rotation=%x\n", ++ __FUNCTION__, r->obj_id, r->obj_type, desired)); ++ ++ assert(r->obj_id); ++ assert(r->obj_type); ++ assert(r->prop_id); ++ ++ if (drmModeObjectSetProperty(sna->kgem.fd, ++ r->obj_id, r->obj_type, ++ r->prop_id, desired)) ++ return false; ++ ++ r->current = desired; ++ return true; ++} ++ ++bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation) ++{ ++ 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, ++ rotation)); ++ ++ return rotation_set(to_sna(crtc->scrn), ++ &to_sna_crtc(crtc)->sprite_rotation, ++ rotation); ++} ++ ++static bool + sna_crtc_apply(xf86CrtcPtr crtc) + { + struct sna *sna = to_sna(crtc->scrn); +@@ -876,30 +920,13 @@ sna_crtc_apply(xf86CrtcPtr crtc) + + assert(config->num_output < ARRAY_SIZE(output_ids)); + +- if (sna_crtc->rotation != sna_crtc->last_rotation) { +- assert(sna_crtc->rotation_id); +- +- DBG(("%s: disabling CRTC:%d [pipe=%d] before changing rotation from %x to %x\n", +- __FUNCTION__, sna_crtc->id, sna_crtc->pipe, +- sna_crtc->last_rotation, sna_crtc->rotation)); +- +- memset(&arg, 0, sizeof(arg)); +- arg.crtc_id = sna_crtc->id; +- (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); +- +- if (drmModeObjectSetProperty(sna->kgem.fd, sna_crtc->id, +- DRM_MODE_OBJECT_CRTC, +- sna_crtc->rotation_id, +- sna_crtc->rotation)) { +- ERR(("%s: set-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n", +- __FUNCTION__, sna_crtc->rotation_id, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno)); +- return false; +- } +- +- sna_crtc->last_rotation = sna_crtc->rotation; +- DBG(("%s: CRTC:%d [pipe=%d] rotation set to %x\n", +- __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation)); ++ if (!rotation_set(sna, &sna_crtc->primary_rotation, 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_id, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno)); ++ return false; + } ++ DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n", ++ __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation)); + + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; +@@ -1156,14 +1183,7 @@ sna_crtc_disable(xf86CrtcPtr crtc) + arg.crtc_id = sna_crtc->id; + (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); + +- if (sna_crtc->last_rotation != RR_Rotate_0) { +- assert(sna_crtc->rotation_id); +- (void)drmModeObjectSetProperty(sna->kgem.fd, sna_crtc->id, +- DRM_MODE_OBJECT_CRTC, +- sna_crtc->rotation_id, +- RR_Rotate_0); +- sna_crtc->last_rotation = RR_Rotate_0; +- } ++ rotation_set(sna, &sna_crtc->primary_rotation, RR_Rotate_0); + + sna_crtc_disable_shadow(sna, sna_crtc); + +@@ -1399,9 +1419,9 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc) + &f_fb_to_crtc)) { + bool needs_transform = true; + DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n", +- __FUNCTION__, crtc->rotation, to_sna_crtc(crtc)->supported_rotations, +- !!(crtc->rotation & to_sna_crtc(crtc)->supported_rotations))); +- if (to_sna_crtc(crtc)->supported_rotations & crtc->rotation) ++ __FUNCTION__, crtc->rotation, to_sna_crtc(crtc)->primary_rotation.supported, ++ !!(crtc->rotation & to_sna_crtc(crtc)->primary_rotation.supported))); ++ if (to_sna_crtc(crtc)->primary_rotation.supported & crtc->rotation) + needs_transform = RRTransformCompute(crtc->x, crtc->y, + crtc->mode.HDisplay, crtc->mode.VDisplay, + RR_Rotate_0, transform, +@@ -1545,6 +1565,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) + return NULL; + + assert(!sna_crtc->shadow); ++ assert(sna_crtc->primary_rotation.supported & crtc->rotation); + sna_crtc->rotation = crtc->rotation; + return kgem_bo_reference(bo); + } +@@ -1944,7 +1965,7 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = { + }; + + static int +-sna_crtc_find_plane(struct sna *sna, int pipe) ++sna_crtc_find_sprite(struct sna *sna, int pipe) + { + #ifdef DRM_IOCTL_MODE_GETPLANERESOURCES + struct drm_mode_get_plane_res r; +@@ -1992,74 +2013,93 @@ sna_crtc_find_plane(struct sna *sna, int pipe) + } + + static void +-sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc) ++rotation_init(struct sna *sna, struct rotation *r, uint32_t obj_id, uint32_t obj_type) + { ++#if USE_ROTATION + drmModeObjectPropertiesPtr props; ++ int i, j; + +- sna_crtc->supported_rotations = RR_Rotate_0; +- sna_crtc->rotation = sna_crtc->last_rotation = RR_Rotate_0; +- +-#if USE_ROTATION +- props = drmModeObjectGetProperties(sna->kgem.fd, +- sna_crtc->id, +- DRM_MODE_OBJECT_CRTC); +- if (props) { +- int i, j; ++ props = drmModeObjectGetProperties(sna->kgem.fd, obj_id, obj_type); ++ if (props == NULL) ++ return; + +- DBG(("%s: CRTC:%d has %d props\n", __FUNCTION__, sna_crtc->id, props->count_props)); ++ DBG(("%s: object %d (type %u) has %d props\n", __FUNCTION__, ++ obj_id, obj_type, props->count_props)); + +- for (i = 0; i < props->count_props; i++) { +- struct drm_mode_get_property prop; +- struct drm_mode_property_enum *enums; ++ for (i = 0; i < props->count_props; i++) { ++ struct drm_mode_get_property prop; ++ struct drm_mode_property_enum *enums; + +- memset(&prop, 0, sizeof(prop)); +- prop.prop_id = props->props[i]; +- if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) +- continue; ++ memset(&prop, 0, sizeof(prop)); ++ prop.prop_id = props->props[i]; ++ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) ++ continue; + +- DBG(("%s: prop[%d] .id=%d, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, +- props->props[i], prop.name, prop.flags, props->prop_values[i])); +- if ((prop.flags & DRM_MODE_PROP_BITMASK) == 0) +- continue; ++ DBG(("%s: prop[%d] .id=%d, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, ++ props->props[i], prop.name, prop.flags, props->prop_values[i])); ++ if ((prop.flags & DRM_MODE_PROP_BITMASK) == 0) ++ continue; + +- if (strcmp(prop.name, "rotation")) +- continue; ++ if (strcmp(prop.name, "rotation")) ++ continue; + +- /* Note that this property only controls the primary +- * plane, not the cursor or sprite planes. +- */ +- sna_crtc->rotation_id = props->props[i]; +- sna_crtc->rotation = sna_crtc->last_rotation = props->prop_values[i]; +- +- DBG(("%s: found rotation property .id=%d, num_enums=%d\n", +- __FUNCTION__, prop.prop_id, prop.count_enum_blobs)); +- enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); +- if (enums != NULL) { +- prop.count_values = 0; +- prop.enum_blob_ptr = (uintptr_t)enums; +- +- if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { +- /* XXX we assume that the mapping between kernel enum and +- * RandR remains fixed for our lifetimes. +- */ +- for (j = 0; j < prop.count_enum_blobs; j++) { +- DBG(("%s: CRTC:%d rotation[%d] = %s [%x]\n", __FUNCTION__, sna_crtc->id, j, +- enums[j].name, enums[j].value)); +- sna_crtc->supported_rotations |= 1 << enums[j].value; +- } ++ r->obj_id = obj_id; ++ r->obj_type = obj_type; ++ r->prop_id = props->props[i]; ++ r->current = props->prop_values[i]; ++ ++ DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n", ++ __FUNCTION__, prop.prop_id, (long)props->prop_values[i], prop.count_enum_blobs)); ++ enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); ++ if (enums != NULL) { ++ prop.count_values = 0; ++ prop.enum_blob_ptr = (uintptr_t)enums; ++ ++ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { ++ /* XXX we assume that the mapping between kernel enum and ++ * RandR remains fixed for our lifetimes. ++ */ ++ for (j = 0; j < prop.count_enum_blobs; j++) { ++ DBG(("%s: rotation[%d] = %s [%x]\n", __FUNCTION__, ++ j, enums[j].name, enums[j].value)); ++ r->supported |= 1 << enums[j].value; + } +- +- free(enums); + } + +- break; ++ free(enums); + } + +- drmModeFreeObjectProperties(props); ++ break; + } ++ ++ drmModeFreeObjectProperties(props); + #endif +- DBG(("%s: CRTC:%d [pipe=%d], supported-rotations=%x, current-rotation=%x\n", +- __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->supported_rotations, sna_crtc->last_rotation)); ++} ++ ++static void ++rotation_reset(struct rotation *r) ++{ ++ if (r->prop_id == 0) ++ return; ++ ++ r->current = 0; ++} ++ ++static void ++sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc) ++{ ++ 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, DRM_MODE_OBJECT_CRTC); ++ rotation_init(sna, &sna_crtc->sprite_rotation, sna_crtc->sprite, DRM_MODE_OBJECT_PLANE); ++ ++ DBG(("%s: CRTC:%d [pipe=%d], primary: supported-rotations=%x, current-rotation=%x, sprite: 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)); + } + + static bool +@@ -2089,7 +2129,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num) + return false; + } + sna_crtc->pipe = get_pipe.pipe; +- sna_crtc->plane = sna_crtc_find_plane(sna, sna_crtc->pipe); ++ sna_crtc->sprite = sna_crtc_find_sprite(sna, sna_crtc->pipe); + + if (xf86IsEntityShared(scrn->entityList[0]) && + scrn->confScreen->device->screen != sna_crtc->pipe) { +@@ -4316,6 +4356,10 @@ void sna_mode_reset(struct sna *sna) + continue; + + sna_crtc->dpms_mode = DPMSModeOff; ++ ++ /* Force the rotation property to be reset on next use */ ++ rotation_reset(&sna_crtc->primary_rotation); ++ rotation_reset(&sna_crtc->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 b6a7950..f4dcb82 100644 +--- a/src/sna/sna_video_sprite.c ++++ b/src/sna/sna_video_sprite.c +@@ -205,10 +205,10 @@ sna_video_sprite_show(struct sna *sna, + /* XXX handle video spanning multiple CRTC */ + + VG_CLEAR(s); +- s.plane_id = sna_crtc_to_plane(crtc); ++ s.plane_id = sna_crtc_to_sprite(crtc); + + update_dst_box_to_crtc_coords(sna, crtc, dstBox); +- if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) { ++ if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + int tmp = frame->width; + frame->width = frame->height; + frame->height = tmp; +@@ -383,11 +383,15 @@ static int sna_video_sprite_put_image(ClientPtr client, + &clip)) + goto invisible; + +- if (!crtc || sna_crtc_to_plane(crtc) == 0) ++ if (!crtc || sna_crtc_to_sprite(crtc) == 0) + goto invisible; + +- /* sprites can't handle rotation natively, store it for the copy func */ +- video->rotation = crtc->rotation; ++ /* 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); ++ video->rotation = crtc->rotation; ++ } + + if (xvmc_passthrough(format->id)) { + DBG(("%s: using passthough, name=%d\n", diff --git a/debian/patches/03-reorganise-native-rotation.diff b/debian/patches/03-reorganise-native-rotation.diff new file mode 100644 index 0000000..ebcf23d --- /dev/null +++ b/debian/patches/03-reorganise-native-rotation.diff @@ -0,0 +1,245 @@ +commit 5f8714335729b4fbbb33d89dbaf0f13aa3d8427b +Author: Chris Wilson <ch...@chris-wilson.co.uk> +Date: Fri Feb 14 16:18:34 2014 +0000 + + sna: Reorganise native rotation ioctls to compile on old Linux + + It is not just the BSDs that lack these ioctls in their userspace + headers, but everything older than about a year... + + Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> + +--- a/src/sna/sna_display.c ++++ b/src/sna/sna_display.c +@@ -842,9 +842,109 @@ + to_sna_crtc(crtc)->dpms_mode = DPMSModeOff; + } + ++#define LOCAL_MODE_OBJECT_CRTC 0xcccccccc ++#define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee ++static void ++rotation_init(struct sna *sna, struct rotation *r, uint32_t obj_id, uint32_t obj_type) ++{ ++#if USE_ROTATION ++#define LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct local_mode_obj_get_properties) ++ struct local_mode_obj_get_properties { ++ uint64_t props_ptr; ++ uint64_t prop_values_ptr; ++ uint32_t count_props; ++ uint32_t obj_id; ++ uint32_t obj_type; ++ uint32_t pad; ++ } props; ++ uint64_t *prop_values; ++ int i, j; ++ ++ memset(&props, 0, sizeof(struct local_mode_obj_get_properties)); ++ props.obj_id = obj_id; ++ props.obj_type = obj_type; ++ ++ if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &props)) ++ return; ++ ++ DBG(("%s: object %d (type %u) has %d props\n", __FUNCTION__, ++ obj_id, obj_type, props.count_props)); ++ ++ if (props.count_props == 0) ++ return; ++ ++ prop_values = malloc(2*sizeof(uint64_t)*props.count_props); ++ if (prop_values == NULL) ++ return; ++ ++ props.props_ptr = (uintptr_t)prop_values; ++ props.prop_values_ptr = (uintptr_t)(prop_values + props.count_props); ++ ++ if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &props)) ++ props.count_props = 0; ++ ++ for (i = 0; i < props.count_props; i++) { ++ struct drm_mode_get_property prop; ++ struct drm_mode_property_enum *enums; ++ ++ memset(&prop, 0, sizeof(prop)); ++ prop.prop_id = prop_values[i]; ++ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) ++ continue; ++ ++ DBG(("%s: prop[%d] .id=%d, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, ++ prop_values[i], prop.name, prop.flags, prop_values[i+props.count_props])); ++ if ((prop.flags & (1 << 5)) == 0) ++ continue; ++ ++ if (strcmp(prop.name, "rotation")) ++ continue; ++ ++ r->obj_id = obj_id; ++ r->obj_type = obj_type; ++ r->prop_id = prop_values[i]; ++ r->current = prop_values[i + props.count_props]; ++ ++ DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n", ++ __FUNCTION__, prop.prop_id, (long)prop_values[i+props.count_props], prop.count_enum_blobs)); ++ enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); ++ if (enums != NULL) { ++ prop.count_values = 0; ++ prop.enum_blob_ptr = (uintptr_t)enums; ++ ++ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { ++ /* XXX we assume that the mapping between kernel enum and ++ * RandR remains fixed for our lifetimes. ++ */ ++ for (j = 0; j < prop.count_enum_blobs; j++) { ++ DBG(("%s: rotation[%d] = %s [%x]\n", __FUNCTION__, ++ j, enums[j].name, enums[j].value)); ++ r->supported |= 1 << enums[j].value; ++ } ++ } ++ ++ free(enums); ++ } ++ ++ break; ++ } ++ ++ free(prop_values); ++#endif ++} ++ + static bool + rotation_set(struct sna *sna, struct rotation *r, uint32_t desired) + { ++#define LOCAL_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct local_mode_obj_set_property) ++ struct local_mode_obj_set_property { ++ uint64_t value; ++ uint32_t prop_id; ++ uint32_t obj_id; ++ uint32_t obj_type; ++ uint32_t pad; ++ } prop; ++ + if (desired == r->current) + return true; + +@@ -858,15 +958,27 @@ + assert(r->obj_type); + assert(r->prop_id); + +- if (drmModeObjectSetProperty(sna->kgem.fd, +- r->obj_id, r->obj_type, +- r->prop_id, desired)) ++ prop.obj_id = r->obj_id; ++ prop.obj_type = r->obj_type; ++ prop.prop_id = r->prop_id; ++ prop.value = desired; ++ ++ if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_SETPROPERTY, &prop)) + return false; + + r->current = desired; + return true; + } + ++static void ++rotation_reset(struct rotation *r) ++{ ++ if (r->prop_id == 0) ++ return; ++ ++ r->current = 0; ++} ++ + bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation) + { + DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n", +@@ -1987,79 +2099,6 @@ + } + + static void +-rotation_init(struct sna *sna, struct rotation *r, uint32_t obj_id, uint32_t obj_type) +-{ +-#if USE_ROTATION +- drmModeObjectPropertiesPtr props; +- int i, j; +- +- props = drmModeObjectGetProperties(sna->kgem.fd, obj_id, obj_type); +- if (props == NULL) +- return; +- +- DBG(("%s: object %d (type %u) has %d props\n", __FUNCTION__, +- obj_id, obj_type, props->count_props)); +- +- for (i = 0; i < props->count_props; i++) { +- struct drm_mode_get_property prop; +- struct drm_mode_property_enum *enums; +- +- memset(&prop, 0, sizeof(prop)); +- prop.prop_id = props->props[i]; +- if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) +- continue; +- +- DBG(("%s: prop[%d] .id=%d, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, +- props->props[i], prop.name, prop.flags, props->prop_values[i])); +- if ((prop.flags & DRM_MODE_PROP_BITMASK) == 0) +- continue; +- +- if (strcmp(prop.name, "rotation")) +- continue; +- +- r->obj_id = obj_id; +- r->obj_type = obj_type; +- r->prop_id = props->props[i]; +- r->current = props->prop_values[i]; +- +- DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n", +- __FUNCTION__, prop.prop_id, (long)props->prop_values[i], prop.count_enum_blobs)); +- enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); +- if (enums != NULL) { +- prop.count_values = 0; +- prop.enum_blob_ptr = (uintptr_t)enums; +- +- if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { +- /* XXX we assume that the mapping between kernel enum and +- * RandR remains fixed for our lifetimes. +- */ +- for (j = 0; j < prop.count_enum_blobs; j++) { +- DBG(("%s: rotation[%d] = %s [%x]\n", __FUNCTION__, +- j, enums[j].name, enums[j].value)); +- r->supported |= 1 << enums[j].value; +- } +- } +- +- free(enums); +- } +- +- break; +- } +- +- drmModeFreeObjectProperties(props); +-#endif +-} +- +-static void +-rotation_reset(struct rotation *r) +-{ +- if (r->prop_id == 0) +- return; +- +- r->current = 0; +-} +- +-static void + sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *sna_crtc) + { + sna_crtc->rotation = RR_Rotate_0; +@@ -2067,8 +2106,8 @@ + 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, DRM_MODE_OBJECT_CRTC); +- rotation_init(sna, &sna_crtc->sprite_rotation, sna_crtc->sprite, DRM_MODE_OBJECT_PLANE); ++ 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", + __FUNCTION__, sna_crtc->id, sna_crtc->pipe, diff --git a/debian/patches/04-inherit-native-rotation.diff b/debian/patches/04-inherit-native-rotation.diff new file mode 100644 index 0000000..ea781d3 --- /dev/null +++ b/debian/patches/04-inherit-native-rotation.diff @@ -0,0 +1,21 @@ +commit 8eb6335653e6e38228ecf95c3eef82ca2a864e45 +Author: Chris Wilson <ch...@chris-wilson.co.uk> +Date: Fri Feb 14 19:36:47 2014 +0000 + + sna: Inherit the native rotation on initial output probing + + Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> + +diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c +index 8d2ec8a..636217a 100644 +--- a/src/sna/sna_display.c ++++ b/src/sna/sna_display.c +@@ -3692,7 +3692,7 @@ static bool sna_probe_initial_configuration(struct sna *sna) + continue; + + mode_from_kmode(scrn, &mode.mode, &crtc->desiredMode); +- crtc->desiredRotation = RR_Rotate_0; ++ crtc->desiredRotation = sna_crtc->primary_rotation.current; + crtc->desiredX = mode.x; -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/e1xlfqa-0008jh...@moszumanska.debian.org