From: Michel Dänzer <michel.daen...@amd.com>

Enable at build time with --enable-glamor and runtime with

        Option  "AccelMethod" "glamor"

The most notable lack of functionality is XVideo. Use something like VDPAU for
now.

Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
---
 configure.ac          |   14 +++
 man/radeon.man        |   39 ++++---
 src/Makefile.am       |    8 ++
 src/drmmode_display.c |    8 +-
 src/radeon.h          |  105 ++++++++++++++++++-
 src/radeon_accel.c    |    7 +-
 src/radeon_dri2.c     |  240 ++++++++++++++++++++++++++++---------------
 src/radeon_exa.c      |   32 ------
 src/radeon_glamor.c   |  269 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/radeon_glamor.h   |   93 +++++++++++++++++
 src/radeon_kms.c      |   39 ++++---
 11 files changed, 711 insertions(+), 143 deletions(-)
 create mode 100644 src/radeon_glamor.c
 create mode 100644 src/radeon_glamor.h

diff --git a/configure.ac b/configure.ac
index a73dd4e..86199f2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,6 +91,20 @@ AM_CONDITIONAL(LIBUDEV, test x$LIBUDEV = xyes)
 SAVE_CPPFLAGS="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS $XORG_CFLAGS"
 
+AC_MSG_CHECKING([whether to include GLAMOR support])
+AC_ARG_ENABLE(glamor,
+             AS_HELP_STRING([--enable-glamor],
+                            [Enable glamor, a new GL-based acceleration 
[default=no]]),
+             [GLAMOR="$enableval"],
+             [GLAMOR=no])
+AC_MSG_RESULT([$GLAMOR])
+AM_CONDITIONAL(GLAMOR, test x$GLAMOR != xno)
+if test "x$GLAMOR" != "xno"; then
+       PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.3.1])
+       PKG_CHECK_MODULES(LIBGLAMOR_EGL, [glamor-egl])
+       AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration])
+fi
+
 AC_CHECK_DECL(xf86ModeBandwidth,
              [AC_DEFINE(HAVE_XF86MODEBANDWIDTH, 1, [Have xf86ModeBandwidth 
prototype])],
              [],
diff --git a/man/radeon.man b/man/radeon.man
index da0c1cc..be50314 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -211,13 +211,6 @@ For example:
 Option \*qZaphodHeads\*q \*qLVDS,VGA-0\*q
 will assign xrandr outputs LVDS and VGA-0 to this instance of the driver.
 .TP
-.BI "Option \*qEXAVSync\*q \*q" boolean \*q
-This option attempts to avoid tearing by stalling the engine until the display
-controller has passed the destination region.  It reduces tearing at the cost
-of performance and has been known to cause instability on some chips.
-The default is
-.B off.
-.TP
 .BI "Option \*qColorTiling\*q \*q" "boolean" \*q
 The framebuffer can be addressed either in linear or tiled mode. Tiled mode 
can provide
 significant performance benefits with 3D applications.  Tiling will be 
disabled if the drm
@@ -241,6 +234,33 @@ The default value is
 .B off
 for R/RV6XX, R/RV7XX, RS780, RS880, EVERGREEN, and CAYMAN.
 .TP
+.BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
+Enable DRI2 page flipping.  The default is
+.B on.
+Pageflipping is supported on all radeon hardware.
+.TP
+.BI "Option \*qAccelMethod\*q \*q" "string" \*q
+Chooses between available acceleration architectures.  Valid values are
+.B EXA
+and
+.B glamor.
+The default is
+.B EXA.
+
+.PP
+The following driver
+.B Options
+are supported for
+.B EXA
+:
+.TP
+.BI "Option \*qEXAVSync\*q \*q" boolean \*q
+This option attempts to avoid tearing by stalling the engine until the display
+controller has passed the destination region.  It reduces tearing at the cost
+of performance and has been known to cause instability on some chips.
+The default is
+.B off.
+.TP
 .BI "Option \*qEXAPixmaps\*q \*q" boolean \*q
 Under KMS, to avoid thrashing pixmaps in/out of VRAM on low memory cards,
 we use a heuristic based on VRAM amount to determine whether to allow EXA
@@ -259,11 +279,6 @@ the framerate of applications that render frames at less 
than refresh rate.
 .IP
 The default value is
 .B on.
-.TP
-.BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
-Enable DRI2 page flipping.  The default is
-.B on.
-Pageflipping is supported on all radeon hardware.
 
 .SH TEXTURED VIDEO ATTRIBUTES
 The driver supports the following X11 Xv attributes for Textured Video.
diff --git a/src/Makefile.am b/src/Makefile.am
index e857f21..da94927 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -64,6 +64,13 @@ radeon_drv_la_SOURCES = \
        $(RADEON_EXA_SOURCES) \
        $(RADEON_KMS_SRCS)
 
+if GLAMOR
+AM_CFLAGS += @LIBGLAMOR_CFLAGS@
+radeon_drv_la_LIBADD += @LIBGLAMOR_LIBS@
+radeon_drv_la_SOURCES += \
+        radeon_glamor.c
+endif
+
 EXTRA_DIST = \
        radeon_textured_videofuncs.c \
        r600_reg.h \
@@ -88,6 +95,7 @@ EXTRA_DIST = \
        radeon_exa_render.c \
        radeon_exa_funcs.c \
        radeon_exa_shared.h \
+       radeon_glamor.h \
        radeon.h \
        radeon_probe.h \
        radeon_reg.h \
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 27569e5..6a35728 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -101,7 +101,8 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn,
                return NULL;
        }
 
