[PATCH 17/18] Add glamor back into the driver

Keith Packard keithp at keithp.com
Sat Aug 16 23:13:20 PDT 2014


This adds glamor support back into the driver, but instad of going
through UXA, this uses it directly instead. Supports DRI2 directly and
DRI3 via glamor.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 configure.ac            |  42 ++++++-
 src/intel_driver.h      |   2 +-
 src/intel_module.c      |   5 +-
 src/uxa/Makefile.am     |  46 +++++--
 src/uxa/intel.h         |  11 ++
 src/uxa/intel_display.c |  25 +++-
 src/uxa/intel_dri.c     | 188 +++++++++++++---------------
 src/uxa/intel_driver.c  | 322 +++++++++++++++++++++++++++++++++++++-----------
 src/uxa/intel_glamor.c  | 290 +++++++++++++++++++++++++++++++++++++++++++
 src/uxa/intel_glamor.h  |  60 +++++++++
 src/uxa/intel_uxa.c     | 100 +++++++++++++++
 src/uxa/intel_uxa.h     |   8 ++
 src/uxa/intel_video.c   |  65 +++++++---
 13 files changed, 949 insertions(+), 215 deletions(-)
 create mode 100644 src/uxa/intel_glamor.c
 create mode 100644 src/uxa/intel_glamor.h

diff --git a/configure.ac b/configure.ac
index 80ffea2..2126f35 100644
--- a/configure.ac
+++ b/configure.ac
@@ -401,6 +401,22 @@ if test "x$UXA" != "xno"; then
 	UXA=yes
 fi
 
+AC_ARG_ENABLE(glamor,
+	      AS_HELP_STRING([--enable-glamor],
+			     [Enable glamor, a new GL-based acceleration [default=no]]),
+	      [GLAMOR="$enableval"],
+	      [GLAMOR="no"])
+if test "x$GLAMOR" != "xno"; then
+	if pkg-config --exists "xorg-server >= 1.15.99.901"; then
+		GLAMOR="yes (using Xorg glamor module)"
+	else
+		PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.6.0])
+		PKG_CHECK_MODULES(LIBGLAMOR_EGL, [glamor-egl])
+		GLAMOR="yes (using libglamor)"
+	fi
+	AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration])
+fi
+
 PKG_CHECK_MODULES(XORG, [xorg-server >= $required_xorg_server_version xproto fontsproto pixman-1 >= $required_pixman_version $REQUIRED_MODULES])
 ABI_VERSION=`$PKG_CONFIG --variable=abi_videodrv xorg-server`
 
@@ -603,6 +619,10 @@ AC_MSG_CHECKING([whether to include UXA support])
 AC_MSG_RESULT([$UXA])
 AM_CONDITIONAL(UXA, test "x$UXA" != "xno")
 
+AC_MSG_CHECKING([whether to include GLAMOR support])
+AC_MSG_RESULT([$GLAMOR])
+AM_CONDITIONAL(GLAMOR, test "x$GLAMOR" != "xno")
+
 AC_MSG_CHECKING([whether to include SNA support])
 AM_CONDITIONAL(SNA, test "x$SNA" != "xno")
 AC_MSG_RESULT([$SNA])
@@ -623,7 +643,7 @@ fi
 
 AC_ARG_WITH(default-accel,
 	    AS_HELP_STRING([--with-default-accel],
-			   [Select the default acceleration method out of none, sna, or uxa  [default is sna if enabled, otherwise uxa]]),
+			   [Select the default acceleration method out of glamor, none, sna, or uxa  [default is sna if enabled, otherwise uxa]]),
 			   [accel="$withval"],
 			   [accel="auto"])
 if test "x$accel" = "xyes"; then
@@ -638,6 +658,10 @@ if test "x$accel" = "xauto"; then
 	else
 		if test "x$UXA" != "xno"; then
 			accel="uxa"
+		else
+			if test "x$GLAMOR" != "xno"; then
+				accel="glamor"
+			fi
 		fi
 	fi
 	if test "x$accel" = "xauto" -a "x$KMS" = "xyes"; then
@@ -664,6 +688,15 @@ if test "x$accel" = "xuxa"; then
 	fi
 fi
 
+if test "x$accel" = "xglamor"; then
+	if test "x$GLAMOR" != "xno"; then
+		AC_DEFINE(DEFAULT_ACCEL_METHOD, GLAMOR, [Default acceleration method])
+		have_accel="yes"
+	else
+		AC_MSG_ERROR([glamor acceleration requested as default, but is not enabled])
+	fi
+fi
+
 if test "x$have_accel" = "xnone"; then
 	if test "x$KMS" = "xyes"; then
 		if test "x$SNA" != "xno" -o "x$UXA" != "xno"; then
@@ -851,6 +884,13 @@ if test "x$UXA" != "xno"; then
 		accel_msg="$accel_msg uxa"
 	fi
 fi
+if test "x$GLAMOR" != "xno"; then
+	if test "$accel" = "glamor"; then
+		accel_msg="$accel_msg *glamor"
+	else
+		accel_msg="$accel_msg glamor"
+	fi
+fi
 
 if test "x$dri_msg" = "x"; then
 	dri_msg=" none"
diff --git a/src/intel_driver.h b/src/intel_driver.h
index 172ebc4..13e2688 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -136,7 +136,7 @@ int intel_put_master(ScrnInfoPtr scrn);
 void intel_put_device(ScrnInfoPtr scrn);
 
 #define IS_DEFAULT_ACCEL_METHOD(x) ({ \
-	enum { NOACCEL, SNA, UXA } default_accel_method__ = DEFAULT_ACCEL_METHOD; \
+	enum { NOACCEL, SNA, UXA, GLAMOR } default_accel_method__ = DEFAULT_ACCEL_METHOD; \
 	default_accel_method__ == x; \
 })
 
diff --git a/src/intel_module.c b/src/intel_module.c
index d7b42f6..57ac5ef 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -489,7 +489,7 @@ _xf86findDriver(const char *ident, XF86ConfDevicePtr p)
 	return NULL;
 }
 
-static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
+static enum accel_method { NOACCEL, SNA, UXA, GLAMOR } get_accel_method(void)
 {
 	enum accel_method accel_method = DEFAULT_ACCEL_METHOD;
 	XF86ConfDevicePtr dev;
@@ -509,6 +509,8 @@ static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
 				accel_method = SNA;
 			else if (strcasecmp(s, "uxa") == 0)
 				accel_method = UXA;
+			else if (strcasecmp(s, "glamor") == 0)
+				accel_method = GLAMOR;
 		}
 	}
 
