diff --git a/src/intel.h b/src/intel.h
index d4c9aff..01011f5 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -76,6 +76,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <libudev.h>
 #endif
 
+#if XMIR
+#include "xmir.h"
+#else
+typedef struct xmir_screen xmir_screen;
+#endif
+
 /* remain compatible to xorg-server 1.6 */
 #ifndef MONITOR_EDID_COMPLETE_RAWDATA
 #define MONITOR_EDID_COMPLETE_RAWDATA EDID_COMPLETE_RAWDATA
@@ -350,6 +356,7 @@ typedef struct intel_screen_private {
 	InputHandlerProc uevent_handler;
 #endif
 	Bool has_prime_vmap_flush;
+	xmir_screen *xmir;
 } intel_screen_private;
 
 #ifndef I915_PARAM_HAS_PRIME_VMAP_FLUSH
diff --git a/src/intel_display.c b/src/intel_display.c
index 17168e5..d84a367 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -1872,6 +1872,17 @@ intel_mode_init(struct intel_screen_private *intel)
 {
 	struct intel_mode *mode = intel->modes;
 
+	if (intel->modes == NULL) {
+		mode = calloc (sizeof *mode, 1);
+		mode->fd = intel->drmSubFD;
+
+		mode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
+		mode->event_context.vblank_handler = intel_vblank_handler;
+		mode->event_context.page_flip_handler = intel_page_flip_handler;
+
+		intel->modes = mode;
+	}
+
 	/* We need to re-register the mode->fd for the synchronisation
 	 * feedback on every server generation, so perform the
 	 * registration within ScreenInit and not PreInit.
@@ -1967,6 +1978,13 @@ Bool intel_crtc_on(xf86CrtcPtr crtc)
 	Bool ret;
 	int i;
 
+	/* We're not in control of this crtc, probably because we're running nested.
+	 * We can't say anything useful about whether the CRTC's on or not, so say
+	 * off.
+	 */
+	if (!intel_crtc)
+		return FALSE;
+
 	if (!crtc->enabled)
 		return FALSE;
 
diff --git a/src/intel_dri.c b/src/intel_dri.c
index 0370034..e382e5e 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -68,6 +68,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "intel_glamor.h"
 #include "uxa.h"
 
+#ifdef XMIR
+#include "xmir.h"
+#include "xf86Priv.h"
+#endif
+
 typedef struct {
 	int refcnt;
 	PixmapPtr pixmap;
@@ -1545,6 +1550,19 @@ static const char *dri_driver_name(intel_screen_private *intel)
 	return s;
 }
 
+#if DRI2INFOREC_VERSION >= 8 && defined(XMIR)
+static int I830DRI2AuthMagic(ScreenPtr screen, uint32_t magic)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+
+	if (xorgMir)
+		return xmir_auth_drm_magic(intel->xmir, magic);
+	else
+		return drmAuthMagic(intel->drmSubFD, magic);
+}
+#endif
+
 Bool I830DRI2ScreenInit(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -1625,6 +1643,11 @@ Bool I830DRI2ScreenInit(ScreenPtr screen)
 	driverNames[0] = info.driverName;
 #endif
 
+#if DRI2INFOREC_VERSION >= 8 && XMIR
+	info.version = 8;
+	info.AuthMagic2 = I830DRI2AuthMagic;
+#endif
+
 	return DRI2ScreenInit(screen, &info);
 }
 
diff --git a/src/intel_driver.c b/src/intel_driver.c
index ae2e31e..e960d89 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -64,6 +64,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "intel.h"
 #include "intel_video.h"
 
+#ifdef XMIR
+#include "xmir.h"
+#include "dix.h"
+#include "xf86Priv.h"
+#endif
+
 #ifdef INTEL_XVMC
 #define _INTEL_XVMC_SERVER_
 #include "intel_hwmc.h"
@@ -169,7 +175,8 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
 	if (!intel_uxa_create_screen_resources(screen))
 		return FALSE;
 
-	intel_copy_fb(scrn);
+	if (!xorgMir)
+		intel_copy_fb(scrn);
 	return TRUE;
 }
 