-       exaMoveInPixmap(pixmap);
+       if (!info->use_glamor)
+               exaMoveInPixmap(pixmap);
        radeon_set_pixmap_bo(pixmap, bo);
        if (info->ChipFamily >= CHIP_FAMILY_R600) {
                surface = radeon_get_pixmap_surface(pixmap);
@@ -278,7 +279,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
        uint32_t tiling_flags = 0;
        Bool ret;
 
-       if (info->accelOn == FALSE)
+       if (info->accelOn == FALSE || info->use_glamor)
                goto fallback;
 
        for (i = 0; i < xf86_config->num_crtc; i++) {
@@ -1442,6 +1443,9 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int 
height)
                                       crtc->rotation, crtc->x, crtc->y);
        }
 
+       if (info->use_glamor)
+               radeon_glamor_create_screen_resources(scrn->pScreen);
+
        if (old_fb_id)
                drmModeRmFB(drmmode->fd, old_fb_id);
        if (old_front)
diff --git a/src/radeon.h b/src/radeon.h
index d357dc1..2f05249 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -51,6 +51,7 @@
 
 #include "exa.h"
 
+#include "radeon_glamor.h"
 
                                /* Exa and Cursor Support */
 #include "xf86Cursor.h"
@@ -429,6 +430,7 @@ typedef struct {
     Bool              allowColorTiling2D;
     struct radeon_accel_state *accel_state;
     Bool              accelOn;
+    Bool              use_glamor;
     Bool             exa_pixmaps;
     Bool              exa_force_create;
     XF86ModReqInfo    exaReq;
@@ -522,11 +524,107 @@ extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
                                int num, const char *file,
                                const char *func, int line);
 void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size);
-struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix);
-struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
-void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo);
+
+static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
+{
+#ifdef USE_GLAMOR
+    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
+
+    if (info->use_glamor) {
+       struct radeon_pixmap *priv;
+       priv = radeon_get_pixmap_private(pPix);
+       return priv ? &priv->surface : NULL;
+    } else
+#endif
+    {
+       struct radeon_exa_pixmap_priv *driver_priv;
+       driver_priv = exaGetPixmapDriverPrivate(pPix);
+       return &driver_priv->surface;
+    }
+
+    return NULL;
+}
+
 uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
 