@@ -570,6 +572,7 @@ intel_scrn_create(DriverPtr		driver,
 #if !USE_SNA
 	case NOACCEL:
 #endif
+	case GLAMOR:
 	case UXA:
 		  return intel_init_scrn(scrn);
 #endif
diff --git a/src/uxa/Makefile.am b/src/uxa/Makefile.am
index 426f598..5d342d3 100644
--- a/src/uxa/Makefile.am
+++ b/src/uxa/Makefile.am
@@ -25,21 +25,26 @@ AM_CFLAGS += -I$(top_srcdir)/xvmc -I$(top_srcdir)/src -I$(top_srcdir)/src/render
 noinst_LTLIBRARIES = libuxa.la
 libuxa_la_LIBADD = $(UDEV_LIBS) $(DRMINTEL_LIBS) $(DRM_LIBS)
 libuxa_la_SOURCES = \
-	intel_uxa.h \
-	brw_defines.h \
-	brw_structs.h \
 	common.h \
 	intel.h \
-	intel_batchbuffer.c \
-	intel_batchbuffer.h \
 	intel_display.c \
 	intel_driver.c \
+	intel_glamor.h \
 	intel_memory.c \
-	intel_uxa.c \
 	intel_video.c \
 	intel_video.h \
 	intel_video_overlay.c \
 	intel_video_overlay.h \
+	$(NULL)
+
+if UXA
+libuxa_la_SOURCES += \
+	intel_uxa.h \
+	intel_batchbuffer.c \
+	intel_batchbuffer.h \
+	brw_defines.h \
+	brw_structs.h \
+	intel_uxa.c \
 	intel_uxa_video.c \
 	i830_3d.c \
 	i830_render.c \
@@ -60,8 +65,18 @@ libuxa_la_SOURCES = \
 	uxa-glyphs.c \
 	uxa-render.c \
 	uxa-priv.h \
-	uxa-unaccel.c
+	uxa-unaccel.c \
+	 $(NULL)
+endif
+
+if GLAMOR
+AM_CFLAGS += $(LIBGLAMOR_CFLAGS)
+libuxa_la_LIBADD += $(LIBGLAMOR_LIBS)
+libuxa_la_SOURCES += \
+	intel_glamor.h \
+	intel_glamor.c \
 	$(NULL)
+endif
 
 if DRI2
 AM_CFLAGS += $(DRI2_CFLAGS)
@@ -74,6 +89,17 @@ libuxa_la_LIBADD += \
 	$(NULL)
 endif
 
+if UXA
+
+if XVMC
+AM_CFLAGS += -I$(top_srcdir)/xvmc
+libuxa_la_SOURCES += \
+	intel_hwmc.c \
+	$(NULL)
+endif
+
+endif
+
 if DRI3
 libuxa_la_SOURCES += \
 	intel_dri3.c \
@@ -87,9 +113,3 @@ libuxa_la_SOURCES += \
 	$(NULL)
 endif
 
-if XVMC
-AM_CFLAGS += -I$(top_srcdir)/xvmc
-libuxa_la_SOURCES += \
-	intel_hwmc.c \
-	$(NULL)
-endif
diff --git a/src/uxa/intel.h b/src/uxa/intel.h
index bc61a3e..b1902a2 100644
--- a/src/uxa/intel.h
+++ b/src/uxa/intel.h
@@ -111,10 +111,21 @@ enum dri_type {
 	DRI_ACTIVE
 };
 
+enum accel_type {
+#if USE_GLAMOR
+        ACCEL_GLAMOR,
+#endif
+#if USE_UXA
+        ACCEL_UXA,
+#endif
+};
+
 typedef struct intel_screen_private {
 	ScrnInfoPtr scrn;
 	int cpp;
 
+        enum accel_type accel;
+
 #define RENDER_BATCH			I915_EXEC_RENDER
 #define BLT_BATCH			I915_EXEC_BLT
 	unsigned int current_batch;
diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index 3314598..14a7398 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -60,6 +60,10 @@
 #include "intel_uxa.h"
 #endif
 
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
+
 #define KNOWN_MODE_FLAGS ((1<<14)-1)
 
 struct intel_drm_queue {
@@ -686,7 +690,10 @@ intel_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 		return TRUE;
 	}
 
-	bo = intel_get_pixmap_bo(ppix);
+        bo = intel_get_pixmap_bo(ppix);
+        if (!bo)
+                return FALSE;
+
 	if (intel->front_buffer) {
 		ErrorF("have front buffer\n");
 	}
@@ -1475,8 +1482,20 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 	scrn->virtualX = width;
 	scrn->virtualY = height;
 
-	if (!intel_uxa_create_screen_resources(scrn->pScreen))
-		goto fail;
+        switch (intel->accel) {
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                if (!intel_glamor_create_screen_resources(scrn->pScreen))
+                        goto fail;
+                break;
+#endif
+#if USE_UXA
+        case ACCEL_UXA:
+                if (!intel_uxa_create_screen_resources(scrn->pScreen))
+                        goto fail;
+                break;
+#endif
+        }
 
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
diff --git a/src/uxa/intel_dri.c b/src/uxa/intel_dri.c
index b302221..f191af7 100644
--- a/src/uxa/intel_dri.c
+++ b/src/uxa/intel_dri.c
@@ -69,6 +69,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #if USE_UXA
 #include "intel_uxa.h"
 #endif
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
 
 typedef struct {
 	int refcnt;
@@ -83,16 +86,28 @@ static int i830_client_key;
 
 static uint32_t pixmap_flink(PixmapPtr pixmap)
 {
-	struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap);
+        dri_bo *bo = intel_get_pixmap_bo(pixmap);
 	uint32_t name;
 
-	if (priv == NULL || priv->bo == NULL)
+	if (bo == NULL)
 		return 0;
 
-	if (dri_bo_flink(priv->bo, &name) != 0)
+	if (dri_bo_flink(bo, &name) != 0)
 		return 0;
 
-	priv->pinned |= PIN_DRI2;
+#if USE_UXA
+        switch (intel_get_screen_private(xf86ScreenToScrn(pixmap->drawable.pScreen))->accel) {
+        case ACCEL_UXA:
+        {
+                struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap);
+                priv->pinned |= PIN_DRI2;
+
+                break;
+        }
+        default:
+                break;
+        }
+#endif
 	return name;
 }
 
@@ -381,81 +396,15 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
 	(*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0);
 	ValidateGC(dst, gc);
 
-	/* Wait for the scanline to be outside the region to be copied */
-	if (scrn->vtSema &&
-	    pixmap_is_scanout(get_drawable_pixmap(dst)) &&
-	    intel->swapbuffers_wait && INTEL_INFO(intel)->gen < 060) {
-		BoxPtr box;
-		BoxRec crtcbox;
-		int y1, y2;
-		int event, load_scan_lines_pipe;
-		xf86CrtcPtr crtc;
-		Bool full_height = FALSE;
-
-		box = REGION_EXTENTS(unused, gc->pCompositeClip);
-		crtc = intel_covering_crtc(scrn, box, NULL, &crtcbox);
-
-		/*
-		 * Make sure the CRTC is valid and this is the real front
-		 * buffer
-		 */
-		if (crtc != NULL && !crtc->rotatedData) {
-			int pipe = intel_crtc_to_pipe(crtc);
-
-			/*
-			 * Make sure we don't wait for a scanline that will
-			 * never occur
-			 */
-			y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0;
-			y2 = (box->y2 <= crtcbox.y2) ?
-			    box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1;
-
-			if (y1 == 0 && y2 == (crtcbox.y2 - crtcbox.y1))
-			    full_height = TRUE;
-
-			/*
-			 * Pre-965 doesn't have SVBLANK, so we need a bit
-			 * of extra time for the blitter to start up and
-			 * do its job for a full height blit
-			 */
-			if (full_height && INTEL_INFO(intel)->gen < 040)
-			    y2 -= 2;
-
-			if (pipe == 0) {
-				event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
-				load_scan_lines_pipe =
-				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
-				if (full_height && INTEL_INFO(intel)->gen >= 040)
-				    event = MI_WAIT_FOR_PIPEA_SVBLANK;
-			} else {
-				event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
-				load_scan_lines_pipe =
-				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
-				if (full_height && INTEL_INFO(intel)->gen >= 040)
-				    event = MI_WAIT_FOR_PIPEB_SVBLANK;
-			}
-
-			if (crtc->mode.Flags & V_INTERLACE) {
-				/* DSL count field lines */
-				y1 /= 2;
-				y2 /= 2;
-			}
-
-			BEGIN_BATCH(5);
-			/*
-			 * The documentation says that the LOAD_SCAN_LINES
-			 * command always comes in pairs. Don't ask me why.
-			 */
-			OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
-				  load_scan_lines_pipe);
-			OUT_BATCH((y1 << 16) | (y2-1));
-			OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
-				  load_scan_lines_pipe);
-			OUT_BATCH((y1 << 16) | (y2-1));
-			OUT_BATCH(MI_WAIT_FOR_EVENT | event);
-			ADVANCE_BATCH();
-		}
-	}
+        switch (intel->accel) {
+#if USE_UXA
+        case ACCEL_UXA:
+                intel_uxa_wait_scanline(dst, gc);
+                break;
+#endif
+        default:
+                break;
+        }
 
 	/* It's important that this copy gets submitted before the
 	 * direct rendering client submits rendering for the next
@@ -477,7 +426,7 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
 	/* And make sure the WAIT_FOR_EVENT is queued before any
 	 * modesetting/dpms operations on the pipe.
 	 */