@@ -246,41 +253,51 @@ static void intel_check_dri_option(ScrnInfoPtr scrn)
 
 static Bool intel_open_drm_master(ScrnInfoPtr scrn)
 {
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-	struct pci_device *dev = intel->PciInfo;
-	drmSetVersion sv;
 	struct drm_i915_getparam gp;
 	int err, has_gem;
-	char busid[20];
+	intel_screen_private *intel = intel_get_screen_private(scrn);
 
-	snprintf(busid, sizeof(busid), "pci:%04x:%02x:%02x.%d",
-		 dev->domain, dev->bus, dev->dev, dev->func);
+        struct pci_device *dev = intel->PciInfo;
+        drmSetVersion sv;
+        char busid[20];
 
-	intel->drmSubFD = drmOpen(NULL, busid);
-	if (intel->drmSubFD == -1) {
+        snprintf(busid, sizeof(busid), "pci:%04x:%02x:%02x.%d",
+                 dev->domain, dev->bus, dev->dev, dev->func);
+
+	if (xorgMir) {
+	    intel->drmSubFD = xmir_get_drm_fd(busid);
+            if (intel->drmSubFD < 0) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "[drm] Failed to retrieve DRM device %s from Mir\n",
+			   busid);
+		return FALSE;
+            }
+	} else {
+	    intel->drmSubFD = drmOpen(NULL, busid);
+	    if (intel->drmSubFD == -1) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "[drm] Failed to open DRM device for %s: %s\n",
 			   busid, strerror(errno));
 		return FALSE;
-	}
-
-	/* Check that what we opened was a master or a master-capable FD,
-	 * by setting the version of the interface we'll use to talk to it.
-	 * (see DRIOpenDRMMaster() in DRI1)
-	 */
-	sv.drm_di_major = 1;
-	sv.drm_di_minor = 1;
-	sv.drm_dd_major = -1;
-	sv.drm_dd_minor = -1;
-	err = drmSetInterfaceVersion(intel->drmSubFD, &sv);
-	if (err != 0) {
+	    }
+
+	    /* Check that what we opened was a master or a master-capable FD,
+	     * by setting the version of the interface we'll use to talk to it.
+	     * (see DRIOpenDRMMaster() in DRI1)
+	     */
+	    sv.drm_di_major = 1;
+	    sv.drm_di_minor = 1;
+	    sv.drm_dd_major = -1;
+	    sv.drm_dd_minor = -1;
+	    err = drmSetInterfaceVersion(intel->drmSubFD, &sv);
+	    if (err != 0) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "[drm] failed to set drm interface version.\n");
 		drmClose(intel->drmSubFD);
 		intel->drmSubFD = -1;
 		return FALSE;
+	    }
 	}
-
 	has_gem = FALSE;
 	gp.param = I915_PARAM_HAS_GEM;
 	gp.value = &has_gem;