+static inline void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
+{
+#ifdef USE_GLAMOR
+    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
+
+    if (info->use_glamor) {
+       struct radeon_pixmap *priv;
+
+       priv = radeon_get_pixmap_private(pPix);
+       if (priv == NULL && bo == NULL)
+           return;
+
+       if (priv) {
+           if (priv->bo == bo)
+               return;
+
+           if (priv->bo)
+               radeon_bo_unref(priv->bo);
+
+           free(priv);
+           priv = NULL;
+       }
+
+       if (bo) {
+           uint32_t pitch;
+
+           priv = calloc(1, sizeof (struct radeon_pixmap));
+           if (priv == NULL)
+               goto out;
+
+           radeon_bo_ref(bo);
+           priv->bo = bo;
+
+           radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch);
+       }
+out:
+       radeon_set_pixmap_private(pPix, priv);
+    } else
+#endif /* USE_GLAMOR */
+    {
+       struct radeon_exa_pixmap_priv *driver_priv;
+
+       driver_priv = exaGetPixmapDriverPrivate(pPix);
+       if (driver_priv) {
+           uint32_t pitch;
+
+           if (driver_priv->bo)
+               radeon_bo_unref(driver_priv->bo);
+
+           radeon_bo_ref(bo);
+           driver_priv->bo = bo;
+
+           radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
+       }
+    }
+}
+
+static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
+{
+#ifdef USE_GLAMOR
+    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
+
+    if (info->use_glamor) {
+       struct radeon_pixmap *priv;
+       priv = radeon_get_pixmap_private(pPix);
+       return priv ? priv->bo : NULL;
+    } else
+#endif
+    {
+       struct radeon_exa_pixmap_priv *driver_priv;
+       driver_priv = exaGetPixmapDriverPrivate(pPix);
+       return driver_priv->bo;
+    }
+
+    return NULL;
+}
+
+
 #define CP_PACKET0(reg, n)                                             \
        (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
 #define CP_PACKET1(reg0, reg1)                                         \
@@ -659,6 +757,7 @@ static __inline__ void RADEON_SYNC(RADEONInfoPtr info, 
ScrnInfoPtr pScrn)
 }
 
 enum {
+    RADEON_CREATE_PIXMAP_DRI2 = 0x08000000,
     RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000,
     RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000,
     RADEON_CREATE_PIXMAP_DEPTH = 0x40000000, /* for r200 */
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 15cf2bd..8eff5c5 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -182,7 +182,12 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
 
     if (info->directRenderingEnabled) {
-       if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+       if (info->use_glamor) {
+           if (!radeon_glamor_init(pScreen)) {
+               info->use_glamor = FALSE;
+               return FALSE;
+           }
+       } else if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
            if (!EVERGREENDrawInit(pScreen))
                return FALSE;
        } else
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 8c24de9..12b198c 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -73,6 +73,77 @@ struct dri2_buffer_priv {
 };
 
 
+static PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
+{
+    if (drawable->type == DRAWABLE_PIXMAP)
+       return (PixmapPtr)drawable;
+    else
+       return (*drawable->pScreen->GetWindowPixmap)((WindowPtr)drawable);
+}
+
+
+static PixmapPtr fixup_glamor(DrawablePtr drawable, PixmapPtr pixmap)
+{
+       PixmapPtr old = get_drawable_pixmap(drawable);
+#ifdef USE_GLAMOR
+       ScreenPtr screen = drawable->pScreen;
+       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+       struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
+       GCPtr gc;
+
+       /* With a glamor pixmap, 2D pixmaps are created in texture
+        * and without a static BO attached to it. To support DRI,
+        * we need to create a new textured-drm pixmap and
+        * need to copy the original content to this new textured-drm
+        * pixmap, and then convert the old pixmap to a coherent
+        * textured-drm pixmap which has a valid BO attached to it
+        * and also has a valid texture, thus both glamor and DRI2
+        * can access it.
+        *
+        */
+
+       /* Copy the current contents of the pixmap to the bo. */
+       gc = GetScratchGC(drawable->depth, screen);
+       if (gc) {
+               ValidateGC(&pixmap->drawable, gc);
+               gc->ops->CopyArea(&old->drawable, &pixmap->drawable,
+                                 gc,
+                                 0, 0,
+                                 old->drawable.width,
+                                 old->drawable.height,
+                                 0, 0);
+               FreeScratchGC(gc);
+       }
+
+       radeon_set_pixmap_private(pixmap, NULL);
+       screen->DestroyPixmap(pixmap);
+
+       /* And redirect the pixmap to the new bo (for 3D). */
+       radeon_set_pixmap_private(old, priv);
+       old->refcnt++;
+
+       /* This creating should not fail, as we already created its
+        * successfully. But if it happens, we put a warning indicator
+        * here, and the old pixmap will still be a glamor pixmap, and
+        * latter the pixmap_flink will get a 0 name, then the X server
+        * will pass a BadAlloc to the client.*/
+       if (!radeon_glamor_create_textured_pixmap(old))
+               xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                          "Failed to get DRI drawable for glamor pixmap.\n");
+
+       screen->ModifyPixmapHeader(old,
+                                  old->drawable.width,
+                                  old->drawable.height,
+                                  0, 0,
+                                  priv->stride,
+                                  NULL);
+
+#endif /* USE_GLAMOR*/
+
+       return old;
+}
+
+
 #ifndef USE_DRI2_1_1_0
 static BufferPtr
 radeon_dri2_create_buffers(DrawablePtr drawable,
@@ -85,13 +156,13 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
     BufferPtr buffers;
     struct dri2_buffer_priv *privates;
     PixmapPtr pixmap, depth_pixmap;
-    struct radeon_exa_pixmap_priv *driver_priv;
+    struct radeon_bo *bo;
     int i, r, need_enlarge = 0;
     int flags = 0;
     unsigned front_width;
     uint32_t tiling = 0;
 
-    pixmap = screen->GetScreenPixmap(screen);
+    pixmap = pScreen->GetScreenPixmap(pScreen);
     front_width = pixmap->drawable.width;
 
     buffers = calloc(count, sizeof *buffers);
@@ -106,17 +177,25 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
 
     depth_pixmap = NULL;
     for (i = 0; i < count; i++) {
+       Bool is_glamor_pixmap = FALSE;
+       unsigned aligned_width = drawable->width;
+       unsigned aligned_height = drawable->height;
+
         if (attachments[i] == DRI2BufferFrontLeft) {
-            if (drawable->type == DRAWABLE_PIXMAP) {
-                pixmap = (Pixmap*)drawable;
-            } else {
-                pixmap = (*pScreen->GetWindowPixmap)((WindowPtr)drawable);
-            }
-            pixmap->refcnt++;
+            pixmap = get_drawable_pixmap(drawable);
+           if (info->use_glamor && !radeon_get_pixmap_bo(pixmap)) {
+               is_glamor_pixmap = TRUE;
+               aligned_width = pixmap->drawable.width;
+               aligned_height = pixmap->drawable.height;
+               pixmap = NULL;
+           } else
+               pixmap->refcnt++;
         } else if (attachments[i] == DRI2BufferStencil && depth_pixmap) {
             pixmap = depth_pixmap;
             pixmap->refcnt++;
-        } else {
+        }
+
+       if (!pixmap) {
            /* tile the back buffer */
            switch(attachments[i]) {
            case DRI2BufferDepth:
@@ -145,6 +224,8 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
                break;
            case DRI2BufferBackLeft:
            case DRI2BufferBackRight:
+           case DRI2BufferFrontLeft:
+           case DRI2BufferFrontRight:
            case DRI2BufferFakeFrontLeft:
            case DRI2BufferFakeFrontRight:
                if (info->ChipFamily >= CHIP_FAMILY_R600)
@@ -164,14 +245,15 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
            if (flags & RADEON_CREATE_PIXMAP_TILING_MACRO)
                tiling |= RADEON_TILING_MACRO;
 
+           if (aligned_width == front_width)
+               aligned_width = pScrn->virtualX;
+
            if (need_enlarge) {
                /* evergreen uses separate allocations for depth and stencil
                 * so we make an extra large depth buffer to cover stencil
                 * as well.
                 */
-               unsigned aligned_width = drawable->width;
                unsigned width_align = drmmode_get_pitch_align(pScrn, 
drawable->depth / 8, tiling);
-               unsigned aligned_height;
                unsigned height_align = drmmode_get_height_align(pScrn, tiling);
                unsigned base_align = drmmode_get_base_align(pScrn, 
drawable->depth / 8, tiling);
                unsigned pitch_bytes;
@@ -181,42 +263,33 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
                    aligned_width = pScrn->virtualX;
                aligned_width = RADEON_ALIGN(aligned_width, width_align);
                pitch_bytes = aligned_width * (drawable->depth / 8);
-               aligned_height = RADEON_ALIGN(drawable->height, height_align);
+               aligned_height = RADEON_ALIGN(aligned_height, height_align);
                size = pitch_bytes * aligned_height;
                size = RADEON_ALIGN(size, base_align);
                /* add additional size for stencil */
                size += aligned_width * aligned_height;
                aligned_height = RADEON_ALIGN(size / pitch_bytes, height_align);
-
-               pixmap = (*pScreen->CreatePixmap)(pScreen,
-                                                 aligned_width,
-                                                 aligned_height,
-                                                 drawable->depth,
-                                                 flags);
-
-           } else {
-               unsigned aligned_width = drawable->width;
-
-               if (aligned_width == front_width)
-                   aligned_width = pScrn->virtualX;
-
-               pixmap = (*pScreen->CreatePixmap)(pScreen,
-                                                 aligned_width,
-                                                 drawable->height,
-                                                 drawable->depth,
-                                                 flags);
            }
+
+           pixmap = (*pScreen->CreatePixmap)(pScreen,
+                                             aligned_width,
+                                             aligned_height,
+                                             drawable->depth,
+                                             flags | 
RADEON_CREATE_PIXMAP_DRI2);
         }
 
         if (attachments[i] == DRI2BufferDepth) {
             depth_pixmap = pixmap;
         }
-       info->exa_force_create = TRUE;
-       exaMoveInPixmap(pixmap);
-       info->exa_force_create = FALSE;
-        driver_priv = exaGetPixmapDriverPrivate(pixmap);
-       if (!driver_priv ||
-           radeon_gem_get_kernel_name(driver_priv->bo, &buffers[i].name) != 0) 
{
+       if (!info->use_glamor) {
+           info->exa_force_create = TRUE;
+           exaMoveInPixmap(pixmap);
+           info->exa_force_create = FALSE;
+       }
+       if (is_glamor_pixmap)
+           pixmap = fixup_glamor(drawable, pixmap);
+       bo = radeon_get_pixmap_bo(pixmap);
+       if (!bo || radeon_gem_get_kernel_name(bo, &buffers[i].name) != 0) {
            int j;
 
            for (j = 0; j < i; j++)
@@ -249,11 +322,13 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
     BufferPtr buffers;
     struct dri2_buffer_priv *privates;
     PixmapPtr pixmap, depth_pixmap;
-    struct radeon_exa_pixmap_priv *driver_priv;
+    struct radeon_bo *bo;
     int flags;
     unsigned front_width;
     uint32_t tiling = 0;
     unsigned aligned_width = drawable->width;
+    unsigned height = drawable->height;
+    Bool is_glamor_pixmap = FALSE;
 
     pixmap = pScreen->GetScreenPixmap(pScreen);
     front_width = pixmap->drawable.width;
@@ -261,16 +336,20 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
     pixmap = depth_pixmap = NULL;
 
     if (attachment == DRI2BufferFrontLeft) {
-        if (drawable->type == DRAWABLE_PIXMAP) {
-            pixmap = (PixmapPtr)drawable;
-        } else {
-            pixmap = (*pScreen->GetWindowPixmap)((WindowPtr)drawable);
-        }
-        pixmap->refcnt++;
+        pixmap = get_drawable_pixmap(drawable);
+       if (info->use_glamor && !radeon_get_pixmap_bo(pixmap)) {
+           is_glamor_pixmap = TRUE;
+           aligned_width = pixmap->drawable.width;
+           height = pixmap->drawable.height;
+           pixmap = NULL;
+       } else
+           pixmap->refcnt++;
     } else if (attachment == DRI2BufferStencil && depth_pixmap) {
         pixmap = depth_pixmap;
         pixmap->refcnt++;
-    } else {
+    }
+
+    if (!pixmap) {
        /* tile the back buffer */
        switch(attachment) {
        case DRI2BufferDepth:
@@ -310,6 +389,8 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
            break;
        case DRI2BufferBackLeft:
        case DRI2BufferBackRight:
+       case DRI2BufferFrontLeft:
+       case DRI2BufferFrontRight:
        case DRI2BufferFakeFrontLeft:
        case DRI2BufferFakeFrontRight:
            if (info->ChipFamily >= CHIP_FAMILY_R600) {
@@ -336,9 +417,9 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
 
            pixmap = (*pScreen->CreatePixmap)(pScreen,
                                              aligned_width,
-                                             drawable->height,
+                                             height,
                                              (format != 
0)?format:drawable->depth,
-                                             flags);
+                                             flags | 
RADEON_CREATE_PIXMAP_DRI2);
     }
 
     if (!pixmap)
@@ -351,12 +432,15 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
     if (attachment == DRI2BufferDepth) {
         depth_pixmap = pixmap;
     }
-    info->exa_force_create = TRUE;
-    exaMoveInPixmap(pixmap);
-    info->exa_force_create = FALSE;
-    driver_priv = exaGetPixmapDriverPrivate(pixmap);
-    if (!driver_priv ||
-       (radeon_gem_get_kernel_name(driver_priv->bo, &buffers->name) != 0))
+    if (!info->use_glamor) {
+       info->exa_force_create = TRUE;
+       exaMoveInPixmap(pixmap);
+       info->exa_force_create = FALSE;
+    }
+    if (is_glamor_pixmap)
+       pixmap = fixup_glamor(drawable, pixmap);
+    bo = radeon_get_pixmap_bo(pixmap);
+    if (!bo || radeon_gem_get_kernel_name(bo, &buffers->name) != 0)
         goto error;
 
     privates = calloc(1, sizeof(struct dri2_buffer_priv));
@@ -476,11 +560,10 @@ radeon_dri2_copy_region(DrawablePtr drawable,
            if (extents->x1 == 0 && extents->y1 == 0 &&
                extents->x2 == drawable->width &&
                extents->y2 == drawable->height) {
-               struct radeon_exa_pixmap_priv *exa_priv =
-                   exaGetPixmapDriverPrivate(dst_private->pixmap);
+               struct radeon_bo *bo = 
radeon_get_pixmap_bo(dst_private->pixmap);
 
-               if (exa_priv && exa_priv->bo)
-                   radeon_bo_wait(exa_priv->bo);
+               if (bo)
+                   radeon_bo_wait(bo);
            }
        }
     }
@@ -643,7 +726,7 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr 
client,
                          void *data, unsigned int target_msc)
 {
     struct dri2_buffer_priv *back_priv;
-    struct radeon_exa_pixmap_priv *exa_priv;
+    struct radeon_bo *bo;
     DRI2FrameEventPtr flip_info;
 
     /* Main crtc for this drawable shall finally deliver pageflip event. */
@@ -665,9 +748,9 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr 
client,
 
     /* Page flip the full screen buffer */
     back_priv = back->driverPrivate;
-    exa_priv = exaGetPixmapDriverPrivate(back_priv->pixmap);
+    bo = radeon_get_pixmap_bo(back_priv->pixmap);
 
-    return radeon_do_pageflip(scrn, exa_priv->bo, flip_info, ref_crtc_hw_id);
+    return radeon_do_pageflip(scrn, bo, flip_info, ref_crtc_hw_id);
 }
 
 static Bool
@@ -675,19 +758,17 @@ update_front(DrawablePtr draw, DRI2BufferPtr front)
 {
     int r;
     PixmapPtr pixmap;
+    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(draw->pScreen));
     struct dri2_buffer_priv *priv = front->driverPrivate;
-    struct radeon_exa_pixmap_priv *driver_priv;
-
-    if (draw->type == DRAWABLE_PIXMAP)
-       pixmap = (PixmapPtr)draw;
-    else
-       pixmap = (*draw->pScreen->GetWindowPixmap)((WindowPtr)draw);
+    struct radeon_bo *bo;
 
+    pixmap = get_drawable_pixmap(draw);
     pixmap->refcnt++;
 
-    exaMoveInPixmap(pixmap);
-    driver_priv = exaGetPixmapDriverPrivate(pixmap);
-    r = radeon_gem_get_kernel_name(driver_priv->bo, &front->name);
+    if (!info->use_glamor)
+       exaMoveInPixmap(pixmap);
+    bo = radeon_get_pixmap_bo(pixmap);
+    r = radeon_gem_get_kernel_name(bo, &front->name);
     if (r) {
        (*draw->pScreen->DestroyPixmap)(pixmap);
        return FALSE;
@@ -753,10 +834,9 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, 
DRI2BufferPtr front, DRI2BufferPt
 {
     struct dri2_buffer_priv *front_priv = front->driverPrivate;
     struct dri2_buffer_priv *back_priv = back->driverPrivate;
-    struct radeon_exa_pixmap_priv *front_radeon, *back_radeon;
+    struct radeon_bo *front_bo, *back_bo;
     ScreenPtr screen;
     RADEONInfoPtr info;
-    struct radeon_bo *bo;
     int tmp;
 
     /* Swap BO names so DRI works */
@@ -765,22 +845,22 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, 
DRI2BufferPtr front, DRI2BufferPt
     back->name = tmp;
 
     /* Swap pixmap bos */
-    front_radeon = exaGetPixmapDriverPrivate(front_priv->pixmap);
-    back_radeon = exaGetPixmapDriverPrivate(back_priv->pixmap);
-    bo = back_radeon->bo;
-    back_radeon->bo = front_radeon->bo;
-    front_radeon->bo = bo;
+    front_bo = radeon_get_pixmap_bo(front_priv->pixmap);
+    back_bo = radeon_get_pixmap_bo(back_priv->pixmap);
+    radeon_set_pixmap_bo(front_priv->pixmap, back_bo);
+    radeon_set_pixmap_bo(back_priv->pixmap, front_bo);
 
     /* Do we need to update the Screen? */
     screen = draw->pScreen;
     info = RADEONPTR(xf86ScreenToScrn(screen));
-    if (front_radeon->bo == info->front_bo) {
+    if (front_bo == info->front_bo) {
+       radeon_bo_ref(back_bo);
        radeon_bo_unref(info->front_bo);
-       info->front_bo = back_radeon->bo;
-       radeon_bo_ref(info->front_bo);
-       front_radeon = 
exaGetPixmapDriverPrivate(screen->GetScreenPixmap(screen));
-        front_radeon->bo = bo;
+       info->front_bo = back_bo;
+       radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), back_bo);
     }
+
+    radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap);
 }
 
 void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index d80c7e4..5c5d997 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -325,20 +325,6 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void 
*driverPriv)
     free(driverPriv);
 }
 
-struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
-{
-    struct radeon_exa_pixmap_priv *driver_priv;
-    driver_priv = exaGetPixmapDriverPrivate(pPix);
-    return driver_priv->bo;
-}
-
-struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
-{
-    struct radeon_exa_pixmap_priv *driver_priv;
-    driver_priv = exaGetPixmapDriverPrivate(pPix);
-    return &driver_priv->surface;
-}
-
 uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix)
 {
     struct radeon_exa_pixmap_priv *driver_priv;
@@ -346,24 +332,6 @@ uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix)
     return driver_priv->tiling_flags;
 }
 