-	intel_batch_submit(scrn);
+	intel_flush(intel);
 }
 
 static void
@@ -671,10 +620,9 @@ i830_dri2_del_frame_event(DRI2FrameEventPtr info)
 	free(info);
 }
 
-static struct intel_uxa_pixmap *
+static void
 intel_exchange_pixmap_buffers(struct intel_screen_private *intel, PixmapPtr front, PixmapPtr back)
 {
-	struct intel_uxa_pixmap *new_front = NULL, *new_back;
 	RegionRec region;
 
 	/* Post damage on the front buffer so that listeners, such
@@ -687,16 +635,20 @@ intel_exchange_pixmap_buffers(struct intel_screen_private *intel, PixmapPtr fron
 	region.data = NULL;
 	DamageRegionAppend(&front->drawable, &region);
 
-	new_front = intel_uxa_get_pixmap_private(back);
-	new_back = intel_uxa_get_pixmap_private(front);
-	intel_uxa_set_pixmap_private(front, new_front);
-	intel_uxa_set_pixmap_private(back, new_back);
-	new_front->busy = 1;
-	new_back->busy = -1;
+        switch (intel->accel) {
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                intel_glamor_exchange_buffers(intel, front, back);
+                break;
+#endif
+#if USE_UXA
+        case ACCEL_UXA:
+                intel_uxa_exchange_buffers(intel, front, back);
+                break;
+#endif
+        }
 
 	DamageRegionProcessPending(&front->drawable);
-
-	return new_front;
 }
 
 static void
@@ -704,7 +656,6 @@ I830DRI2ExchangeBuffers(struct intel_screen_private *intel, DRI2BufferPtr front,
 {
 	I830DRI2BufferPrivatePtr front_priv, back_priv;
 	int tmp;
-	struct intel_uxa_pixmap *new_front;
 
 	front_priv = front->driverPrivate;
 	back_priv = back->driverPrivate;
@@ -715,11 +666,12 @@ I830DRI2ExchangeBuffers(struct intel_screen_private *intel, DRI2BufferPtr front,
 	back->name = tmp;
 
 	/* Swap pixmap bos */
-	new_front = intel_exchange_pixmap_buffers(intel,
-						  front_priv->pixmap,
-						  back_priv->pixmap);
+	intel_exchange_pixmap_buffers(intel,
+                                      front_priv->pixmap,
+                                      back_priv->pixmap);
+
 	dri_bo_unreference (intel->front_buffer);
-	intel->front_buffer = new_front->bo;
+	intel->front_buffer = intel_get_pixmap_bo(front_priv->pixmap);
 	dri_bo_reference (intel->front_buffer);
 }
 
