[Intel-gfx] [RFC PATCH 2/2] sna: Support running nested in Mir

christopher.halse.rogers at canonical.com christopher.halse.rogers at canonical.com
Mon Jul 22 08:44:40 CEST 2013


From: Christopher James Halse Rogers <raof at ubuntu.com>

This is pretty much functional for both SNA and UXA, but can't reasonably
be applied until the Xserver patch has landed, and that needs more work.

This demonstrates the approach, however.

There's probably some code to be shared with XWayland support, around the
output handling (or lack thereof) and possibly integration with the underlying
compositor for SwapBuffers etc.

---
 src/intel.h          |   7 ++
 src/intel_display.c  |  18 +++++
 src/intel_dri.c      |  23 +++++++
 src/intel_driver.c   | 191 ++++++++++++++++++++++++++++++++++++++++++++-------
 src/intel_module.c   |  30 +++++++-
 src/sna/sna.h        |  12 ++++
 src/sna/sna_accel.c  |  28 ++++++++
 src/sna/sna_dri.c    |   5 ++
 src/sna/sna_driver.c | 140 +++++++++++++++++++++++++++++++------
 9 files changed, 406 insertions(+), 48 deletions(-)

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;
 
-- 
1.8.3.2




More information about the Intel-gfx mailing list