-void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
-{
-    struct radeon_exa_pixmap_priv *driver_priv;
-
-    driver_priv = exaGetPixmapDriverPrivate(pPix);
-    if (driver_priv) {
-       uint32_t pitch;
-
-       if (driver_priv->bo)
-           radeon_bo_unref(driver_priv->bo);
-
-       radeon_bo_ref(bo);
-       driver_priv->bo = bo;
-
-       radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
-    }
-}
-
 Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix)
 {
     struct radeon_exa_pixmap_priv *driver_priv;
diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c
new file mode 100644
index 0000000..232332e
--- /dev/null
+++ b/src/radeon_glamor.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright © 2011 Intel Corporation.
+ *             2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xf86.h>
+#define GLAMOR_FOR_XORG  1
+#include <glamor.h>
+
+#include "radeon.h"
+#include "radeon_bo_helper.h"
+
+#if HAS_DEVPRIVATEKEYREC
+DevPrivateKeyRec glamor_pixmap_index;
+#else
+int glamor_pixmap_index;
+#endif
+
+void
+radeon_glamor_exchange_buffers(PixmapPtr src,
+                              PixmapPtr dst)
+{
+       RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(dst->drawable.pScreen));
+
+       if (!info->use_glamor)
+               return;
+       glamor_egl_exchange_buffers(src, dst);
+}
+
+Bool
+radeon_glamor_create_screen_resources(ScreenPtr screen)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+       RADEONInfoPtr info = RADEONPTR(scrn);
+
+       if (!info->use_glamor)
+               return TRUE;
+
+       if (!glamor_glyphs_init(screen))
+               return FALSE;
+
+       if (!glamor_egl_create_textured_screen_ext(screen,
+                                                  info->front_bo->handle,
+                                                  scrn->displayWidth *
+                                                  info->pixel_bytes,
+                                                  NULL))
+               return FALSE;
+
+       return TRUE;
+}
+
+
+Bool
+radeon_glamor_pre_init(ScrnInfoPtr scrn)
+{
+       RADEONInfoPtr info = RADEONPTR(scrn);
+       pointer glamor_module;
+       CARD32 version;
+       const char *s;
+
+       s = xf86GetOptValString(info->Options, OPTION_ACCELMETHOD);
+       if (s == NULL)
+               return FALSE;
+
+       if (strcasecmp(s, "glamor") != 0)
+               return FALSE;
+
+       /* Load glamor module */
+       if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) {
+               version = xf86GetModuleVersion(glamor_module);
+               if (version < MODULE_VERSION_NUMERIC(0,3,1)) {
+                       xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                       "Incompatible glamor version, required >= 0.3.0.\n");
+                       return FALSE;
+               } else {
+                       if (glamor_egl_init(scrn, info->dri2.drm_fd)) {
+                               xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                                          "glamor detected, initialising EGL 
layer.\n");
+                       } else {
+                               xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                                          "glamor detected, failed to 
initialize EGL.\n");
+                               return FALSE;
+                       }
+               }
+       } else {
+               xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glamor not available\n");
+               return FALSE;
+       }
+
+       info->use_glamor = TRUE;
+
+       return TRUE;
+}
+
+Bool
+radeon_glamor_create_textured_pixmap(PixmapPtr pixmap)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+       RADEONInfoPtr info = RADEONPTR(scrn);
+       struct radeon_pixmap *priv;
+
+       if ((info->use_glamor) == 0)
+               return TRUE;
+
+       priv = radeon_get_pixmap_private(pixmap);
+       if (glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle,
+                                             priv->stride))
+               return TRUE;
+       else
+               return FALSE;
+}
+
+static PixmapPtr
+radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+                       unsigned usage)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+       struct radeon_pixmap *priv;
+       PixmapPtr pixmap, new_pixmap = NULL;
+
+       if (!(usage & RADEON_CREATE_PIXMAP_DRI2)) {
+               pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
+               if (pixmap)
+                       return pixmap;
+       }
+
+       if (w > 32767 || h > 32767)
+               return NullPixmap;
+
+       if (depth == 1)
+               return fbCreatePixmap(screen, w, h, depth, usage);
+
+       if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32)
+               return fbCreatePixmap(screen, w, h, depth, usage);
+
+       pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
+       if (pixmap == NullPixmap)
+               return pixmap;
+
+       if (w && h) {
+               priv = calloc(1, sizeof (struct radeon_pixmap));
+               if (priv == NULL)
+                       goto fallback_pixmap;
+
+               priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage,
+                                                 pixmap->drawable.bitsPerPixel,
+                                                 &priv->stride,
+                                                 &priv->surface,
+                                                 &priv->tiling_flags);
+               if (!priv->bo)
+                       goto fallback_priv;
+
+               radeon_set_pixmap_private(pixmap, priv);
+
+               screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, priv->stride, 
NULL);
+
+               if (!radeon_glamor_create_textured_pixmap(pixmap))
+                       goto fallback_glamor;
+       }
+
+       return pixmap;
+
+fallback_glamor:
+       if (usage & RADEON_CREATE_PIXMAP_DRI2) {
+       /* XXX need further work to handle the DRI2 failure case.
+        * Glamor don't know how to handle a BO only pixmap. Put
+        * a warning indicator here.
+        */
+               xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                          "Failed to create textured DRI2 pixmap.");
+               return pixmap;
+       }
+       /* Create textured pixmap failed means glamor failed to
+        * create a texture from current BO for some reasons. We turn
+        * to create a new glamor pixmap and clean up current one.
+        * One thing need to be noted, this new pixmap doesn't
+        * has a priv and bo attached to it. It's glamor's responsbility
+        * to take care of it. Glamor will mark this new pixmap as a
+        * texture only pixmap and will never fallback to DDX layer
+        * afterwards.
+        */
+       new_pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
+       radeon_bo_unref(priv->bo);
+fallback_priv:
+       free(priv);
+fallback_pixmap:
+       fbDestroyPixmap(pixmap);
+       if (new_pixmap)
+               return new_pixmap;
+       else
+               return fbCreatePixmap(screen, w, h, depth, usage);
+}
+
+static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap)
+{
+       if (pixmap->refcnt == 1) {
+               glamor_egl_destroy_textured_pixmap(pixmap);
+               radeon_set_pixmap_bo(pixmap, NULL);
+       }
+       fbDestroyPixmap(pixmap);
+       return TRUE;
+}
+
+Bool
+radeon_glamor_init(ScreenPtr screen)
+{
+       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+       if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS | GLAMOR_USE_EGL_SCREEN 
|
+                        GLAMOR_USE_SCREEN | GLAMOR_USE_PICTURE_SCREEN)) {
+               xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                          "Failed to initialize glamor.\n");
+               return FALSE;
+       }
+
+       if (!glamor_egl_init_textured_pixmap(screen)) {
+               xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                          "Failed to initialize textured pixmap of screen for 
glamor.\n");
+               return FALSE;
+       }
+
+#if HAS_DIXREGISTERPRIVATEKEY
+       if (!dixRegisterPrivateKey(&glamor_pixmap_index, PRIVATE_PIXMAP, 0))
+#else
+       if (!dixRequestPrivate(&glamor_pixmap_index, 0))
+#endif
+               return FALSE;
+
+       screen->CreatePixmap = radeon_glamor_create_pixmap;
+       screen->DestroyPixmap = radeon_glamor_destroy_pixmap;
+
+       xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                  "Use GLAMOR acceleration.\n");
+       return TRUE;
+}
+
+void
+radeon_glamor_flush(ScrnInfoPtr pScrn)
+{
+       RADEONInfoPtr info = RADEONPTR(pScrn);
+
+       if (info->use_glamor)
+               glamor_block_handler(pScrn->pScreen);
+}
diff --git a/src/radeon_glamor.h b/src/radeon_glamor.h
new file mode 100644
index 0000000..40c9092
--- /dev/null
+++ b/src/radeon_glamor.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2011 Intel Corporation.
+ *             2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef RADEON_GLAMOR_H
+#define RADEON_GLAMOR_H
+
+#ifdef USE_GLAMOR
+
+#include "radeon_surface.h"
+
+Bool radeon_glamor_pre_init(ScrnInfoPtr scrn);
+Bool radeon_glamor_init(ScreenPtr screen);
+Bool radeon_glamor_create_screen_resources(ScreenPtr screen);
+void radeon_glamor_free_screen(int scrnIndex, int flags);
+
+void radeon_glamor_flush(ScrnInfoPtr pScrn);
+
+Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap);
+void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst);
+
+Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap);
+
+struct radeon_pixmap {
+       struct radeon_surface surface;
+       struct radeon_bo *bo;
+
+       uint32_t tiling_flags;
+       int stride;
+};
+
+#if HAS_DEVPRIVATEKEYREC
+extern DevPrivateKeyRec glamor_pixmap_index;
+#else
+extern int glamor_pixmap_index;
+#endif
+
+static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
+{
+#if HAS_DEVPRIVATEKEYREC
+       return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
+#else
+       return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
+#endif
+}
+
+static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct 
radeon_pixmap *priv)
+{
+       dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
+}
+
+#else
+
+static inline Bool radeon_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; }
+static inline Bool radeon_glamor_init(ScreenPtr screen) { return FALSE; }
+static inline Bool radeon_glamor_create_screen_resources(ScreenPtr screen) { 
return FALSE; }
+static inline void radeon_glamor_free_screen(int scrnIndex, int flags) { }
+
+static inline void radeon_glamor_flush(ScrnInfoPtr pScrn) { }
+
+static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap) { 
return FALSE; }
+
+static inline void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr 
dst) {}
+
+static inline Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap) { 
return FALSE; }
+
+static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr 
pixmap) { return NULL; }
+
+#endif
+
+#endif /* RADEON_GLAMOR_H */
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 61d6419..5d9ccff 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -224,7 +224,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr 
pScreen)
            return FALSE;
     }
 