@@ -299,7 +316,7 @@ static Bool intel_open_drm_master(ScrnInfoPtr scrn)
 
 static void intel_close_drm_master(intel_screen_private *intel)
 {
-	if (intel && intel->drmSubFD > 0) {
+	if (intel && intel->drmSubFD > 0 && !xorgMir) {
 		drmClose(intel->drmSubFD);
 		intel->drmSubFD = -1;
 	}
@@ -462,6 +479,101 @@ static void intel_setup_capabilities(ScrnInfoPtr scrn)
 #endif
 }
 
+#ifdef XMIR
+
+static void
+intel_xmir_copy_pixmap_to_mir(PixmapPtr src,
+                              int dst_fd)
+{
+	ScreenPtr pScreen = src->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+        dri_bo *bo;
+	PixmapPtr dst;
+	unsigned int pitch = scrn->displayWidth * intel->cpp;
+
+	/* TODO: This is open-coded create_pixmap_for_bo
+	 * We actually want to keep a stable pixmap, and just intel_set_pixmap_bo each time.
+	 */
+
+	dst = pScreen->CreatePixmap(pScreen, 0, 0, scrn->depth, 0);
+
+	if (dst == NullPixmap)
+		return;
+
+	if (!pScreen->ModifyPixmapHeader(dst,
+					 scrn->virtualX, scrn->virtualY,
+					 scrn->depth, scrn->bitsPerPixel,
+					 pitch, NULL))
+		goto cleanup_dst;
+
+
+        bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, dst_fd, 0);
+        if (!bo)
+            goto cleanup_dst;
+        intel_set_pixmap_bo(dst, bo);
+
+	if (!intel->uxa_driver->prepare_copy(src, dst,
+					     -1, -1,
+					     GXcopy, FB_ALLONES))
+		goto cleanup_dst;
+
+	intel->uxa_driver->copy(dst,
+				0, 0,
+				0, 0,
+				scrn->virtualX, scrn->virtualY);
+
+	intel->uxa_driver->done_copy(dst);
+
+        /* Ensure we submit the right buffer */
+        intel_batch_submit(scrn);
+cleanup_dst:
+	(*pScreen->DestroyPixmap)(dst);
+}
+
+static void
+intel_xmir_buffer_available(WindowPtr win)
+{
+	int window_fd;
+	PixmapPtr window_pixmap;
+
+	if(!xmir_window_is_dirty(win))
+		return;
+
+	window_fd = xmir_prime_fd_for_window(win);
+
+	window_pixmap = (*win->drawable.pScreen->GetWindowPixmap)(win);
+	intel_xmir_copy_pixmap_to_mir(window_pixmap, window_fd);
+
+	xmir_submit_rendering_for_window(win, NULL);
+}
+
+static void
+intel_submit_dirty_window(WindowPtr win, DamagePtr damage)
+{
+	int window_fd;
+	PixmapPtr window_pixmap;
+
+	if(!xmir_window_has_free_buffer(win))
+		return;
+
+	window_fd = xmir_prime_fd_for_window(win);
+
+	window_pixmap = (*win->drawable.pScreen->GetWindowPixmap)(win);
+	intel_xmir_copy_pixmap_to_mir(window_pixmap, window_fd);
+
+	xmir_submit_rendering_for_window(win, DamageRegion(damage));
+
+	DamageEmpty(damage);
+}
+
+static xmir_driver driver = {
+	XMIR_DRIVER_VERSION,
+	intel_xmir_buffer_available
+};
+
+#endif /* XMIR */
+
 /**
  * This is called before ScreenInit to do any require probing of screen
  * configuration.
@@ -516,6 +628,12 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 
 	intel->PciInfo = xf86GetPciInfoForEntity(intel->pEnt->index);
 
+	if (xorgMir) {
+		intel->xmir = xmir_screen_create(scrn);
+		if (!intel->xmir)
+			return FALSE;
+	}
+
 	if (!intel_open_drm_master(scrn)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Failed to become DRM master.\n");
@@ -560,6 +678,9 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 	intel_check_chipset_option(scrn);
 	intel_check_dri_option(scrn);
 
+        if (intel->xmir && !xmir_screen_pre_init(scrn, intel->xmir, &driver))
+            return FALSE;
+
 	if (!intel_init_bufmgr(intel)) {
 		PreInitCleanup(scrn);
 		return FALSE;
@@ -622,7 +743,10 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 
 	I830XvInit(scrn);
 
-	if (!intel_mode_pre_init(scrn, intel->drmSubFD, intel->cpp)) {
+	if (xorgMir) {
+		xf86ProviderSetup(scrn, NULL, "Intel");
+	}
+	else if (!intel_mode_pre_init(scrn, intel->drmSubFD, intel->cpp)) {
 		PreInitCleanup(scrn);
 		return FALSE;
 	}
@@ -759,6 +883,10 @@ I830BlockHandler(BLOCKHANDLER_ARGS_DECL)
 #ifdef INTEL_PIXMAP_SHARING
 	intel_dirty_update(screen);
 #endif
+#ifdef XMIR
+	if (xorgMir)
+		xmir_screen_for_each_damaged_window(intel->xmir, intel_submit_dirty_window);
+#endif
 }
 
 static Bool
@@ -974,6 +1102,9 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 
 	fbPictureInit(screen, NULL, 0);
 
+	if(intel->xmir)
+		xmir_screen_init(screen, intel->xmir);
+
 	xf86SetBlackWhitePixels(screen);
 
 	if (!intel_uxa_init(screen)) {
@@ -987,7 +1118,7 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 	miDCInitialize(screen, xf86GetPointerScreenFuncs());
 
 	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n");
-	if (!xf86_cursors_init(screen, 64, 64,
+	if (!xorgMir && !xf86_cursors_init(screen, 64, 64,
 			       (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
 				HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
 				HARDWARE_CURSOR_INVERT_MASK |
@@ -1109,6 +1240,9 @@ static void I830LeaveVT(VT_FUNC_ARGS_DECL)
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	int ret;
 
+	if (xorgMir)
+		return;
+
 	xf86RotateFreeShadow(scrn);
 
 	xf86_hide_cursors(scrn);
@@ -1128,6 +1262,10 @@ static Bool I830EnterVT(VT_FUNC_ARGS_DECL)
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	int ret;
 
+	if (xorgMir) {
+		return xf86SetDesiredModes(scrn);
+	}
+
 	ret = drmSetMaster(intel->drmSubFD);
 	if (ret) {
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1184,7 +1322,8 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
 	}
 
 	if (intel->front_buffer) {
-		intel_mode_remove_fb(intel);
+		if (!xorgMir)
+			intel_mode_remove_fb(intel);
 		drm_intel_bo_unreference(intel->front_buffer);
 		intel->front_buffer = NULL;
 	}
diff --git a/src/intel_module.c b/src/intel_module.c
index c1d0e09..602b889 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -51,6 +51,11 @@
 #include <xf86platformBus.h>
 #endif
 
+#ifdef XMIR
+#include <xf86Priv.h>
+#include <xmir.h>
+#endif
+
 static const struct intel_device_info intel_generic_info = {
 	.gen = -1,
 };
@@ -428,6 +433,11 @@ static Bool intel_driver_func(ScrnInfoPtr pScrn,
 #else
 		(*flag) = HW_IO | HW_MMIO;
 #endif
+
+#ifdef XMIR
+		if (xorgMir)
+			(*flag) = HW_SKIP_CONSOLE;
+#endif
 		return TRUE;
 	default:
 		/* Unknown or deprecated function */