@@ -797,6 +749,26 @@ I830DRI2ScheduleFlip(struct intel_screen_private *intel,
 
 		drm_intel_bo_disable_reuse(new_back);
 		dri_bo_flink(new_back, &intel->back_name);
+#if USE_GLAMOR
+		if (intel->accel == ACCEL_GLAMOR) {
+                        I830DRI2BufferPrivatePtr drvpriv;
+                        PixmapPtr front_pixmap, back_pixmap;
+                        ScreenPtr screen;
+
+			screen = draw->pScreen;
+			drvpriv = info->front->driverPrivate;
+			front_pixmap = drvpriv->pixmap;
+
+			back_pixmap = intel_glamor_create_back_pixmap(screen,
+								      front_pixmap,
+								      new_back);
+			if (back_pixmap == NULL) {
+				drm_intel_bo_unreference(new_back);
+				return FALSE;
+			}
+			intel->back_pixmap = back_pixmap;
+		}
+#endif
 	} else {
 		new_back = intel->back_buffer;
 		intel->back_buffer = NULL;
@@ -841,8 +813,6 @@ can_exchange(DrawablePtr drawable, DRI2BufferPtr front, DRI2BufferPtr back)
 	I830DRI2BufferPrivatePtr back_priv = back->driverPrivate;
 	PixmapPtr front_pixmap = front_priv->pixmap;
 	PixmapPtr back_pixmap = back_priv->pixmap;
-	struct intel_uxa_pixmap *front_intel = intel_uxa_get_pixmap_private(front_pixmap);
-	struct intel_uxa_pixmap *back_intel = intel_uxa_get_pixmap_private(back_pixmap);
 
 	if (!pScrn->vtSema)
 		return FALSE;
@@ -874,12 +844,24 @@ can_exchange(DrawablePtr drawable, DRI2BufferPtr front, DRI2BufferPtr back)
 		return FALSE;
 #endif
 
-	/* prevent an implicit tiling mode change */
-	if (front_intel->tiling != back_intel->tiling)
-		return FALSE;
-
-	if (front_intel->pinned & ~(PIN_SCANOUT | PIN_DRI2))
-		return FALSE;
+        switch (intel->accel) {
+#if USE_UXA
+        case ACCEL_UXA:
+        {
+                struct intel_uxa_pixmap *front_intel = intel_uxa_get_pixmap_private(front_pixmap);
+                struct intel_uxa_pixmap *back_intel = intel_uxa_get_pixmap_private(back_pixmap);
+                /* prevent an implicit tiling mode change */
+                if (front_intel->tiling != back_intel->tiling)
+                        return FALSE;
+
+                if (front_intel->pinned & ~(PIN_SCANOUT | PIN_DRI2))
+                        return FALSE;
+                break;
+        }
+#endif
+        default:
+                break;
+        }
 
 	return TRUE;
 }
diff --git a/src/uxa/intel_driver.c b/src/uxa/intel_driver.c
index 8d5e279..b3ac742 100644
--- a/src/uxa/intel_driver.c
+++ b/src/uxa/intel_driver.c
@@ -72,6 +72,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "intel_uxa.h"
 #endif
 
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
+
 #include "intel_options.h"
 #include "i915_drm.h"
 
@@ -162,8 +166,20 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
 	if (!(*screen->CreateScreenResources) (screen))
 		return FALSE;
 
-	if (!intel_uxa_create_screen_resources(screen))
-		return FALSE;
+        switch (intel->accel) {
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                if (!intel_glamor_create_screen_resources(screen))
+                        return FALSE;
+                break;
+#endif
+#if USE_UXA
+        case ACCEL_UXA:
+                if (!intel_uxa_create_screen_resources(screen))
+                        return FALSE;
+                intel_copy_fb(scrn);
+#endif
+        }
 
 	return TRUE;
 }
@@ -171,19 +187,62 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
 void
 intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo)
 {
-        intel_uxa_set_pixmap_bo(pixmap, bo);
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+
+        switch (intel->accel) {
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                intel_glamor_set_pixmap_bo(pixmap, bo);
+                break;
+#endif
+#if USE_UXA
+        case ACCEL_UXA:
+                intel_uxa_set_pixmap_bo(pixmap, bo);
+                break;
+#endif
+        default:
+                ErrorF("No accel architecture, cannot set pixmap bo\n");
+                break;
+        }
 }
 
 dri_bo *
 intel_get_pixmap_bo(PixmapPtr pixmap)
 {
-        return intel_uxa_get_pixmap_bo(pixmap);
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+
+	switch (intel->accel) {
+#if USE_GLAMOR
+	case ACCEL_GLAMOR:
+		return intel_glamor_get_pixmap_bo(pixmap);
+#endif
+#if USE_UXA
+        case ACCEL_UXA:
+		return intel_uxa_get_pixmap_bo(pixmap);
+#endif
+        default:
+                ErrorF("No accel architecture, cannot set pixmap bo\n");
+	        return NULL;
+        }
 }
 
 void
 intel_flush(intel_screen_private *intel)
 {
-        intel_batch_submit(intel->scrn);
+	switch (intel->accel) {
+#if USE_GLAMOR
+	case ACCEL_GLAMOR:
+                intel_glamor_flush(intel);
+                break;
+#endif
+#if USE_UXA
+        case ACCEL_UXA:
+                intel_batch_submit(intel->scrn);
+                break;
+#endif
+        }
 }
 
 static void PreInitCleanup(ScrnInfoPtr scrn)
@@ -201,6 +260,41 @@ static void intel_check_chipset_option(ScrnInfoPtr scrn)
 	intel_detect_chipset(scrn, intel->pEnt);
 }
 
+static void intel_check_accel_option(ScrnInfoPtr scrn)
+{
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	enum { NOACCEL, SNA, UXA, GLAMOR } accel_method = DEFAULT_ACCEL_METHOD;
+	const char *s;
+
+	s = xf86GetOptValString(intel->Options, OPTION_ACCEL_METHOD);
+	if (s != NULL) {
+#if USE_GLAMOR
+                if (strcasecmp(s, "glamor") == 0)
+                        accel_method = GLAMOR;
+                else
+#endif
+#if USE_UXA
+                if (strcasecmp(s, "uxa") == 0)
+                        accel_method = UXA;
+                else
+#endif
+                        accel_method = DEFAULT_ACCEL_METHOD;
+        }
+        switch (accel_method) {
+        default:
+#if USE_GLAMOR
+        case GLAMOR:
+                intel->accel = ACCEL_GLAMOR;
+                break;
+#endif
+#if USE_UXA
+        case UXA:
+                intel->accel = ACCEL_UXA;
+                break;
+#endif
+        }
+}
+
 static Bool I830GetEarlyOptions(ScrnInfoPtr scrn)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
@@ -525,6 +619,7 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 	intel_setup_capabilities(scrn);
 	intel_check_chipset_option(scrn);
 	intel_check_dri_option(scrn);
+        intel_check_accel_option(scrn);
 
 	if (!intel_init_bufmgr(intel)) {
 		PreInitCleanup(scrn);
@@ -611,14 +706,37 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 		return FALSE;
 	}
 