-    if (info->dri2.enabled) {
+    if (info->dri2.enabled || info->use_glamor) {
        if (info->front_bo) {
            PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
            radeon_set_pixmap_bo(pPix, info->front_bo);
@@ -234,6 +234,10 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr 
pScreen)
            }
        }
     }
+
+    if (info->use_glamor)
+       radeon_glamor_create_screen_resources(pScreen);
+
     return TRUE;
 }
 
@@ -247,6 +251,9 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
     (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
     pScreen->BlockHandler = RADEONBlockHandler_KMS;
 
+    if (info->use_glamor)
+       radeon_glamor_flush(pScrn);
+
     radeon_cs_flush_indirect(pScrn);
 }
 
@@ -258,6 +265,7 @@ radeon_flush_callback(CallbackListPtr *list,
 
     if (pScrn->vtSema) {
         radeon_cs_flush_indirect(pScrn);
+       radeon_glamor_flush(pScrn);
     }
 }
 
@@ -416,6 +424,9 @@ static Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn)
        return TRUE;
     }
 
+    if (radeon_glamor_pre_init(pScrn))
+       return TRUE;
+
     if (info->ChipFamily == CHIP_FAMILY_PALM) {
        info->accel_state->allowHWDFS = RADEONIsFusionGARTWorking(pScrn);
     } else
