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

Reply via email to