-	/* Load the dri modules if requested. */
-#if HAVE_DRI2
-	if (intel->dri2 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri2"))
-		intel->dri2 = DRI_DISABLED;
+        switch (intel->accel) {
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                if (!intel_glamor_pre_init(scrn)) {
+                        PreInitCleanup(scrn);
+                        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                                   "Failed to pre init glamor display.\n");
+                        intel->accel = ACCEL_UXA;
+                }
+                break;
 #endif
+        default:
+                break;
+        }
+
+        switch (intel->accel) {
+#if USE_UXA
+        case ACCEL_UXA:
 #if HAVE_DRI3
-	if (intel->dri3 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri3"))
-		intel->dri3 = DRI_DISABLED;
+                if (intel->dri3 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri3"))
+                        intel->dri3 = DRI_DISABLED;
+#endif
+                break;
+#endif
+        default:
+                break;
+        }
+
+#if HAVE_DRI2
+        if (intel->dri2 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri2"))
+                intel->dri2 = DRI_DISABLED;
 #endif
 
 	return TRUE;
@@ -869,9 +987,11 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	VisualPtr visual;
+#if USE_UXA
 #ifdef INTEL_XVMC
 	MessageType from;
 #endif
+#endif
 	struct pci_device *const device = intel->PciInfo;
 	int fb_bar = IS_GEN2(intel) ? 0 : 2;
 
@@ -923,22 +1043,40 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 
 	xf86SetBlackWhitePixels(screen);
 
-	if (!intel_uxa_init(screen)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Hardware acceleration initialization failed\n");
-		return FALSE;
-	}
-
-#if HAVE_DRI2
-	if (intel->dri2 == DRI_NONE && I830DRI2ScreenInit(screen))
-		intel->dri2 = DRI_ACTIVE;
+        switch (intel->accel) {
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                if (!intel_glamor_init(screen)) {
+                        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                                   "Glamor acceleration initialization failed\n");
+                        return FALSE;
+                }
+                /* XXX indirect GL under Glamor doesn't work because of recursion during
+                 * buffer creation
+                 */
+                enableIndirectGLX = FALSE;
+                break;
 #endif
-
+#if USE_UXA
+        case ACCEL_UXA:
+                if (!intel_uxa_init(screen)) {
+                        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                                   "Hardware acceleration initialization failed\n");
+                        return FALSE;
+                }
 #if HAVE_DRI3
-	if (!intel_sync_init(screen))
-		intel->dri3 = DRI_DISABLED;
-	if (intel->dri3 == DRI_NONE && intel_dri3_screen_init(screen))
-		intel->dri3 = DRI_ACTIVE;
+                if (!intel_sync_init(screen))
+                        intel->dri3 = DRI_DISABLED;
+                if (intel->dri3 == DRI_NONE && intel_dri3_screen_init(screen))
+                        intel->dri3 = DRI_ACTIVE;
+#endif
+                break;
+#endif
+        }
+
+#if HAVE_DRI2
+        if (intel->dri2 == DRI_NONE && I830DRI2ScreenInit(screen))
+                intel->dri2 = DRI_ACTIVE;
 #endif
 
 	if (xf86ReturnOptValBool(intel->Options, OPTION_PRESENT, TRUE))
@@ -993,19 +1131,6 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 
 	xf86DPMSInit(screen, xf86DPMSSet, 0);
 
-#ifdef INTEL_XVMC
-	if (INTEL_INFO(intel)->gen >= 040)
-		intel->XvMCEnabled = TRUE;
-	from = (intel->dri2 == DRI_ACTIVE &&
-		xf86GetOptValBool(intel->Options, OPTION_XVMC,
-				  &intel->XvMCEnabled) ? X_CONFIG : X_DEFAULT);
-	xf86DrvMsg(scrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
-		   intel->XvMCEnabled ? "en" : "dis");
-#endif
-	/* Init video */
-	if (intel->XvEnabled)
-		intel_video_init(screen);
-
 #if HAVE_DRI2
 	switch (intel->dri2) {
 	case DRI_ACTIVE:
@@ -1026,25 +1151,46 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 		   "DRI2: Not available\n");
 #endif
 
+        switch (intel->accel) {
+#if USE_UXA
+        case ACCEL_UXA:
+#ifdef INTEL_XVMC
+                if (INTEL_INFO(intel)->gen >= 040)
+                        intel->XvMCEnabled = TRUE;
+                from = (intel->dri2 == DRI_ACTIVE &&
+                        xf86GetOptValBool(intel->Options, OPTION_XVMC,
+                                          &intel->XvMCEnabled) ? X_CONFIG : X_DEFAULT);
+                xf86DrvMsg(scrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
+                           intel->XvMCEnabled ? "en" : "dis");
+#endif
 #if HAVE_DRI3
-	switch (intel->dri3) {
-	case DRI_ACTIVE:
-		xf86DrvMsg(scrn->scrnIndex, X_INFO,
-			   "DRI3: Enabled\n");
-		break;
-	case DRI_DISABLED:
-		xf86DrvMsg(scrn->scrnIndex, X_INFO,
-			   "DRI3: Disabled\n");
-		break;
-	case DRI_NONE:
-		xf86DrvMsg(scrn->scrnIndex, X_INFO,
-			   "DRI3: Failed\n");
-		break;
-	}
+                switch (intel->dri3) {
+                case DRI_ACTIVE:
+                        xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                                   "DRI3: Enabled\n");
+                        break;
+                case DRI_DISABLED:
+                        xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                                   "DRI3: Disabled\n");
+                        break;
+                case DRI_NONE:
+                        xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                                   "DRI3: Failed\n");
+                        break;
+                }
 #else
-	xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		   "DRI3: Not available\n");
+                xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                           "DRI3: Not available\n");
 #endif
+#endif
+                break;
+        default:
+                break;
+        }
+
+	/* Init video */
+	if (intel->XvEnabled)
+		intel_video_init(screen);
 
 	if (serverGeneration == 1)
 		xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options);
@@ -1138,14 +1284,33 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
 
 	DeleteCallback(&FlushCallback, intel_flush_callback, scrn);
 