@@ -838,16 +849,18 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
        }
     }
 
-    info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
-                                             OPTION_EXA_PIXMAPS, 
-                                            ((info->vram_size > (32 * 1024 * 
1024) &&
-                                             info->RenderAccel)));
-    if (info->exa_pixmaps)
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-               "EXA: Driver will allow EXA pixmaps in VRAM\n");
-    else
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-               "EXA: Driver will not allow EXA pixmaps in VRAM\n");
+    if (!info->use_glamor) {
+       info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
+                                                OPTION_EXA_PIXMAPS,
+                                                ((info->vram_size > (32 * 1024 
* 1024) &&
+                                                info->RenderAccel)));
+       if (info->exa_pixmaps)
+           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                      "EXA: Driver will allow EXA pixmaps in VRAM\n");
+       else
+           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                      "EXA: Driver will not allow EXA pixmaps in VRAM\n");
+    }
 
     /* no tiled scanout on r6xx+ yet */
     if (info->allowColorTiling) {
@@ -1186,7 +1199,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
      */
     /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
 #endif
-    if (info->r600_shadow_fb == FALSE) {
+    if (!info->use_glamor && info->r600_shadow_fb == FALSE) {
         /* Init Xv */
         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
                        "Initializing Xv\n");
@@ -1322,7 +1335,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
        xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
        return FALSE;
     }
-    if (info->r600_shadow_fb == FALSE) {
+    if (!info->use_glamor && info->r600_shadow_fb == FALSE) {
         info->accel_state->exa = exaDriverAlloc();
         if (info->accel_state->exa == NULL) {
            xf86DrvMsg(pScreen->myNum, X_ERROR, "exaDriverAlloc failed\n");
-- 
1.7.10.4


_______________________________________________
xorg-driver-ati mailing list
xorg-driver-ati@lists.x.org
http://lists.x.org/mailman/listinfo/xorg-driver-ati

Reply via email to