update from xf86-video-ati 7.10.0 to 18.0.0

https://lists.x.org/archives/xorg-announce/2018-March/002854.html

Index: configure
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/configure,v
retrieving revision 1.22
diff -u -p -r1.22 configure
--- configure   20 Feb 2018 04:49:20 -0000      1.22
+++ configure   8 Mar 2018 06:46:35 -0000
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for xf86-video-ati 7.10.0.
+# Generated by GNU Autoconf 2.69 for xf86-video-ati 18.0.0.
 #
 # Report bugs to 
<https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='xf86-video-ati'
 PACKAGE_TARNAME='xf86-video-ati'
-PACKAGE_VERSION='7.10.0'
-PACKAGE_STRING='xf86-video-ati 7.10.0'
+PACKAGE_VERSION='18.0.0'
+PACKAGE_STRING='xf86-video-ati 18.0.0'
 
PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon'
 PACKAGE_URL=''
 
@@ -1390,7 +1390,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures xf86-video-ati 7.10.0 to adapt to many kinds of 
systems.
+\`configure' configures xf86-video-ati 18.0.0 to adapt to many kinds of 
systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1460,7 +1460,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of xf86-video-ati 7.10.0:";;
+     short | recursive ) echo "Configuration of xf86-video-ati 18.0.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1616,7 +1616,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-xf86-video-ati configure 7.10.0
+xf86-video-ati configure 18.0.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2031,7 +2031,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by xf86-video-ati $as_me 7.10.0, which was
+It was created by xf86-video-ati $as_me 18.0.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2862,7 +2862,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='xf86-video-ati'
- VERSION='7.10.0'
+ VERSION='18.0.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -11206,8 +11206,8 @@ else
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
-      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
-      *GNU* | *'with BFD'*)
+      case `"$lt_cv_path_LD" -v 2>/dev/null </dev/null` in
+      *GNU* | *'with BFD'* | *LLD*)
        test "$with_gnu_ld" != no && break
        ;;
       *)
@@ -11237,8 +11237,8 @@ if ${lt_cv_prog_gnu_ld+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
+case `$LD -v 2>/dev/null </dev/null` in
+*GNU* | *'with BFD'* | *LLD*)
   lt_cv_prog_gnu_ld=yes
   ;;
 *)
@@ -19057,8 +19057,8 @@ for ac_header in present.h
 do :
   ac_fn_c_check_header_compile "$LINENO" "present.h" "ac_cv_header_present_h" 
"#include <X11/Xmd.h>
                 #include <X11/Xproto.h>
-                #include <X11/X.h>
                 #include \"xorg-server.h\"
+                #include <X11/X.h>
 "
 if test "x$ac_cv_header_present_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
@@ -19881,7 +19881,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by xf86-video-ati $as_me 7.10.0, which was
+This file was extended by xf86-video-ati $as_me 18.0.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19947,7 +19947,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-xf86-video-ati config.status 7.10.0
+xf86-video-ati config.status 18.0.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
Index: configure.ac
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/configure.ac,v
retrieving revision 1.15
diff -u -p -r1.15 configure.ac
--- configure.ac        20 Feb 2018 04:49:20 -0000      1.15
+++ configure.ac        8 Mar 2018 06:46:25 -0000
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-video-ati],
-        [7.10.0],
+        [18.0.0],
         
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon],
         [xf86-video-ati])
 
@@ -180,8 +180,8 @@ AC_CHECK_HEADERS([misyncshm.h], [], [],
 AC_CHECK_HEADERS([present.h], [], [],
                 [#include <X11/Xmd.h>
                 #include <X11/Xproto.h>
-                #include <X11/X.h>
-                #include "xorg-server.h"])
+                #include "xorg-server.h"
+                #include <X11/X.h>])
 
 AC_CHECK_HEADERS([dri3.h], [], [],
                 [#include <X11/Xmd.h>
Index: man/radeon.man
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/man/radeon.man,v
retrieving revision 1.15
diff -u -p -r1.15 radeon.man
--- man/radeon.man      20 Feb 2018 04:49:20 -0000      1.15
+++ man/radeon.man      8 Mar 2018 06:43:42 -0000
@@ -18,7 +18,8 @@ following features:
 .PD 0
 .TP 2
 \(bu
-Full support for 8-, 15-, 16- and 24-bit pixel depths;
+Full support for 8-, 15-, 16- and 24-bit pixel depths, and for 30-bit depth on 
Linux 3.16
+and later;
 .TP
 \(bu
 RandR 1.2 and RandR 1.3 support;
@@ -288,8 +289,8 @@ separate scanout buffers need to be allo
 on. If this option is set, the default value of the property is 'on' or 'off'
 accordingly. If this option isn't set, the default value of the property is
 .B auto,
-which means that TearFree is on for outputs with rotation or other RandR
-transforms, and for RandR 1.4 slave outputs, otherwise off.
+which means that TearFree is on for rotated outputs, outputs with RandR
+transforms applied and for RandR 1.4 slave outputs, otherwise off.
 .TP
 .BI "Option \*qAccelMethod\*q \*q" "string" \*q
 Chooses between available acceleration architectures.  Valid values are
Index: src/drmmode_display.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/drmmode_display.c,v
retrieving revision 1.15
diff -u -p -r1.15 drmmode_display.c
--- src/drmmode_display.c       20 Feb 2018 04:49:20 -0000      1.15
+++ src/drmmode_display.c       8 Mar 2018 06:43:42 -0000
@@ -34,6 +34,7 @@
 #include <time.h>
 #include "cursorstr.h"
 #include "damagestr.h"
+#include "inputstr.h"
 #include "list.h"
 #include "micmap.h"
 #include "xf86cmap.h"
@@ -942,9 +943,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc,
                if (!fb)
                        fb = 
radeon_pixmap_get_fb(pScreen->GetWindowPixmap(pScreen->root));
                if (!fb) {
-                       fb = radeon_fb_create(pRADEONEnt->fd, pScrn->virtualX,
-                                             pScrn->virtualY, pScrn->depth,
-                                             pScrn->bitsPerPixel,
+                       fb = radeon_fb_create(pScrn, pRADEONEnt->fd,
+                                             pScrn->virtualX, pScrn->virtualY,
                                              pScrn->displayWidth * 
info->pixel_bytes,
                                              info->front_bo->handle);
                        /* Prevent refcnt of ad-hoc FBs from reaching 2 */
@@ -1394,8 +1394,9 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drm
        xf86CrtcPtr crtc;
        drmmode_crtc_private_ptr drmmode_crtc;
        RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+       RADEONInfoPtr info = RADEONPTR(pScrn);
 
-       crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
+       crtc = xf86CrtcCreate(pScrn, &info->drmmode_crtc_funcs);
        if (crtc == NULL)
                return 0;
 
@@ -1414,6 +1415,72 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drm
        return 1;
 }
 
+/*
+ * Update all of the property values for an output
+ */
+static void
+drmmode_output_update_properties(xf86OutputPtr output)
+{
+       drmmode_output_private_ptr drmmode_output = output->driver_private;
+       int i, j, k;
+       int err;
+       drmModeConnectorPtr koutput;
+
+       /* Use the most recently fetched values from the kernel */
+       koutput = drmmode_output->mode_output;
+
+       if (!koutput)
+               return;
+
+       for (i = 0; i < drmmode_output->num_props; i++) {
+               drmmode_prop_ptr p = &drmmode_output->props[i];
+
+               for (j = 0; j < koutput->count_props; j++) {
+                       if (koutput->props[j] != p->mode_prop->prop_id)
+                               continue;
+
+                       /* Check to see if the property value has changed */
+                       if (koutput->prop_values[j] == p->value)
+                               break;
+
+                       p->value = koutput->prop_values[j];
+
+                       if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
+                               INT32 value = p->value;
+
+                               err = 
RRChangeOutputProperty(output->randr_output,
+                                                            p->atoms[0], 
XA_INTEGER,
+                                                            32, 
PropModeReplace, 1,
+                                                            &value, FALSE, 
TRUE);
+                               if (err != 0) {
+                                       xf86DrvMsg(output->scrn->scrnIndex, 
X_ERROR,
+                                                  "RRChangeOutputProperty 
error, %d\n",
+                                                  err);
+                               }
+                       } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
+                               for (k = 0; k < p->mode_prop->count_enums; k++) 
{
+                                       if (p->mode_prop->enums[k].value == 
p->value)
+                                               break;
+                               }
+                               if (k < p->mode_prop->count_enums) {
+                                       err = 
RRChangeOutputProperty(output->randr_output,
+                                                                    
p->atoms[0], XA_ATOM,
+                                                                    32, 
PropModeReplace, 1,
+                                                                    
&p->atoms[k + 1], FALSE,
+                                                                    TRUE);
+                                       if (err != 0) {
+                                               
xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+                                                          
"RRChangeOutputProperty error, %d\n",
+                                                          err);
+                                       }
+                               }
+                       }
+
+                       break;
+               }
+        }
+}
+
 static xf86OutputStatus
 drmmode_output_detect(xf86OutputPtr output)
 {
@@ -1423,9 +1490,14 @@ drmmode_output_detect(xf86OutputPtr outp
        xf86OutputStatus status;
        drmModeFreeConnector(drmmode_output->mode_output);
 
-       drmmode_output->mode_output = drmModeGetConnector(pRADEONEnt->fd, 
drmmode_output->output_id);
-       if (!drmmode_output->mode_output)
+       drmmode_output->mode_output =
+           drmModeGetConnector(pRADEONEnt->fd, drmmode_output->output_id);
+       if (!drmmode_output->mode_output) {
+               drmmode_output->output_id = -1;
                return XF86OutputStatusDisconnected;
+       }
+
+       drmmode_output_update_properties(output);
 
        switch (drmmode_output->mode_output->connection) {
        case DRM_MODE_CONNECTED:
@@ -1448,6 +1520,51 @@ drmmode_output_mode_valid(xf86OutputPtr 
        return MODE_OK;
 }
 
+static int
+koutput_get_prop_idx(int fd, drmModeConnectorPtr koutput,
+        int type, const char *name)
+{
+    int idx = -1;
+
+    for (int i = 0; i < koutput->count_props; i++) {
+        drmModePropertyPtr prop = drmModeGetProperty(fd, koutput->props[i]);
+
+        if (!prop)
+            continue;
+
+        if (drm_property_type_is(prop, type) && !strcmp(prop->name, name))
+            idx = i;
+
+        drmModeFreeProperty(prop);
+
+        if (idx > -1)
+            break;
+    }
+
+    return idx;
+}
+
+static int
+koutput_get_prop_id(int fd, drmModeConnectorPtr koutput,
+        int type, const char *name)
+{
+    int idx = koutput_get_prop_idx(fd, koutput, type, name);
+
+    return (idx > -1) ? koutput->props[idx] : -1;
+}
+
+static drmModePropertyBlobPtr
+koutput_get_prop_blob(int fd, drmModeConnectorPtr koutput, const char *name)
+{
+    drmModePropertyBlobPtr blob = NULL;
+    int idx = koutput_get_prop_idx(fd, koutput, DRM_MODE_PROP_BLOB, name);
+
+    if (idx > -1)
+        blob = drmModeGetPropertyBlob(fd, koutput->prop_values[idx]);
+
+    return blob;
+}
+
 static DisplayModePtr
 drmmode_output_get_modes(xf86OutputPtr output)
 {
@@ -1456,25 +1573,16 @@ drmmode_output_get_modes(xf86OutputPtr o
        RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn);
        int i;
        DisplayModePtr Modes = NULL, Mode;
-       drmModePropertyPtr props;
        xf86MonPtr mon = NULL;
 
        if (!koutput)
                return NULL;
 
+       drmModeFreePropertyBlob(drmmode_output->edid_blob);
+
        /* look for an EDID property */
-       for (i = 0; i < koutput->count_props; i++) {
-               props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]);
-               if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
-                       if (!strcmp(props->name, "EDID")) {
-                               if (drmmode_output->edid_blob)
-                                       
drmModeFreePropertyBlob(drmmode_output->edid_blob);
-                               drmmode_output->edid_blob = 
drmModeGetPropertyBlob(pRADEONEnt->fd, koutput->prop_values[i]);
-                       }
-               }
-               if (props)
-                       drmModeFreeProperty(props);
-       }
+       drmmode_output->edid_blob =
+               koutput_get_prop_blob(pRADEONEnt->fd, koutput, "EDID");
 
        if (drmmode_output->edid_blob) {
                mon = xf86InterpretEDID(output->scrn->scrnIndex,
@@ -1895,7 +2003,6 @@ drmmode_output_init(ScrnInfoPtr pScrn, d
        drmModeConnectorPtr koutput;
        drmModeEncoderPtr *kencoders = NULL;
        drmmode_output_private_ptr drmmode_output;
-       drmModePropertyPtr props;
        drmModePropertyBlobPtr path_blob = NULL;
        char name[32];
        int i;
@@ -1905,17 +2012,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, d
        if (!koutput)
                return 0;
 
-       for (i = 0; i < koutput->count_props; i++) {
-               props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]);
-               if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
-                       if (!strcmp(props->name, "PATH")) {
-                               path_blob = 
drmModeGetPropertyBlob(pRADEONEnt->fd, koutput->prop_values[i]);
-                               drmModeFreeProperty(props);
-                               break;
-                       }
-                       drmModeFreeProperty(props);
-               }
-       }
+       path_blob = koutput_get_prop_blob(pRADEONEnt->fd, koutput, "PATH");
 
        kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
        if (!kencoders) {
@@ -1995,17 +2092,9 @@ drmmode_output_init(ScrnInfoPtr pScrn, d
        /* work out the possible clones later */
        output->possible_clones = 0;
 
-       for (i = 0; i < koutput->count_props; i++) {
-               props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]);
-               if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
-                       if (!strcmp(props->name, "DPMS")) {
-                               drmmode_output->dpms_enum_id = 
koutput->props[i];
-                               drmModeFreeProperty(props);
-                               break;
-                       }
-                       drmModeFreeProperty(props);
-               }
-       }
+       drmmode_output->dpms_enum_id =
+               koutput_get_prop_id(pRADEONEnt->fd, koutput, DRM_MODE_PROP_ENUM,
+                                   "DPMS");
 
        if (dynamic) {
                output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), 
output->name, strlen(output->name), output);
@@ -2530,13 +2619,24 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn,
        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
                       "%d crtcs needed for screen.\n", crtcs_needed);
 
+       /* Need per-screen drmmode_crtc_funcs, based on our global template,
+        * so we can disable some functions, depending on screen settings.
+        */
+       info->drmmode_crtc_funcs = drmmode_crtc_funcs;
+
        if (info->r600_shadow_fb) {
                /* Rotation requires hardware acceleration */
-               drmmode_crtc_funcs.shadow_allocate = NULL;
-               drmmode_crtc_funcs.shadow_create = NULL;
-               drmmode_crtc_funcs.shadow_destroy = NULL;
+               info->drmmode_crtc_funcs.shadow_allocate = NULL;
+               info->drmmode_crtc_funcs.shadow_create = NULL;
+               info->drmmode_crtc_funcs.shadow_destroy = NULL;
        }
 
+       /* Hw gamma lut's are currently bypassed by the hw at color depth 30,
+        * so spare the server the effort to compute and update the cluts.
+        */
+       if (pScrn->depth == 30)
+               info->drmmode_crtc_funcs.gamma_set = NULL;
+
        drmmode->count_crtcs = mode_res->count_crtcs;
        xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, 
mode_res->max_height);
 
@@ -2628,6 +2728,56 @@ Bool drmmode_set_bufmgr(ScrnInfoPtr pScr
 }
 
 
+static void drmmode_sprite_do_set_cursor(struct radeon_device_priv 
*device_priv,
+                                        ScrnInfoPtr scrn, int x, int y)
+{
+       RADEONInfoPtr info = RADEONPTR(scrn);
+       CursorPtr cursor = device_priv->cursor;
+       Bool sprite_visible = device_priv->sprite_visible;
+
+       if (cursor) {
+               x -= cursor->bits->xhot;
+               y -= cursor->bits->yhot;
+
+               device_priv->sprite_visible =
+                       x < scrn->virtualX && y < scrn->virtualY &&
+                       (x + cursor->bits->width > 0) &&
+                       (y + cursor->bits->height > 0);
+       } else {
+               device_priv->sprite_visible = FALSE;
+       }
+
+       info->sprites_visible += device_priv->sprite_visible - sprite_visible;
+}
+
+void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+                              CursorPtr pCursor, int x, int y)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+       RADEONInfoPtr info = RADEONPTR(scrn);
+       struct radeon_device_priv *device_priv =
+               dixLookupScreenPrivate(&pDev->devPrivates,
+                                      &radeon_device_private_key, pScreen);
+
+       device_priv->cursor = pCursor;
+       drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
+
+       info->SetCursor(pDev, pScreen, pCursor, x, y);
+}
+
+void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
+                               int y)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+       RADEONInfoPtr info = RADEONPTR(scrn);
+       struct radeon_device_priv *device_priv =
+               dixLookupScreenPrivate(&pDev->devPrivates,
+                                      &radeon_device_private_key, pScreen);
+
+       drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
+
+       info->MoveCursor(pDev, pScreen, x, y);
+}
 
 void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct 
radeon_bo *bo)
 {
@@ -2655,26 +2805,36 @@ Bool drmmode_set_desired_modes(ScrnInfoP
 {
        xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
        RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+       unsigned num_desired = 0, num_on = 0;
        int c;
 
+       /* First, disable all unused CRTCs */
+       if (set_hw) {
+               for (c = 0; c < config->num_crtc; c++) {
+                       xf86CrtcPtr crtc = config->crtc[c];
+                       drmmode_crtc_private_ptr drmmode_crtc = 
crtc->driver_private;
+
+                       /* Skip disabled CRTCs */
+                       if (crtc->enabled)
+                               continue;
+
+                       drmmode_do_crtc_dpms(crtc, DPMSModeOff);
+                       drmModeSetCrtc(pRADEONEnt->fd,
+                                      drmmode_crtc->mode_crtc->crtc_id,
+                                      0, 0, 0, NULL, 0, NULL);
+                       drmmode_fb_reference(pRADEONEnt->fd,
+                                            &drmmode_crtc->fb, NULL);
+               }
+       }
+
+       /* Then, try setting the chosen mode on each CRTC */
        for (c = 0; c < config->num_crtc; c++) {
                xf86CrtcPtr     crtc = config->crtc[c];
-               drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
                xf86OutputPtr   output = NULL;
                int             o;
 
-               /* Skip disabled CRTCs */
-               if (!crtc->enabled) {
-                       if (set_hw) {
-                               drmmode_do_crtc_dpms(crtc, DPMSModeOff);
-                               drmModeSetCrtc(pRADEONEnt->fd,
-                                              drmmode_crtc->mode_crtc->crtc_id,
-                                              0, 0, 0, NULL, 0, NULL);
-                               drmmode_fb_reference(pRADEONEnt->fd,
-                                                    &drmmode_crtc->fb, NULL);
-                       }
+               if (!crtc->enabled)
                        continue;
-               }
 
                if (config->output[config->compat_output]->crtc == crtc)
                        output = config->output[config->compat_output];
@@ -2691,14 +2851,19 @@ Bool drmmode_set_desired_modes(ScrnInfoP
                if (!output)
                        continue;
 
+               num_desired++;
+
                /* Mark that we'll need to re-set the mode for sure */
                memset(&crtc->mode, 0, sizeof(crtc->mode));
                if (!crtc->desiredMode.CrtcHDisplay)
                {
                        DisplayModePtr  mode = xf86OutputFindClosestMode 
(output, pScrn->currentMode);
 
-                       if (!mode)
-                               return FALSE;
+                       if (!mode) {
+                               xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                                          "Failed to find mode for CRTC %d\n", 
c);
+                               continue;
+                       }
                        crtc->desiredMode = *mode;
                        crtc->desiredRotation = RR_Rotate_0;
                        crtc->desiredX = 0;
@@ -2706,18 +2871,30 @@ Bool drmmode_set_desired_modes(ScrnInfoP
                }
 
                if (set_hw) {
-                       if (!crtc->funcs->set_mode_major(crtc, 
&crtc->desiredMode, crtc->desiredRotation,
-                                                        crtc->desiredX, 
crtc->desiredY))
-                               return FALSE;
+                       if (crtc->funcs->set_mode_major(crtc, 
&crtc->desiredMode,
+                                                       crtc->desiredRotation,
+                                                       crtc->desiredX,
+                                                       crtc->desiredY)) {
+                               num_on++;
+                       } else {
+                               xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                                          "Failed to set mode on CRTC %d\n", 
c);
+                       }
                } else {
                        crtc->mode = crtc->desiredMode;
                        crtc->rotation = crtc->desiredRotation;
                        crtc->x = crtc->desiredX;
                        crtc->y = crtc->desiredY;
-                       if (!drmmode_handle_transform(crtc))
-                               return FALSE;
+                       if (drmmode_handle_transform(crtc))
+                               num_on++;
                }
        }
+
+       if (num_on == 0 && num_desired > 0) {
+               xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to enable any 
CRTC\n");
+               return FALSE;
+       }
+
        return TRUE;
 }
 
@@ -2730,8 +2907,10 @@ Bool drmmode_setup_colormap(ScreenPtr pS
                       "Initializing kms color map\n");
        if (!miCreateDefColormap(pScreen))
            return FALSE;
-       /* all radeons support 10 bit CLUTs */
-       if (!xf86HandleColormaps(pScreen, 256, 10,
+
+       /* All radeons support 10 bit CLUTs. They get bypassed at depth 30. */
+       if (pScrn->depth != 30 &&
+           !xf86HandleColormaps(pScreen, 256, 10,
                                 NULL, NULL,
                                 CMAP_PALETTED_TRUECOLOR
 #if 0 /* This option messes up text mode! (e...@suse.de) */
@@ -2796,23 +2975,23 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, dr
         */
        for (i = 0; i < config->num_output; i++) {
                xf86OutputPtr output = config->output[i];
+               xf86CrtcPtr crtc = output->crtc;
                drmmode_output_private_ptr drmmode_output = 
output->driver_private;
-               uint32_t con_id = drmmode_output->mode_output->connector_id;
-               drmModeConnectorPtr koutput;
+
+               drmmode_output_detect(output);
+
+               if (!crtc || !drmmode_output->mode_output)
+                       continue;
 
                /* Get an updated view of the properties for the current 
connector and
                 * look for the link-status property
                 */
-               koutput = drmModeGetConnectorCurrent(pRADEONEnt->fd, con_id);
-               for (j = 0; koutput && j < koutput->count_props; j++) {
-                       drmModePropertyPtr props;
-                       props = drmModeGetProperty(pRADEONEnt->fd, 
koutput->props[j]);
-                       if (props && props->flags & DRM_MODE_PROP_ENUM &&
-                           !strcmp(props->name, "link-status") &&
-                           koutput->prop_values[j] == 
DRM_MODE_LINK_STATUS_BAD) {
-                               xf86CrtcPtr crtc = output->crtc;
-                               if (!crtc)
-                                       continue;
+               for (j = 0; j < drmmode_output->num_props; j++) {
+                       drmmode_prop_ptr p = &drmmode_output->props[j];
+
+                       if (!strcmp(p->mode_prop->name, "link-status")) {
+                               if (p->value != DRM_MODE_LINK_STATUS_BAD)
+                                       break;
 
                                /* the connector got a link failure, re-set the 
current mode */
                                drmmode_set_mode_major(crtc, &crtc->mode, 
crtc->rotation,
@@ -2820,12 +2999,13 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, dr
 
                                xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                                           "hotplug event: connector %u's 
link-state is BAD, "
-                                          "tried resetting the current mode. 
You may be left "
-                                          "with a black screen if this 
fails...\n", con_id);
+                                          "tried resetting the current mode. 
You may be left"
+                                          "with a black screen if this 
fails...\n",
+                                          
drmmode_output->mode_output->connector_id);
+
+                               break;
                        }
-                       drmModeFreeProperty(props);
                }
-               drmModeFreeConnector(koutput);
        }
 
        mode_res = drmModeGetResources(pRADEONEnt->fd);
Index: src/drmmode_display.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/drmmode_display.h,v
retrieving revision 1.9
diff -u -p -r1.9 drmmode_display.h
--- src/drmmode_display.h       20 Feb 2018 04:49:20 -0000      1.9
+++ src/drmmode_display.h       8 Mar 2018 06:43:42 -0000
@@ -206,6 +206,10 @@ extern Bool drmmode_pre_init(ScrnInfoPtr
 extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct 
radeon_bo_manager *bufmgr);
+extern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+                                     CursorPtr pCursor, int x, int y);
+extern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
int x,
+                                      int y);
 extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, 
struct radeon_bo *bo);
 void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int 
y);
 extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
Index: src/evergreen_exa.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/evergreen_exa.c,v
retrieving revision 1.8
diff -u -p -r1.8 evergreen_exa.c
--- src/evergreen_exa.c 20 Feb 2018 04:49:20 -0000      1.8
+++ src/evergreen_exa.c 8 Mar 2018 06:43:42 -0000
@@ -668,6 +668,10 @@ struct formatinfo {
 };
 
 static struct formatinfo EVERGREENTexFormats[] = {
+    {PICT_a2r10g10b10, FMT_2_10_10_10},
+    {PICT_x2r10g10b10, FMT_2_10_10_10},
+    {PICT_a2b10g10r10, FMT_2_10_10_10},
+    {PICT_x2b10g10r10, FMT_2_10_10_10},
     {PICT_a8r8g8b8,    FMT_8_8_8_8},
     {PICT_x8r8g8b8,    FMT_8_8_8_8},
     {PICT_a8b8g8r8,    FMT_8_8_8_8},
@@ -723,6 +727,12 @@ static uint32_t EVERGREENGetBlendCntl(in
 static Bool EVERGREENGetDestFormat(PicturePtr pDstPicture, uint32_t 
*dst_format)
 {
     switch (pDstPicture->format) {
+    case PICT_a2r10g10b10:
+    case PICT_x2r10g10b10:
+    case PICT_a2b10g10r10:
+    case PICT_x2b10g10r10:
+       *dst_format = COLOR_2_10_10_10;
+       break;
     case PICT_a8r8g8b8:
     case PICT_x8r8g8b8:
     case PICT_a8b8g8r8:
@@ -891,6 +901,7 @@ static Bool EVERGREENTextureSetup(Pictur
 
     /* component swizzles */
     switch (pPict->format) {
+    case PICT_a2r10g10b10:
     case PICT_a1r5g5b5:
     case PICT_a8r8g8b8:
        pix_r = SQ_SEL_Z; /* R */
@@ -898,12 +909,14 @@ static Bool EVERGREENTextureSetup(Pictur
        pix_b = SQ_SEL_X; /* B */
        pix_a = SQ_SEL_W; /* A */
        break;
+    case PICT_a2b10g10r10:
     case PICT_a8b8g8r8:
        pix_r = SQ_SEL_X; /* R */
        pix_g = SQ_SEL_Y; /* G */
        pix_b = SQ_SEL_Z; /* B */
        pix_a = SQ_SEL_W; /* A */
        break;
+    case PICT_x2b10g10r10:
     case PICT_x8b8g8r8:
        pix_r = SQ_SEL_X; /* R */
        pix_g = SQ_SEL_Y; /* G */
@@ -922,6 +935,7 @@ static Bool EVERGREENTextureSetup(Pictur
        pix_b = SQ_SEL_W; /* B */
        pix_a = SQ_SEL_1; /* A */
        break;
+    case PICT_x2r10g10b10:
     case PICT_x1r5g5b5:
     case PICT_x8r8g8b8:
     case PICT_r5g6b5:
@@ -1425,6 +1439,8 @@ static Bool EVERGREENPrepareComposite(in
     cb_conf.surface = accel_state->dst_obj.surface;
 
     switch (pDstPicture->format) {
+    case PICT_a2r10g10b10:
+    case PICT_x2r10g10b10:
     case PICT_a8r8g8b8:
     case PICT_x8r8g8b8:
     case PICT_a1r5g5b5:
@@ -1432,6 +1448,8 @@ static Bool EVERGREENPrepareComposite(in
     default:
        cb_conf.comp_swap = 1; /* ARGB */
        break;
+    case PICT_a2b10g10r10:
+    case PICT_x2b10g10r10:
     case PICT_a8b8g8r8:
     case PICT_x8b8g8r8:
        cb_conf.comp_swap = 0; /* ABGR */
Index: src/r600_exa.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/r600_exa.c,v
retrieving revision 1.10
diff -u -p -r1.10 r600_exa.c
--- src/r600_exa.c      20 Feb 2018 04:49:20 -0000      1.10
+++ src/r600_exa.c      8 Mar 2018 06:43:42 -0000
@@ -727,6 +727,10 @@ struct formatinfo {
 };
 
 static struct formatinfo R600TexFormats[] = {
+    {PICT_a2r10g10b10, FMT_2_10_10_10},
+    {PICT_x2r10g10b10, FMT_2_10_10_10},
+    {PICT_a2b10g10r10, FMT_2_10_10_10},
+    {PICT_x2b10g10r10, FMT_2_10_10_10},
     {PICT_a8r8g8b8,    FMT_8_8_8_8},
     {PICT_x8r8g8b8,    FMT_8_8_8_8},
     {PICT_a8b8g8r8,    FMT_8_8_8_8},
@@ -782,6 +786,12 @@ static uint32_t R600GetBlendCntl(int op,
 static Bool R600GetDestFormat(PicturePtr pDstPicture, uint32_t *dst_format)
 {
     switch (pDstPicture->format) {
+    case PICT_a2r10g10b10:
+    case PICT_x2r10g10b10:
+    case PICT_a2b10g10r10:
+    case PICT_x2b10g10r10:
+       *dst_format = COLOR_2_10_10_10;
+       break;
     case PICT_a8r8g8b8:
     case PICT_x8r8g8b8:
     case PICT_a8b8g8r8:
@@ -906,6 +916,7 @@ static Bool R600TextureSetup(PicturePtr 
 
     /* component swizzles */
     switch (pPict->format) {
+    case PICT_a2r10g10b10:
     case PICT_a1r5g5b5:
     case PICT_a8r8g8b8:
        pix_r = SQ_SEL_Z; /* R */
@@ -913,12 +924,14 @@ static Bool R600TextureSetup(PicturePtr 
        pix_b = SQ_SEL_X; /* B */
        pix_a = SQ_SEL_W; /* A */
        break;
+    case PICT_a2b10g10r10:
     case PICT_a8b8g8r8:
        pix_r = SQ_SEL_X; /* R */
        pix_g = SQ_SEL_Y; /* G */
        pix_b = SQ_SEL_Z; /* B */
        pix_a = SQ_SEL_W; /* A */
        break;
+    case PICT_x2b10g10r10:
     case PICT_x8b8g8r8:
        pix_r = SQ_SEL_X; /* R */
        pix_g = SQ_SEL_Y; /* G */
@@ -937,6 +950,7 @@ static Bool R600TextureSetup(PicturePtr 
        pix_b = SQ_SEL_W; /* B */
        pix_a = SQ_SEL_1; /* A */
        break;
+    case PICT_x2r10g10b10:
     case PICT_x1r5g5b5:
     case PICT_x8r8g8b8:
     case PICT_r5g6b5:
@@ -1464,6 +1478,8 @@ static Bool R600PrepareComposite(int op,
     cb_conf.surface = accel_state->dst_obj.surface;
 
     switch (pDstPicture->format) {
+    case PICT_a2r10g10b10:
+    case PICT_x2r10g10b10:
     case PICT_a8r8g8b8:
     case PICT_x8r8g8b8:
     case PICT_a1r5g5b5:
@@ -1471,6 +1487,8 @@ static Bool R600PrepareComposite(int op,
     default:
        cb_conf.comp_swap = 1; /* ARGB */
        break;
+    case PICT_a2b10g10r10:
+    case PICT_x2b10g10r10:
     case PICT_a8b8g8r8:
     case PICT_x8b8g8r8:
        cb_conf.comp_swap = 0; /* ABGR */
Index: src/radeon.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/radeon.h,v
retrieving revision 1.17
diff -u -p -r1.17 radeon.h
--- src/radeon.h        20 Feb 2018 04:49:20 -0000      1.17
+++ src/radeon.h        8 Mar 2018 06:43:42 -0000
@@ -192,23 +192,23 @@ radeon_master_screen(ScreenPtr screen)
 static inline ScreenPtr
 radeon_dirty_master(PixmapDirtyUpdatePtr dirty)
 {
+    return radeon_master_screen(dirty->slave_dst->drawable.pScreen);
+}
+
+static inline DrawablePtr
+radeon_dirty_src_drawable(PixmapDirtyUpdatePtr dirty)
+{
 #ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
-    ScreenPtr screen = dirty->src->pScreen;
+    return dirty->src;
 #else
-    ScreenPtr screen = dirty->src->drawable.pScreen;
+    return &dirty->src->drawable;
 #endif
-
-    return radeon_master_screen(screen);
 }
 
 static inline Bool
 radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap)
 {
-#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
-    return dirty->src == &pixmap->drawable;
-#else
-    return dirty->src == pixmap;
-#endif
+    return radeon_dirty_src_drawable(dirty) == &pixmap->drawable;
 }
 
 
@@ -500,6 +500,13 @@ struct radeon_client_priv {
     uint_fast32_t     needs_flush;
 };
 
+struct radeon_device_priv {
+    CursorPtr cursor;
+    Bool sprite_visible;
+};
+
+extern DevScreenPrivateKeyRec radeon_device_private_key;
+
 typedef struct {
     EntityInfoPtr     pEnt;
     pciVideoPtr       PciInfo;
@@ -550,6 +557,12 @@ typedef struct {
     CreateScreenResourcesProcPtr CreateScreenResources;
     CreateWindowProcPtr CreateWindow;
     WindowExposuresProcPtr WindowExposures;
+    void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen,
+                      CursorPtr pCursor, int x, int y);
+    void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
+
+    /* Number of SW cursors currently visible on this screen */
+    int sprites_visible;
 
     Bool              IsSecondary;
 
@@ -622,6 +635,8 @@ typedef struct {
        SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
     } glamor;
 #endif /* USE_GLAMOR */
+
+    xf86CrtcFuncsRec drmmode_crtc_funcs;
 } RADEONInfoRec, *RADEONInfoPtr;
 
 /* radeon_accel.c */
@@ -712,9 +727,9 @@ uint32_t radeon_get_pixmap_tiling(Pixmap
 
 static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
 {
-#ifdef USE_GLAMOR
     ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
+#ifdef USE_GLAMOR
     RADEONInfoPtr info = RADEONPTR(scrn);
 
     if (info->use_glamor) {
@@ -769,6 +784,8 @@ static inline Bool radeon_set_pixmap_bo(
            if (driver_priv->bo)
                radeon_bo_unref(driver_priv->bo);
 
+           drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL);
+
            radeon_bo_ref(bo);
            driver_priv->bo = bo;
 
@@ -819,8 +836,8 @@ static inline Bool radeon_get_pixmap_sha
 }
 
 static inline struct drmmode_fb*
-radeon_fb_create(int drm_fd, uint32_t width, uint32_t height, uint8_t depth,
-                uint8_t bpp, uint32_t pitch, uint32_t handle)
+radeon_fb_create(ScrnInfoPtr scrn, int drm_fd, uint32_t width, uint32_t height,
+                uint32_t pitch, uint32_t handle)
 {
     struct drmmode_fb *fb  = malloc(sizeof(*fb));
 
@@ -828,8 +845,8 @@ radeon_fb_create(int drm_fd, uint32_t wi
        return NULL;
 
     fb->refcnt = 1;
-    if (drmModeAddFB(drm_fd, width, height, depth, bpp, pitch, handle,
-                    &fb->handle) == 0)
+    if (drmModeAddFB(drm_fd, width, height, scrn->depth, scrn->bitsPerPixel,
+                    pitch, handle, &fb->handle) == 0)
        return fb;
 
     free(fb);
@@ -881,9 +898,8 @@ radeon_pixmap_get_fb(PixmapPtr pix)
            ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
            RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
 
-           *fb_ptr = radeon_fb_create(pRADEONEnt->fd, pix->drawable.width,
-                                      pix->drawable.height, 
pix->drawable.depth,
-                                      pix->drawable.bitsPerPixel, pix->devKind,
+           *fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, 
pix->drawable.width,
+                                      pix->drawable.height, pix->devKind,
                                       handle);
        }
     }
Index: src/radeon_dri2.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/radeon_dri2.c,v
retrieving revision 1.11
diff -u -p -r1.11 radeon_dri2.c
--- src/radeon_dri2.c   20 Feb 2018 04:49:20 -0000      1.11
+++ src/radeon_dri2.c   8 Mar 2018 06:43:42 -0000
@@ -125,6 +125,7 @@ radeon_dri2_create_buffer2(ScreenPtr pSc
            cpp = 2;
            break;
        case 24:
+       case 30:
            cpp = 4;
            break;
        default:
@@ -723,7 +724,7 @@ can_flip(xf86CrtcPtr crtc, DrawablePtr d
 
     if (draw->type != DRAWABLE_WINDOW ||
        !info->allowPageFlip ||
-       info->hwcursor_disabled ||
+       info->sprites_visible > 0 ||
        info->drmmode.present_flipping ||
        !pScrn->vtSema ||
        !DRI2CanFlip(draw))
Index: src/radeon_glamor.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/radeon_glamor.c,v
retrieving revision 1.6
diff -u -p -r1.6 radeon_glamor.c
--- src/radeon_glamor.c 20 Feb 2018 04:49:20 -0000      1.6
+++ src/radeon_glamor.c 8 Mar 2018 06:43:42 -0000
@@ -119,6 +119,14 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn)
                return FALSE;
        }
 
+       if (scrn->depth == 30 &&
+           xorgGetVersion() < XORG_VERSION_NUMERIC(1,19,99,1,0)) {
+               xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                          "Depth 30 is not supported by GLAMOR with Xorg < "
+                          "1.19.99.1\n");
+               return FALSE;
+       }
+
 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,0,0,0)
        if (!xf86LoaderCheckSymbol("glamor_egl_init")) {
                xf86DrvMsg(scrn->scrnIndex, s ? X_ERROR : X_WARNING,
Index: src/radeon_kms.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/radeon_kms.c,v
retrieving revision 1.15
diff -u -p -r1.15 radeon_kms.c
--- src/radeon_kms.c    20 Feb 2018 04:49:20 -0000      1.15
+++ src/radeon_kms.c    8 Mar 2018 06:43:42 -0000
@@ -38,6 +38,7 @@
 #include "radeon_reg.h"
 #include "radeon_probe.h"
 #include "micmap.h"
+#include "mipointrst.h"
 
 #include "radeon_version.h"
 #include "shadow.h"
@@ -66,6 +67,7 @@
 #include "radeon_vbo.h"
 
 static DevScreenPrivateKeyRec radeon_client_private_key;
+DevScreenPrivateKeyRec radeon_device_private_key;
 
 extern SymTabRec RADEONChipsets[];
 static Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
@@ -192,18 +194,33 @@ static Bool RADEONGetRec(ScrnInfoPtr pSc
 /* Free our private RADEONInfoRec */
 static void RADEONFreeRec(ScrnInfoPtr pScrn)
 {
+    DevUnion *pPriv;
     RADEONEntPtr pRADEONEnt;
     RADEONInfoPtr  info;
+    EntityInfoPtr pEnt;
 
-    if (!pScrn || !pScrn->driverPrivate) return;
+    if (!pScrn)
+       return;
 
     info = RADEONPTR(pScrn);
+    if (info) {
+       if (info->fbcon_pixmap)
+           pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
+
+       if (info->accel_state) {
+           free(info->accel_state);
+           info->accel_state = NULL;
+       }
 
-    if (info->fbcon_pixmap)
-       pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
-
-    pRADEONEnt = RADEONEntPriv(pScrn);
+       pEnt = info->pEnt;
+       free(pScrn->driverPrivate);
+       pScrn->driverPrivate = NULL;
+    } else {
+       pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
+    }
 
+    pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex);
+    pRADEONEnt = pPriv->ptr;
     if (pRADEONEnt->fd > 0) {
         DevUnion *pPriv;
         RADEONEntPtr pRADEONEnt;
@@ -218,17 +235,12 @@ static void RADEONFreeRec(ScrnInfoPtr pS
                     pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
 #endif
                 drmClose(pRADEONEnt->fd);
-            pRADEONEnt->fd = 0;
+            free(pPriv->ptr);
+            pPriv->ptr = NULL;
         }
     }
 
-    if (info->accel_state) {
-       free(info->accel_state);
-       info->accel_state = NULL;
-    }
-
-    free(pScrn->driverPrivate);
-    pScrn->driverPrivate = NULL;
+    free(pEnt);
 }
 
 static void *
@@ -568,7 +580,8 @@ dirty_region(PixmapDirtyUpdatePtr dirty)
 static void
 redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
 {
-       ScrnInfoPtr pScrn = 
xf86ScreenToScrn(dirty->slave_dst->drawable.pScreen);
+       ScrnInfoPtr src_scrn =
+               xf86ScreenToScrn(radeon_dirty_src_drawable(dirty)->pScreen);
 
        if (RegionNil(region))
                goto out;
@@ -582,7 +595,7 @@ redisplay_dirty(PixmapDirtyUpdatePtr dir
        PixmapSyncDirtyHelper(dirty, region);
 #endif
 
-       radeon_cs_flush_indirect(pScrn);
+       radeon_cs_flush_indirect(src_scrn);
        if (dirty->slave_dst->master_pixmap)
            DamageRegionProcessPending(&dirty->slave_dst->drawable);
 
@@ -1245,6 +1258,7 @@ static Bool RADEONPreInitVisual(ScrnInfo
     case 15:
     case 16:
     case 24:
+    case 30:
        break;
 
     default:
@@ -1331,9 +1345,10 @@ static Bool RADEONPreInitAccel_KMS(ScrnI
        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                   "GPU accel disabled or not working, using shadowfb for 
KMS\n");
 shadowfb:
-       info->r600_shadow_fb = TRUE;
        if (!xf86LoadSubModule(pScrn, "shadow"))
-           info->r600_shadow_fb = FALSE;
+           return FALSE;
+
+       info->r600_shadow_fb = TRUE;
        return TRUE;
     }
 
@@ -1697,7 +1712,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn
         && info->pEnt->location.type != BUS_PLATFORM
 #endif
         )
-        goto fail;
+        return FALSE;
 
     pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
                                 getRADEONEntityIndex());
@@ -1724,24 +1739,24 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn
     pScrn->monitor     = pScrn->confScreen->monitor;
 
     if (!RADEONPreInitVisual(pScrn))
-       goto fail;
+       return FALSE;
 
     xf86CollectOptions(pScrn, NULL);
     if (!(info->Options = malloc(sizeof(RADEONOptions_KMS))))
-       goto fail;
+       return FALSE;
 
     memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS));
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
 
     if (!RADEONPreInitWeight(pScrn))
-       goto fail;
+       return FALSE;
 
     if (!RADEONPreInitChipType_KMS(pScrn))
-        goto fail;
+        return FALSE;
 
     if (radeon_open_drm_master(pScrn) == FALSE) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup 
failed\n");
-       goto fail;
+       return FALSE;
     }
 
     info->dri2.available = FALSE;
@@ -1750,14 +1765,22 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn
     if (info->dri2.pKernelDRMVersion == NULL) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "RADEONDRIGetVersion failed to get the DRM version\n");
-       goto fail;
+       return FALSE;
     }
 
     /* Get ScreenInit function */
     if (!xf86LoadSubModule(pScrn, "fb"))
        return FALSE;
 
-    if (!RADEONPreInitAccel_KMS(pScrn))              goto fail;
+    if (!RADEONPreInitAccel_KMS(pScrn))
+       return FALSE;
+
+    /* Depth 30 only supported since Linux 3.16 / kms driver minor version 39 
*/
+    if (pScrn->depth == 30 && info->dri2.pKernelDRMVersion->version_minor < 
39) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                  "Depth 30 is not supported. Kernel too old. Needs Linux 
3.16+\n");
+       return FALSE;
+    }
 
     radeon_drm_queue_init();
 
@@ -1869,7 +1892,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn
 
     if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == 
FALSE) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup 
failed\n");
-       goto fail;
+       return FALSE;
     }
 
     RADEONSetupCapabilities(pScrn);
@@ -1963,14 +1986,10 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn
 #endif
         ) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
-      goto fail;
-   }
+      return FALSE;
+    }
 
     return TRUE;
- fail:
-    RADEONFreeRec(pScrn);
-    return FALSE;
-
 }
 
 static Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
@@ -1978,12 +1997,48 @@ static Bool RADEONCursorInit_KMS(ScreenP
     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
 
-    return xf86_cursors_init (pScreen, info->cursor_w, info->cursor_h,
-                             (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
-                              HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
-                              HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
-                              HARDWARE_CURSOR_UPDATE_UNHIDDEN |
-                              HARDWARE_CURSOR_ARGB));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+                  "Initializing Cursor\n");
+
+    /* Set Silken Mouse */
+    xf86SetSilkenMouse(pScreen);
+
+    /* Cursor setup */
+    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+    if (info->allowPageFlip) {
+       miPointerScreenPtr PointPriv =
+           dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+       if (!dixRegisterScreenPrivateKey(&radeon_device_private_key, pScreen,
+                                        PRIVATE_DEVICE,
+                                        sizeof(struct radeon_device_priv))) {
+           xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "dixRegisterScreenPrivateKey 
failed\n");
+           return FALSE;
+       }
+
+       if (PointPriv->spriteFuncs->SetCursor != drmmode_sprite_set_cursor) {
+           info->SetCursor = PointPriv->spriteFuncs->SetCursor;
+           info->MoveCursor = PointPriv->spriteFuncs->MoveCursor;
+           PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor;
+           PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor;
+       }
+    }
+
+    if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
+       return TRUE;
+
+    if (!xf86_cursors_init(pScreen, info->cursor_w, info->cursor_h,
+                          HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+                          HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+                          HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+                          HARDWARE_CURSOR_UPDATE_UNHIDDEN |
+                          HARDWARE_CURSOR_ARGB)) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86_cursors_init failed\n");
+       return FALSE;
+    }
+
+    return TRUE;
 }
 
 void
@@ -2126,6 +2181,17 @@ static Bool RADEONCloseScreen_KMS(Screen
 
     pScrn->vtSema = FALSE;
     xf86ClearPrimInitDone(info->pEnt->index);
+
+    if (info->allowPageFlip) {
+       miPointerScreenPtr PointPriv =
+           dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+       if (PointPriv->spriteFuncs->SetCursor == drmmode_sprite_set_cursor) {
+           PointPriv->spriteFuncs->SetCursor = info->SetCursor;
+           PointPriv->spriteFuncs->MoveCursor = info->MoveCursor;
+       }
+    }
+
     pScreen->BlockHandler = info->BlockHandler;
     pScreen->CloseScreen = info->CloseScreen;
     return pScreen->CloseScreen(pScreen);
@@ -2134,14 +2200,9 @@ static Bool RADEONCloseScreen_KMS(Screen
 
 void RADEONFreeScreen_KMS(ScrnInfoPtr pScrn)
 {
-    RADEONInfoPtr  info  = RADEONPTR(pScrn);
-
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
                   "RADEONFreeScreen\n");
 
-    /* when server quits at PreInit, we don't need do this anymore*/
-    if (!info) return;
-
     RADEONFreeRec(pScrn);
 }
 
@@ -2215,7 +2276,7 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScr
        if (info->fb_shadow == NULL) {
            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "Failed to allocate shadow framebuffer\n");
-           info->r600_shadow_fb = FALSE;
+           return FALSE;
        } else {
            if (!fbScreenInit(pScreen, info->fb_shadow,
                              pScrn->virtualX, pScrn->virtualY,
@@ -2326,19 +2387,8 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScr
                   "Initializing DPMS\n");
     xf86DPMSInit(pScreen, xf86DPMSSet, 0);
 
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-                  "Initializing Cursor\n");
-
-    /* Set Silken Mouse */
-    xf86SetSilkenMouse(pScreen);
-
-    /* Cursor setup */
-    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
-
-    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
-       if (RADEONCursorInit_KMS(pScreen)) {
-       }
-    }
+    if (!RADEONCursorInit_KMS(pScreen))
+       return FALSE;
 
     /* DGA setup */
 #ifdef XFreeXDGA
@@ -2423,6 +2473,31 @@ Bool RADEONEnterVT_KMS(ScrnInfoPtr pScrn
 
     radeon_set_drm_master(pScrn);
 
+    if (info->r600_shadow_fb) {
+       int base_align = drmmode_get_base_align(pScrn, info->pixel_bytes, 0);
+       struct radeon_bo *front_bo = radeon_bo_open(info->bufmgr, 0,
+                                                   info->front_bo->size,
+                                                   base_align,
+                                                   RADEON_GEM_DOMAIN_VRAM, 0);
+
+       if (front_bo) {
+           if (radeon_bo_map(front_bo, 1) == 0) {
+               memset(front_bo->ptr, 0, front_bo->size);
+               radeon_bo_unref(info->front_bo);
+               info->front_bo = front_bo;
+           } else {
+               radeon_bo_unref(front_bo);
+               front_bo = NULL;
+           }
+       }
+
+       if (!front_bo) {
+           xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                      "Failed to allocate new scanout BO after VT switch, "
+                      "other DRM masters may see screen contents\n");
+       }
+    }
+
     info->accel_state->XInited3D = FALSE;
     info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
 
@@ -2456,6 +2531,7 @@ CARD32 cleanup_black_fb(OsTimerPtr timer
        drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL);
     }
 
+    TimerFree(timer);
     return 0;
 }
 
@@ -2473,85 +2549,91 @@ pixmap_unref_fb(void *value, XID id, voi
 void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     ScreenPtr pScreen = pScrn->pScreen;
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    struct drmmode_scanout black_scanout = { .pixmap = NULL, .bo = NULL };
-    xf86CrtcPtr crtc;
-    drmmode_crtc_private_ptr drmmode_crtc;
-    unsigned w = 0, h = 0;
-    int i;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
                   "RADEONLeaveVT_KMS\n");
 
-    /* Compute maximum scanout dimensions of active CRTCs */
-    for (i = 0; i < xf86_config->num_crtc; i++) {
-       crtc = xf86_config->crtc[i];
-       drmmode_crtc = crtc->driver_private;
-
-       if (!drmmode_crtc->fb)
-           continue;
-
-       w = max(w, crtc->mode.HDisplay);
-       h = max(h, crtc->mode.VDisplay);
-    }
+    if (!info->r600_shadow_fb) {
+       RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+       xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+       struct drmmode_scanout black_scanout = { .pixmap = NULL, .bo = NULL };
+       xf86CrtcPtr crtc;
+       drmmode_crtc_private_ptr drmmode_crtc;
+       unsigned w = 0, h = 0;
+       int i;
 
-    /* Make all active CRTCs scan out from an all-black framebuffer */
-    if (w > 0 && h > 0) {
-       if (drmmode_crtc_scanout_create(crtc, &black_scanout, w, h)) {
-           struct drmmode_fb *black_fb =
-               radeon_pixmap_get_fb(black_scanout.pixmap);
-
-           radeon_pixmap_clear(black_scanout.pixmap);
-           radeon_cs_flush_indirect(pScrn);
-           radeon_bo_wait(black_scanout.bo);
-
-           for (i = 0; i < xf86_config->num_crtc; i++) {
-               crtc = xf86_config->crtc[i];
-               drmmode_crtc = crtc->driver_private;
-
-               if (drmmode_crtc->fb) {
-                   if (black_fb) {
-                       drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0);
-                   } else {
-                       drmModeSetCrtc(pRADEONEnt->fd,
-                                      drmmode_crtc->mode_crtc->crtc_id, 0, 0,
-                                      0, NULL, 0, NULL);
-                       drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb,
-                                            NULL);
-                   }
+       /* Compute maximum scanout dimensions of active CRTCs */
+       for (i = 0; i < xf86_config->num_crtc; i++) {
+           crtc = xf86_config->crtc[i];
+           drmmode_crtc = crtc->driver_private;
+
+           if (!drmmode_crtc->fb)
+               continue;
+
+           w = max(w, crtc->mode.HDisplay);
+           h = max(h, crtc->mode.VDisplay);
+       }
+
+       /* Make all active CRTCs scan out from an all-black framebuffer */
+       if (w > 0 && h > 0) {
+           if (drmmode_crtc_scanout_create(crtc, &black_scanout, w, h)) {
+               struct drmmode_fb *black_fb =
+                   radeon_pixmap_get_fb(black_scanout.pixmap);
+
+               radeon_pixmap_clear(black_scanout.pixmap);
+               radeon_cs_flush_indirect(pScrn);
+               radeon_bo_wait(black_scanout.bo);
+
+               for (i = 0; i < xf86_config->num_crtc; i++) {
+                   crtc = xf86_config->crtc[i];
+                   drmmode_crtc = crtc->driver_private;
+
+                   if (drmmode_crtc->fb) {
+                       if (black_fb) {
+                           drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0);
+                       } else {
+                           drmModeSetCrtc(pRADEONEnt->fd,
+                                          drmmode_crtc->mode_crtc->crtc_id, 0,
+                                          0, 0, NULL, 0, NULL);
+                           drmmode_fb_reference(pRADEONEnt->fd,
+                                                &drmmode_crtc->fb, NULL);
+                       }
 
-                   if (pScrn->is_gpu) {
-                       if (drmmode_crtc->scanout[0].pixmap)
-                           pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap,
-                                           None, pRADEONEnt);
-                       if (drmmode_crtc->scanout[1].pixmap)
-                           pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
-                                           None, pRADEONEnt);
-                   } else {
-                       drmmode_crtc_scanout_free(drmmode_crtc);
+                       if (pScrn->is_gpu) {
+                           if (drmmode_crtc->scanout[0].pixmap)
+                               pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap,
+                                               None, pRADEONEnt);
+                           if (drmmode_crtc->scanout[1].pixmap)
+                               pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
+                                               None, pRADEONEnt);
+                       } else {
+                           drmmode_crtc_scanout_free(drmmode_crtc);
+                       }
                    }
                }
            }
        }
-    }
 
-    xf86RotateFreeShadow(pScrn);
-    drmmode_crtc_scanout_destroy(&info->drmmode, &black_scanout);
+       xf86RotateFreeShadow(pScrn);
+       drmmode_crtc_scanout_destroy(&info->drmmode, &black_scanout);
 
-    /* Unreference FBs of all pixmaps. After this, the only FB remaining
-     * should be the all-black one being scanned out by active CRTCs
-     */
-    for (i = 0; i < currentMaxClients; i++) {
-       if (i > 0 &&
-           (!clients[i] || clients[i]->clientState != ClientStateRunning))
-            continue;
+       /* Unreference FBs of all pixmaps. After this, the only FB remaining
+        * should be the all-black one being scanned out by active CRTCs
+        */
+       for (i = 0; i < currentMaxClients; i++) {
+           if (i > 0 &&
+               (!clients[i] || clients[i]->clientState != ClientStateRunning))
+               continue;
 
-       FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb,
-                                 pRADEONEnt);
+           FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb,
+                                     pRADEONEnt);
+       }
+
+       pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt);
+    } else {
+       memset(info->front_bo->ptr, 0, info->front_bo->size);
     }
-    pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt);
 
     TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen);
 
Index: src/radeon_present.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/radeon_present.c,v
retrieving revision 1.3
diff -u -p -r1.3 radeon_present.c
--- src/radeon_present.c        20 Feb 2018 04:49:20 -0000      1.3
+++ src/radeon_present.c        8 Mar 2018 06:43:42 -0000
@@ -289,7 +289,7 @@ radeon_present_check_flip(RRCrtcPtr crtc
     if (!info->allowPageFlip)
        return FALSE;
 
-    if (info->hwcursor_disabled)
+    if (info->sprites_visible > 0)
        return FALSE;
 
     if (info->drmmode.dri2_flipping)
Index: src/radeon_textured_video.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-ati/src/radeon_textured_video.c,v
retrieving revision 1.8
diff -u -p -r1.8 radeon_textured_video.c
--- src/radeon_textured_video.c 16 Aug 2013 17:04:13 -0000      1.8
+++ src/radeon_textured_video.c 8 Mar 2018 06:43:42 -0000
@@ -499,11 +499,11 @@ static XF86VideoEncodingRec DummyEncodin
     }
 };
 
-#define NUM_FORMATS 3
+#define NUM_FORMATS 4
 
 static XF86VideoFormatRec Formats[NUM_FORMATS] =
 {
-    {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+    {15, TrueColor}, {16, TrueColor}, {24, TrueColor}, {30, TrueColor}
 };
 
 #define NUM_ATTRIBUTES 2

Reply via email to