-	TimerFree(intel->cache_expire);
-	intel->cache_expire = NULL;
+        switch (intel->accel) {
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                intel_glamor_close_screen(screen);
+                break;
+#endif
+#if USE_UXA
+        case ACCEL_UXA:
+
+                TimerFree(intel->cache_expire);
+                intel->cache_expire = NULL;
 
-	if (intel->uxa_driver) {
-		uxa_driver_fini(screen);
-		free(intel->uxa_driver);
-		intel->uxa_driver = NULL;
-	}
+                intel_batch_teardown(scrn);
+
+                if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100)
+                        gen4_render_state_cleanup(scrn);
+
+                if (intel->uxa_driver) {
+                        uxa_driver_fini(screen);
+                        free(intel->uxa_driver);
+                        intel->uxa_driver = NULL;
+                }
+                break;
+#endif
+        default:
+                break;
+        }
 
 	if (intel->back_pixmap) {
 		screen->DestroyPixmap(intel->back_pixmap);
@@ -1167,11 +1332,6 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
 		I830LeaveVT(VT_FUNC_ARGS(0));
 	}
 
-	intel_batch_teardown(scrn);
-
-	if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100)
-		gen4_render_state_cleanup(scrn);
-
 	xf86_cursors_fini(screen);
 
 	i965_free_video(scrn);
@@ -1179,17 +1339,29 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
 	screen->CloseScreen = intel->CloseScreen;
 	(*screen->CloseScreen) (CLOSE_SCREEN_ARGS);
 
-	if (intel->dri2 == DRI_ACTIVE) {
-		I830DRI2CloseScreen(screen);
-		intel->dri2 = DRI_NONE;
-	}
+#if HAVE_DRI2
+        if (intel->dri2 == DRI_ACTIVE) {
+                I830DRI2CloseScreen(screen);
+                intel->dri2 = DRI_NONE;
+        }
+#endif
 
-	if (intel->dri3 == DRI_ACTIVE) {
-		/* nothing to do here? */
-		intel->dri3 = DRI_NONE;
-	}
+        switch (intel->accel) {
+#if USE_UXA
+        case ACCEL_UXA:
+#if HAVE_DRI3
+                if (intel->dri3 == DRI_ACTIVE) {
+                        /* nothing to do here? */
+                        intel->dri3 = DRI_NONE;
+                }
+                intel_sync_close(screen);
+#endif
 
-	intel_sync_close(screen);
+                break;
+#endif
+        default:
+                break;
+        }
 
 	xf86GARTCloseScreen(scrn->scrnIndex);
 
