[PATCH 2/3] Initial glamor support.

Michel Dänzer michel at daenzer.net
Tue Jul 10 04:03:10 PDT 2012


From: Michel Dänzer <michel.daenzer at 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.daenzer at 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




More information about the xorg-driver-ati mailing list