@@ -483,6 +493,21 @@ static Bool has_kernel_mode_setting(const struct pci_device *dev)
 	return ret;
 }
 
+static Bool has_mir_support(const struct pci_device *dev)
+{
+	char id[20];
+
+	snprintf(id, sizeof(id),
+		 "pci:%04x:%02x:%02x.%d",
+		 dev->domain, dev->bus, dev->dev, dev->func);
+
+        if (xmir_get_drm_fd(id) < 0)
+            return FALSE;
+
+        return TRUE;
+}
+
+
 #if !UMS_ONLY
 extern XF86ConfigPtr xf86configptr;
 
@@ -578,7 +603,7 @@ static Bool intel_pci_probe(DriverPtr		driver,
 			    struct pci_device	*device,
 			    intptr_t		match_data)
 {
-	if (!has_kernel_mode_setting(device)) {
+	if (!has_kernel_mode_setting(device) && !xorgMir) {
 #if KMS_ONLY
 		return FALSE;
 #else
@@ -609,6 +634,9 @@ intel_platform_probe(DriverPtr driver,
 	if (!dev->pdev)
 		return FALSE;
 
+        if (xorgMir && !has_mir_support(dev->pdev))
+		return FALSE;
+
 	if (!has_kernel_mode_setting(dev->pdev))
 		return FALSE;
 
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 79ac1ad..9853ce8 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -75,6 +75,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <libudev.h>
 #endif
 
+#if XMIR
+#include <xf86Priv.h>
+#include "xmir.h"
+#else
+typedef struct xmir_screen xmir_screen;
+#define xorgMir 0
+#endif
+
 #if HAS_DEBUG_FULL
 #define DBG(x) ErrorF x
 #else
@@ -306,6 +314,7 @@ struct sna {
 #endif
 
 	struct sna_render render;
+	xmir_screen *xmir;
 
 #if DEBUG_MEMORY
 	struct {
@@ -725,6 +734,9 @@ void sna_accel_watch_flush(struct sna *sna, int enable);
 void sna_accel_close(struct sna *sna);
 void sna_accel_free(struct sna *sna);
 
+void sna_xmir_copy_pixmap_to_mir(PixmapPtr src, int dst_fd);
+int sna_dri_auth_magic2(ScreenPtr screen, uint32_t magic);
+
 void sna_copy_fbcon(struct sna *sna);
 
 bool sna_composite_create(struct sna *sna);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 7e0ca6d..f6ebf1e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -14770,6 +14770,34 @@ void sna_accel_close(struct sna *sna)
 	kgem_cleanup_cache(&sna->kgem);
 }
 
+#ifdef XMIR
+void
+sna_xmir_copy_pixmap_to_mir(PixmapPtr src, int dst_fd)
+{
+	ScreenPtr pScreen = src->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+	struct sna *sna = to_sna_from_pixmap(src);
+	struct sna_pixmap *priv = sna_pixmap(src);
+	struct kgem_bo *bo;
+	unsigned int pitch = priv->gpu_bo->pitch;
+	BoxRec box;
+
+	bo = kgem_create_for_prime(&sna->kgem, dst_fd, pitch * src->drawable.height);
+	if (!bo)
+		return;
+	bo->pitch = pitch;
+
+	box.x1 = box.y1 = 0;
+	box.x2 = scrn->virtualX;
+	box.y2 = scrn->virtualY;
+
+	sna->render.copy_boxes(sna, GXcopy, src, sna_pixmap(src)->gpu_bo, 0, 0,
+			       src, bo, 0, 0, &box, 1, 0);
+	kgem_submit(&sna->kgem);
+	kgem_bo_destroy(&sna->kgem, bo);
+}
+#endif
+
 void sna_accel_block_handler(struct sna *sna, struct timeval **tv)
 {
 	if (sna->kgem.need_retire)
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 9c1bda0..ec3a1eb 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -2469,6 +2469,11 @@ bool sna_dri_open(struct sna *sna, ScreenPtr screen)
 	info.ReuseBufferNotify = NULL;
 #endif
 
+#if DRI2INFOREC_VERSION >= 8 && XMIR
+	info.version = 8;
+	info.AuthMagic2 = sna_dri_auth_magic2;
+#endif
+
 #if USE_ASYNC_SWAP
 	info.version = 10;
 	info.AsyncSwap = sna_dri_async_swap;
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index de1384d..5bd380c 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -242,7 +242,8 @@ static Bool sna_create_screen_resources(ScreenPtr screen)
 					  screen->width,
 					  screen->height,
 					  screen->rootDepth,
-					  SNA_CREATE_FB);
+					  xorgMir ? CREATE_PIXMAP_USAGE_SHARED
+						  : SNA_CREATE_FB);
 	if (!sna->front) {
 		xf86DrvMsg(screen->myNum, X_ERROR,
 			   "[intel] Unable to create front buffer %dx%d at depth %d\n",
@@ -253,7 +254,8 @@ static Bool sna_create_screen_resources(ScreenPtr screen)
 		return FALSE;
 	}
 
-	if (!sna_pixmap_force_to_gpu(sna->front, MOVE_WRITE)) {
+	if (!sna_pixmap_force_to_gpu(sna->front, xorgMir ? MOVE_READ | MOVE_WRITE
+							 : MOVE_WRITE)) {
 		xf86DrvMsg(screen->myNum, X_ERROR,
 			   "[intel] Failed to allocate video resources for front buffer %dx%d at depth %d\n",
 			   screen->width,
@@ -264,6 +266,9 @@ static Bool sna_create_screen_resources(ScreenPtr screen)
 
 	screen->SetScreenPixmap(sna->front);
 
+	if (xorgMir)
+		return TRUE;
+
 	sna_copy_fbcon(sna);
 
 	if (!sna_become_master(sna)) {
@@ -314,7 +319,6 @@ static int sna_open_drm_master(ScrnInfoPtr scrn)
 	struct sna_device *dev;
 	struct sna *sna = to_sna(scrn);
 	struct pci_device *pci = sna->PciInfo;
-	drmSetVersion sv;
 	int err;
 	char busid[20];
 	int fd;
@@ -333,11 +337,16 @@ static int sna_open_drm_master(ScrnInfoPtr scrn)
 		 pci->domain, pci->bus, pci->dev, pci->func);
 
 	DBG(("%s: opening device '%s'\n",  __FUNCTION__, busid));
-	fd = drmOpen(NULL, busid);
+
+	if (!xorgMir)
+		fd = drmOpen(NULL, busid);
+	else
+		fd = xmir_get_drm_fd(busid);
+
 	if (fd == -1) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "[drm] Failed to open DRM device for %s: %s\n",
-			   busid, strerror(errno));
+			   "[drm] Failed to open DRM device for %s%s: %s\n",
+			   busid, xorgMir ? " from Mir" : "", strerror(errno));
 		return -1;
 	}
 
@@ -345,17 +354,21 @@ static int sna_open_drm_master(ScrnInfoPtr scrn)
 	 * by setting the version of the interface we'll use to talk to it.
 	 * (see DRIOpenDRMMaster() in DRI1)
 	 */
-	sv.drm_di_major = 1;
-	sv.drm_di_minor = 1;
-	sv.drm_dd_major = -1;
-	sv.drm_dd_minor = -1;
-	err = drmSetInterfaceVersion(fd, &sv);
-	if (err != 0) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "[drm] failed to set drm interface version: %s [%d].\n",
-			   strerror(-err), -err);
-		drmClose(fd);
-		return -1;
+	if (!xorgMir) {
+		drmSetVersion sv;
+
+		sv.drm_di_major = 1;
+		sv.drm_di_minor = 1;
+		sv.drm_dd_major = -1;
+		sv.drm_dd_minor = -1;
+		err = drmSetInterfaceVersion(fd, &sv);
+		if (err != 0) {
+			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+				"[drm] failed to set drm interface version: %s [%d].\n",
+				strerror(-err), -err);
+			drmClose(fd);
+			return -1;
+		}
 	}
 
 	dev = malloc(sizeof(*dev));
@@ -386,7 +399,8 @@ static void sna_close_drm_master(ScrnInfoPtr scrn)
 	if (--dev->open_count)
 		return;
 
-	drmClose(dev->fd);
+	if (!xorgMir)
+		drmClose(dev->fd);
 	sna_set_device(scrn, NULL);
 	free(dev);
 }
@@ -469,6 +483,51 @@ static Bool fb_supports_depth(int fd, int depth)
 	return ret;
 }
 
+#ifdef XMIR
+
+static void
+sna_xmir_buffer_available(WindowPtr win)
+{
+	int window_fd;
+	PixmapPtr window_pixmap;
+
+	if(!xmir_window_is_dirty(win))
+		return;
+
+	window_fd = xmir_prime_fd_for_window(win);
+
+	window_pixmap = (*win->drawable.pScreen->GetWindowPixmap)(win);
+	sna_xmir_copy_pixmap_to_mir(window_pixmap, window_fd);
+
+	xmir_submit_rendering_for_window(win, NULL);
+}
+
+static void
+sna_xmir_submit_dirty_window(WindowPtr win, DamagePtr damage)
+{
+	int window_fd;
+	PixmapPtr window_pixmap;
+
+	if(!xmir_window_has_free_buffer(win))
+		return;
+
+	window_fd = xmir_prime_fd_for_window(win);
+
+	window_pixmap = (*win->drawable.pScreen->GetWindowPixmap)(win);
+	sna_xmir_copy_pixmap_to_mir(window_pixmap, window_fd);
+
+	xmir_submit_rendering_for_window(win, DamageRegion(damage));
+
+	DamageEmpty(damage);
+}
+
+static xmir_driver sna_xmir_driver = {
+	XMIR_DRIVER_VERSION,
+	sna_xmir_buffer_available
+};
+
+#endif /* XMIR */
+
 /**
  * This is called before ScreenInit to do any require probing of screen
  * configuration.
@@ -536,6 +595,12 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 	scrn->progClock = TRUE;
 	scrn->rgbBits = 8;
 
+	if (xorgMir) {
+		sna->xmir = xmir_screen_create(scrn);
+		if (!sna->xmir)
+			return FALSE;
+	}
+
 	fd = sna_open_drm_master(scrn);
 	if (fd == -1) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -581,6 +646,9 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 
 	intel_detect_chipset(scrn, sna->pEnt, sna->PciInfo);
 
+	if (sna->xmir && !xmir_screen_pre_init(scrn, sna->xmir, &sna_xmir_driver))
+		return FALSE;
+
 	kgem_init(&sna->kgem, fd, sna->PciInfo, sna->info->gen);
 	if (xf86ReturnOptValBool(sna->Options, OPTION_ACCEL_DISABLE, FALSE) ||
 	    !sna_option_cast_to_bool(sna, OPTION_ACCEL_METHOD, TRUE)) {
@@ -635,7 +703,9 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
 			   "Tiling disabled, expect poor performance and increased power consumption.\n");
 
-	if (!sna_mode_pre_init(scrn, sna)) {
+	if (xorgMir)
+		xf86ProviderSetup(scrn, NULL, "Intel");
+	else if (!sna_mode_pre_init(scrn, sna)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "No outputs and no modes.\n");
 		PreInitCleanup(scrn);
@@ -670,6 +740,10 @@ sna_block_handler(BLOCKHANDLER_ARGS_DECL)
 
 	if (*tv == NULL || ((*tv)->tv_usec | (*tv)->tv_sec))
 		sna_accel_block_handler(sna, tv);
+#ifdef XMIR
+	if (xorgMir)
+		xmir_screen_for_each_damaged_window(sna->xmir, sna_xmir_submit_dirty_window);
+#endif
 }
 
 static void
@@ -829,6 +903,9 @@ static void sna_leave_vt(VT_FUNC_ARGS_DECL)
 
 	DBG(("%s\n", __FUNCTION__));
 
+	if (xorgMir)
+		return;
+
 	xf86_hide_cursors(scrn);
 
 	if (drmDropMaster(sna->kgem.fd))
@@ -846,7 +923,8 @@ static Bool sna_early_close_screen(CLOSE_SCREEN_ARGS_DECL)
 	xf86_hide_cursors(scrn);
 	sna_uevent_fini(scrn);
 
-	sna_mode_close(sna);
+	if (!xorgMir)
+		sna_mode_close(sna);
 
 	if (sna->dri_open) {
 		sna_dri_close(sna, screen);
@@ -886,6 +964,19 @@ static Bool sna_late_close_screen(CLOSE_SCREEN_ARGS_DECL)
 	return TRUE;
 }
 
+#if DRI2INFOREC_VERSION >= 8 && defined(XMIR)
+int sna_dri_auth_magic2(ScreenPtr screen, uint32_t magic)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct sna *sna = to_sna(scrn);
+
+	if (xorgMir)
+		return xmir_auth_drm_magic(sna->xmir, magic);
+	else
+		return drmAuthMagic(sna_device(scrn)->fd, magic);
+}
+#endif
+
 static void sna_mode_set(ScrnInfoPtr scrn)
 {
 	struct sna *sna = to_sna(scrn);
@@ -1007,6 +1098,9 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
 		return FALSE;
 	}
 
+	if (sna->xmir)
+		xmir_screen_init(screen, sna->xmir);
+
 	xf86SetBlackWhitePixels(screen);
 
 	xf86SetBackingStore(screen);
@@ -1014,7 +1108,7 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
 	if (!miDCInitialize(screen, xf86GetPointerScreenFuncs()))
 		return FALSE;
 
-	if (xf86_cursors_init(screen, SNA_CURSOR_X, SNA_CURSOR_Y,
+	if (!xorgMir && xf86_cursors_init(screen, SNA_CURSOR_X, SNA_CURSOR_Y,
 			       HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
 			       HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
 			       HARDWARE_CURSOR_INVERT_MASK |
@@ -1109,6 +1203,10 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL)
 	struct sna *sna = to_sna(scrn);
 
 	DBG(("%s\n", __FUNCTION__));
+
+	if (xorgMir)
+		return xf86SetDesiredModes(scrn);
+
 	if (!sna_become_master(sna))
 		return FALSE;
 