diff --git a/src/uxa/intel_glamor.c b/src/uxa/intel_glamor.c
new file mode 100644
index 0000000..15fe369
--- /dev/null
+++ b/src/uxa/intel_glamor.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright © 2011 Intel Corporation.
+ *
+ * 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xorg-server.h"
+#include <xf86.h>
+#define GLAMOR_FOR_XORG  1
+#include <glamor.h>
+#include <unistd.h>
+
+#include "intel.h"
+#include "i915_drm.h"
+#include "intel_glamor.h"
+#include "intel_options.h"
+
+struct intel_glamor_pixmap {
+        dri_bo  *bo;
+};
+
+static DevPrivateKeyRec intel_glamor_pixmap_key;
+
+static inline struct intel_glamor_pixmap *intel_glamor_get_pixmap(PixmapPtr pixmap)
+{
+        return dixGetPrivateAddr(&pixmap->devPrivates, &intel_glamor_pixmap_key);
+}
+
+dri_bo *
+intel_glamor_get_pixmap_bo(PixmapPtr pixmap)
+{
+        dri_bo  *bo = intel_glamor_get_pixmap(pixmap)->bo;
+
+        if (!bo) {
+                ScreenPtr       screen = pixmap->drawable.pScreen;
+                CARD16          stride;
+                CARD32          size;
+                int             fd;
+
+                fd = glamor_fd_from_pixmap(screen,
+                                           pixmap,
+                                           &stride,
+                                           &size);
+
+                if (fd >= 0) {
+                        ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+                        intel_screen_private *intel = intel_get_screen_private(scrn);
+
+                        bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr,
+                                                                fd,
+                                                                size);
+                        close(fd);
+                        intel_glamor_get_pixmap(pixmap)->bo = bo;
+                }
+        }
+        return bo;
+}
+
+static void
+intel_glamor_reference_pixmap_bo(PixmapPtr pixmap, drm_intel_bo *bo)
+{
+        struct intel_glamor_pixmap      *glamor_pixmap = intel_glamor_get_pixmap(pixmap);
+
+        if (glamor_pixmap->bo) {
+                ErrorF("Unreference bo %d size %lu from pixmap %d x %d\n",
+                       glamor_pixmap->bo->handle, glamor_pixmap->bo->size, pixmap->drawable.width, pixmap->drawable.height);
+                drm_intel_bo_unreference(glamor_pixmap->bo);
+                glamor_pixmap->bo = NULL;
+        }
+
+        if (bo) {
+                ErrorF("Reference bo %d size %lu from pixmap %d x %d\n",
+                       bo->handle, bo->size, pixmap->drawable.width, pixmap->drawable.height);
+                drm_intel_bo_reference(bo);
+                glamor_pixmap->bo = bo;
+        }
+}
+
+Bool
+intel_glamor_set_pixmap_bo(PixmapPtr pixmap, drm_intel_bo *bo)
+{
+        if (bo == NULL || glamor_egl_create_textured_pixmap(pixmap,
+                                                            bo->handle,
+                                                            intel_pixmap_pitch(pixmap)))
+        {
+                intel_glamor_reference_pixmap_bo(pixmap, bo);
+                return TRUE;
+        }
+        return FALSE;
+}
+
+XF86VideoAdaptorPtr intel_glamor_xv_init(ScreenPtr screen, int num_ports)
+{
+	return glamor_xv_init(screen, num_ports);
+}
+
+Bool
+intel_glamor_create_screen_resources(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+        PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+        int     old_width, old_height, old_pitch;
+        Bool    ret;
+
+	if (!glamor_glyphs_init(screen))
+		return FALSE;
+
+        old_width = pixmap->drawable.width;
+        old_height = pixmap->drawable.height;
+        old_pitch = pixmap->devKind;
+
+	if (!screen->ModifyPixmapHeader(pixmap,
+					scrn->virtualX,
+					scrn->virtualY,
+					-1, -1,
+					intel->front_pitch,
+					NULL))
+		return FALSE;
+
+        ret = glamor_egl_create_textured_screen_ext(screen,
+                                                    intel->front_buffer->handle,
+                                                    intel->front_pitch,
+                                                    &intel->back_pixmap);
+
+        if (!ret)
+                goto fail;
+
+        intel_glamor_reference_pixmap_bo(pixmap, intel->front_buffer);
+
+        return TRUE;
+
+fail:
+        screen->ModifyPixmapHeader(pixmap,
+                                   old_width, old_height, -1, -1, old_pitch, NULL);
+
+        return FALSE;
+}
+
+Bool
+intel_glamor_pre_init(ScrnInfoPtr scrn)
+{
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	pointer glamor_module;
+	CARD32 version;
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,0,0,0)
+	if (!xf86LoaderCheckSymbol("glamor_egl_init")) {
+		xf86DrvMsg(scrn->scrnIndex,  X_ERROR,
+			   "glamor requires Load \"glamoregl\" in "
+			   "Section \"Module\", disabling.\n");
+		return TRUE;
+	}
+#endif
+
+	/* Load glamor module */
+        glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME);
+	if (!glamor_module) {
+		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			   "glamor not available\n");
+                return TRUE;
+        }
+
+        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 TRUE;
+        }
+        if (!glamor_egl_init(scrn, intel->drmSubFD)) {
+                xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+                           "glamor detected, failed to initialize egl.\n");
+                return TRUE;
+        }
+        xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                   "glamor detected, initialising egl layer.\n");
+
+	return TRUE;
+}
+
+Bool
+intel_glamor_init(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+        if (!dixRegisterPrivateKey(&intel_glamor_pixmap_key, PRIVATE_PIXMAP, sizeof (struct intel_glamor_pixmap)))
+                return FALSE;
+
+	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;
+	}
+
+	return TRUE;
+}
+
+void
+intel_glamor_flush(intel_screen_private * intel)
+{
+	ScreenPtr screen;
+
+	screen = xf86ScrnToScreen(intel->scrn);
+        glamor_block_handler(screen);
+}
+
+Bool
+intel_glamor_close_screen(ScreenPtr screen)
+{
+	return TRUE;
+}
+
+#if HAVE_DRI2
+void
+intel_glamor_exchange_buffers(struct intel_screen_private *intel,
+			      PixmapPtr src,
+			      PixmapPtr dst)
+{
+	glamor_egl_exchange_buffers(src, dst);
+}
+
+PixmapPtr
+intel_glamor_create_back_pixmap(ScreenPtr screen,
+				PixmapPtr front_pixmap,
+				drm_intel_bo *back_bo)
+{
+	PixmapPtr back_pixmap;
+
+	back_pixmap = screen->CreatePixmap(screen,
+					   0,
+					   0,
+				           front_pixmap->drawable.depth,
+				           0);
+	if (back_pixmap == NULL)
+		return NULL;
+
+	screen->ModifyPixmapHeader(back_pixmap,
+				   front_pixmap->drawable.width,
+				   front_pixmap->drawable.height,
+				   0, 0,
+				   front_pixmap->devKind,
+				   0);
+	if (!intel_glamor_set_pixmap_bo(back_pixmap, back_bo)) {
+		ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			   "Failed to create textured back pixmap.\n");
+		screen->DestroyPixmap(back_pixmap);
+		return NULL;
+	}
+	return back_pixmap;
+}
+#endif
diff --git a/src/uxa/intel_glamor.h b/src/uxa/intel_glamor.h
new file mode 100644
index 0000000..2fcabdf
--- /dev/null
+++ b/src/uxa/intel_glamor.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2011 Intel Corporation.
+ *
+ * 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
+#ifndef INTEL_GLAMOR_H
+#define INTEL_GLAMOR_H
+
+#include <xf86xv.h>
+
+Bool intel_glamor_pre_init(ScrnInfoPtr scrn);
+Bool intel_glamor_init(ScreenPtr screen);
+Bool intel_glamor_create_screen_resources(ScreenPtr screen);
+Bool intel_glamor_close_screen(ScreenPtr screen);
+void intel_glamor_free_screen(int scrnIndex, int flags);
+
+void intel_glamor_flush(intel_screen_private * intel);
+
+#if HAVE_DRI2
+PixmapPtr
+intel_glamor_create_back_pixmap(ScreenPtr screen,
+				PixmapPtr front_pixmap,
+				drm_intel_bo *back_bo);
+
+void intel_glamor_exchange_buffers(struct intel_screen_private *intel, PixmapPtr src, PixmapPtr dst);
+#endif
+
+XF86VideoAdaptorPtr intel_glamor_xv_init(ScreenPtr screen, int num_ports);
+
+dri_bo *
+intel_glamor_get_pixmap_bo(PixmapPtr pixmap);
+
+Bool
+intel_glamor_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo);
+
+#endif /* INTEL_GLAMOR_H */
diff --git a/src/uxa/intel_uxa.c b/src/uxa/intel_uxa.c
index 657c2b5..9eaa1a1 100644
--- a/src/uxa/intel_uxa.c
+++ b/src/uxa/intel_uxa.c
@@ -1396,3 +1396,103 @@ Bool intel_uxa_init(ScreenPtr screen)
 	intel->flush_rendering = intel_flush_rendering;
 	return TRUE;
 }
+
+void
+intel_uxa_wait_scanline(DrawablePtr dst, GCPtr gc)
+{
+        ScreenPtr               screen = dst->pScreen;
+	ScrnInfoPtr             scrn = xf86ScreenToScrn(screen);
+	intel_screen_private    *intel = intel_get_screen_private(scrn);
+
+	/* Wait for the scanline to be outside the region to be copied */
+	if (scrn->vtSema &&
+	    pixmap_is_scanout(get_drawable_pixmap(dst)) &&
+	    intel->swapbuffers_wait && INTEL_INFO(intel)->gen < 060) {
+		BoxPtr box;
+		BoxRec crtcbox;
+		int y1, y2;
+		int event, load_scan_lines_pipe;
+		xf86CrtcPtr crtc;
+		Bool full_height = FALSE;
+
+		box = REGION_EXTENTS(unused, gc->pCompositeClip);
+		crtc = intel_covering_crtc(scrn, box, NULL, &crtcbox);
+
+		/*
+		 * Make sure the CRTC is valid and this is the real front
+		 * buffer
+		 */
+		if (crtc != NULL && !crtc->rotatedData) {
+			int pipe = intel_crtc_to_pipe(crtc);
+
+			/*
+			 * Make sure we don't wait for a scanline that will
+			 * never occur
+			 */
+			y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0;
+			y2 = (box->y2 <= crtcbox.y2) ?
+			    box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1;
+
+			if (y1 == 0 && y2 == (crtcbox.y2 - crtcbox.y1))
+			    full_height = TRUE;
+
+			/*
+			 * Pre-965 doesn't have SVBLANK, so we need a bit
+			 * of extra time for the blitter to start up and
+			 * do its job for a full height blit
+			 */
+			if (full_height && INTEL_INFO(intel)->gen < 040)
+			    y2 -= 2;
+
+			if (pipe == 0) {
+				event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
+				load_scan_lines_pipe =
+				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
+				if (full_height && INTEL_INFO(intel)->gen >= 040)
+				    event = MI_WAIT_FOR_PIPEA_SVBLANK;
+			} else {
+				event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
+				load_scan_lines_pipe =
+				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
+				if (full_height && INTEL_INFO(intel)->gen >= 040)
+				    event = MI_WAIT_FOR_PIPEB_SVBLANK;
+			}
+
+			if (crtc->mode.Flags & V_INTERLACE) {
+				/* DSL count field lines */
+				y1 /= 2;
+				y2 /= 2;
+			}
+
+			BEGIN_BATCH(5);
+			/*
+			 * The documentation says that the LOAD_SCAN_LINES
+			 * command always comes in pairs. Don't ask me why.
+			 */
+			OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
+				  load_scan_lines_pipe);
+			OUT_BATCH((y1 << 16) | (y2-1));
+			OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
+				  load_scan_lines_pipe);
+			OUT_BATCH((y1 << 16) | (y2-1));
+			OUT_BATCH(MI_WAIT_FOR_EVENT | event);
+			ADVANCE_BATCH();
+		}
+	}
+}
+
+void
+intel_uxa_exchange_buffers(struct intel_screen_private *intel,
+                           PixmapPtr front,
+                           PixmapPtr back)
+{
+	struct intel_uxa_pixmap *new_front = NULL, *new_back;
+
+	new_front = intel_uxa_get_pixmap_private(back);
+	new_back = intel_uxa_get_pixmap_private(front);
+	intel_uxa_set_pixmap_private(front, new_front);
+	intel_uxa_set_pixmap_private(back, new_back);
+	new_front->busy = 1;
+	new_back->busy = -1;
+
+}
diff --git a/src/uxa/intel_uxa.h b/src/uxa/intel_uxa.h
index 3d495ba..4c711ca 100644
--- a/src/uxa/intel_uxa.h
+++ b/src/uxa/intel_uxa.h
@@ -296,4 +296,12 @@ void Gen6DisplayVideoTextured(ScrnInfoPtr scrn,
 
 void i965_free_video(ScrnInfoPtr scrn);
 
+void
+intel_uxa_wait_scanline(DrawablePtr dst, GCPtr gc);
+
+void
+intel_uxa_exchange_buffers(struct intel_screen_private *intel,
+                           PixmapPtr front,
+                           PixmapPtr back);
+
 #endif /* _INTEL_UXA_H_ */
diff --git a/src/uxa/intel_video.c b/src/uxa/intel_video.c
index ba76453..73920e6 100644
--- a/src/uxa/intel_video.c
+++ b/src/uxa/intel_video.c
@@ -78,7 +78,13 @@
 #define _INTEL_XVMC_SERVER_
 #include "intel_xvmc.h"
 #endif
+#if USE_GLAMOR
+#include "intel_glamor.h"
+#endif
+#if USE_UXA
 #include "intel_uxa.h"
+#endif
+
 #include "intel_video_overlay.h"
 
 Atom intel_xv_Brightness, intel_xv_Contrast, intel_xv_Saturation, intel_xv_ColorKey, intel_xv_Pipe;
@@ -169,7 +175,7 @@ void intel_video_init(ScreenPtr screen)
 	 * adaptors.
 	 */
 	newAdaptors = realloc(adaptors,
-			      (num_adaptors + 3) * sizeof(XF86VideoAdaptorPtr));
+			      (num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr));
 
 	if (newAdaptors == NULL) {
 		free(adaptors);
@@ -183,21 +189,37 @@ void intel_video_init(ScreenPtr screen)
 	intel_xv_Brightness = MAKE_ATOM("XV_BRIGHTNESS");
 	intel_xv_Contrast = MAKE_ATOM("XV_CONTRAST");
 
-        /* Set up textured video if we can do it at this depth and we are on
-         * supported hardware.
-         */
-        if (!intel->force_fallback &&
-            scrn->bitsPerPixel >= 16 &&
-            INTEL_INFO(intel)->gen >= 030 &&
-            INTEL_INFO(intel)->gen < 0100) {
-                texturedAdaptor = intel_uxa_video_setup_image_textured(screen);
-                if (texturedAdaptor != NULL) {
-                        xf86DrvMsg(scrn->scrnIndex, X_INFO,
-                                   "Set up textured video\n");
-                } else {
-                        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-                                   "Failed to set up textured video\n");
+        switch (intel->accel) {
+#if USE_UXA
+        case ACCEL_UXA:
+                /* Set up textured video if we can do it at this depth and we are on
+                 * supported hardware.
+                 */
+                if (!intel->force_fallback &&
+                    scrn->bitsPerPixel >= 16 &&
+                    INTEL_INFO(intel)->gen >= 030 &&
+                    INTEL_INFO(intel)->gen < 0100) {
+                        texturedAdaptor = intel_uxa_video_setup_image_textured(screen);
+                        if (texturedAdaptor != NULL) {
+                                xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                                           "Set up textured video\n");
+                        } else {
+                                xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                                           "Failed to set up textured video\n");
+                        }
                 }
+                break;
+#endif
+#if USE_GLAMOR
+        case ACCEL_GLAMOR:
+                texturedAdaptor = intel_glamor_xv_init(screen, 16);
+                if (texturedAdaptor != NULL)
+                        xf86DrvMsg(scrn->scrnIndex, X_INFO,
+                                   "Set up textured video using glamor\n");
+                break;
+#endif
+        default:
+                break;
         }
 
         overlayAdaptor = intel_video_overlay_setup_image(screen);
@@ -229,9 +251,16 @@ void intel_video_init(ScreenPtr screen)
 		intel->XvEnabled = FALSE;
 	}
 
-        if (texturedAdaptor)
-                intel_xvmc_adaptor_init(screen);
-
+#if defined(INTEL_XVMC) && defined(USE_UXA)
+        switch (intel->accel) {
+        case ACCEL_UXA:
+                if (texturedAdaptor)
+                        intel_xvmc_adaptor_init(screen);
+                break;
+        default:
+                break;
+        }
+#endif
 	free(adaptors);
 }
 
-- 
2.0.1




More information about the xorg-devel mailing list