Signed-off-by: Christopher James Halse Rogers 
<[email protected]>
---
This is mostly just for testing, although it should be safe to apply to nouveau
trunk.

 src/nouveau_dri2.c |   34 +++++++++++
 src/nv_driver.c    |  163 +++++++++++++++++++++++++++++++++++++++++++++++-----
 src/nv_type.h      |    7 +++
 3 files changed, 191 insertions(+), 13 deletions(-)

diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index 7e47575..cb1a395 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -8,6 +8,10 @@
 #ifdef DRI2
 #include "dri2.h"
 #endif
+#ifdef XORG_WAYLAND
+#include <xf86Priv.h>
+#include <xwayland.h>
+#endif
 
 #if defined(DRI2) && DRI2INFOREC_VERSION >= 3
 struct nouveau_dri2_buffer {
@@ -660,6 +664,32 @@ nouveau_dri2_flip_event_handler(unsigned int frame, 
unsigned int tv_sec,
        free(flip);
 }
 
+#ifdef XORG_WAYLAND
+static int nouveau_auth_magic(int fd, uint32_t magic)
+{
+       ScrnInfoPtr pScrn;
+       NVPtr pNv;
+       int i;
+
+       /* Not wayland, go stragight to drm */
+       if (!xorgWayland)
+               return drmAuthMagic(fd, magic);
+
+       /* Technically this should actually iterate over xf86Screens.
+          Since direct access to xf86Screens is going away, though, 
+          we don't bother right now */
+       for (i = 0; i < 1; i++) {
+               pScrn = xf86Screens[i];
+               pNv = NVPTR(pScrn);
+               if (xwl_screen_get_drm_fd(pNv->xwl_screen) == fd)
+                       break;
+       }
+
+       /* Forward the request to our host */
+       return xwl_drm_authenticate(pNv->xwl_screen, magic);
+}
+#endif
+
 Bool
 nouveau_dri2_init(ScreenPtr pScreen)
 {
@@ -689,6 +719,10 @@ nouveau_dri2_init(ScreenPtr pScreen)
        dri2.ScheduleWaitMSC = nouveau_dri2_schedule_wait;
        dri2.GetMSC = nouveau_dri2_get_msc;
 
+#if DRI2INFOREC_VERSION >= 5 && defined(XORG_WAYLAND)
+       dri2.AuthMagic = nouveau_auth_magic;
+#endif
+
 #if DRI2INFOREC_VERSION >= 6
        dri2.SwapLimitValidate = nouveau_dri2_swap_limit_validate;
 #endif
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 9f6d75f..79c5c39 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -32,6 +32,10 @@
 #ifdef DRI2
 #include "dri2.h"
 #endif
+#ifdef XORG_WAYLAND
+#include <xf86Priv.h>
+#include <xwayland.h>
+#endif
 
 /*
  * Forward definitions for the functions that make up the driver.
@@ -73,6 +77,28 @@ static Bool NVPciProbe (     DriverPtr               drv,
                                struct pci_device       *dev,
                                intptr_t                match_data      );
 
+
+static Bool nouveau_driver_func(ScrnInfoPtr pScrn,
+                               xorgDriverFuncOp op,
+                               pointer ptr)
+{
+       xorgHWFlags *flag;
+
+       switch (op) {
+       case GET_REQUIRED_HW_INTERFACES:
+               flag = (CARD32*)ptr;
+               (*flag) = 0;
+#ifdef XORG_WAYLAND
+               if (xorgWayland)
+                       (*flag) = HW_SKIP_CONSOLE;
+#endif
+               return TRUE;
+       default:
+               /* Unknown or deprecated function */
+               return FALSE;
+       }
+}
+
 /*
  * This contains the functions needed by the server after loading the
  * driver module.  It must be supplied, and gets added the driver list by
@@ -89,7 +115,7 @@ _X_EXPORT DriverRec NV = {
        NVAvailableOptions,
        NULL,
        0,
-       NULL,
+       nouveau_driver_func,
        nouveau_device_match,
        NVPciProbe
 };
@@ -215,7 +241,28 @@ NVPciProbe(DriverPtr drv, int entity_num, struct 
pci_device *pci_dev,
        drmVersion *version;
        int chipset, ret;
        char *busid;
+#ifdef XORG_WAYLAND
+       struct xwl_screen *xwl_screen = NULL;
 
+       if (xorgWayland) {
+               xwl_screen = xwl_screen_create ();
+               if (!xwl_screen) {
+                       xf86DrvMsg(-1, X_ERROR, "Failed to initialise 
xwayland.\n");
+                       return FALSE;
+               }
+               if (xwl_drm_pre_init(xwl_screen) != Success) {
+                       xwl_screen_destroy(xwl_screen);
+                       xf86DrvMsg(-1, X_ERROR, "Failed to initialise xwayland 
drm.\n");
+                       return FALSE;
+               }
+               ret = nouveau_device_wrap(xwl_screen_get_drm_fd(xwl_screen), 0, 
&dev);
+               if (ret) {
+                       xwl_screen_destroy(xwl_screen);
+                       xf86DrvMsg(-1, X_ERROR, "[drm] Failed to create drm 
device.\n");
+                       return FALSE;
+               }
+       } else {
+#endif
        if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
                xf86DrvMsg(-1, X_ERROR, "[drm] No DRICreatePCIBusID symbol\n");
                return FALSE;
@@ -229,6 +276,17 @@ NVPciProbe(DriverPtr drv, int entity_num, struct 
pci_device *pci_dev,
                return FALSE;
        }
 
+       ret = drmCheckModesettingSupported(busid);
+       if (ret) {
+               xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n");
+               return FALSE;
+       }
+       free(busid);
+
+#ifdef XORG_WAYLAND
+       }
+#endif
+
        /* Check the version reported by the kernel module.  In theory we
         * shouldn't have to do this, as libdrm_nouveau will do its own checks.
         * But, we're currently using the kernel patchlevel to also version
@@ -243,13 +301,6 @@ NVPciProbe(DriverPtr drv, int entity_num, struct 
pci_device *pci_dev,
        chipset = dev->chipset;
        nouveau_device_del(&dev);
 
-       ret = drmCheckModesettingSupported(busid);
-       free(busid);
-       if (ret) {
-               xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n");
-               return FALSE;
-       }
-
        switch (chipset & 0xf0) {
        case 0x00:
        case 0x10:
@@ -266,14 +317,21 @@ NVPciProbe(DriverPtr drv, int entity_num, struct 
pci_device *pci_dev,
        case 0xe0:
                break;
        default:
+#ifdef XORG_WAYLAND
+               xwl_screen_destroy(xwl_screen);
+#endif
                xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset);
                return FALSE;
        }
 
        pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, NVChipsets,
                                    NULL, NULL, NULL, NULL, NULL);
-       if (!pScrn)
+       if (!pScrn) {
+#ifdef XORG_WAYLAND
+               xwl_screen_destroy(xwl_screen);
+#endif
                return FALSE;
+       }
 
        pScrn->driverVersion    = NV_VERSION;
        pScrn->driverName       = NV_DRIVER_NAME;
@@ -288,6 +346,10 @@ NVPciProbe(DriverPtr drv, int entity_num, struct 
pci_device *pci_dev,
        pScrn->LeaveVT          = NVLeaveVT;
        pScrn->FreeScreen       = NVFreeScreen;
 
+#ifdef XORG_WAYLAND
+       pScrn->driverPrivate    = xwl_screen;
+#endif
+
        xf86SetEntitySharable(entity_num);
 
        pEnt = xf86GetEntityInfo(entity_num);
@@ -376,6 +438,11 @@ NVFlushCallback(CallbackListPtr *list, pointer user_data, 
pointer call_data)
 
        if (pScrn->vtSema && !pNv->NoAccel)
                nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel);
+#ifdef XORG_WAYLAND
+       if (pNv->xwl_screen)
+               xwl_screen_post_damage(pNv->xwl_screen);
+#endif
+
 }
 
 static void 
@@ -399,6 +466,11 @@ NVBlockHandler (
 
        if (pNv->VideoTimerCallback) 
                (*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+
+#ifdef XORG_WAYLAND
+       if (pNv->xwl_screen)
+               xwl_screen_post_damage(pNv->xwl_screen);
+#endif
 }
 
 static Bool
@@ -413,6 +485,11 @@ NVCreateScreenResources(ScreenPtr pScreen)
                return FALSE;
        pScreen->CreateScreenResources = NVCreateScreenResources;
 
+#ifdef XORG_WAYLAND
+       if (pNv->xwl_screen)
+               xwl_screen_init(pNv->xwl_screen, pScreen);
+#endif
+
        drmmode_fbcon_copy(pScreen);
        if (!NVEnterVT(pScrn->scrnIndex, 0))
                return FALSE;
@@ -425,6 +502,27 @@ NVCreateScreenResources(ScreenPtr pScreen)
        return TRUE;
 }
 
+#ifdef XORG_WAYLAND
+static int nouveau_create_window_buffer(struct xwl_window *xwl_window,
+                                       PixmapPtr pixmap)
+{
+       uint32_t name;
+       struct nouveau_bo *bo;
+
+       bo = nouveau_pixmap_bo(pixmap);
+       if (bo == NULL || nouveau_bo_name_get(bo, &name) != 0)
+               return BadDrawable;
+
+       return xwl_create_window_buffer_drm(xwl_window, pixmap, name);
+}
+
+static struct xwl_driver xwl_driver = {
+       .version = 1,
+       .use_drm = 1,
+       .create_window_buffer = nouveau_create_window_buffer
+};
+#endif
+
 /*
  * This is called at the end of each server generation.  It restores the
  * original (text) mode.  It should also unmap the video memory, and free
@@ -439,6 +537,11 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
        ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
        NVPtr pNv = NVPTR(pScrn);
 
+#ifdef XORG_WAYLAND
+       if (pNv->xwl_screen)
+               xwl_screen_close(pNv->xwl_screen);
+#endif
+
        drmmode_screen_fini(pScreen);
 
        if (!pNv->NoAccel)
@@ -507,6 +610,11 @@ NVFreeScreen(int scrnIndex, int flags)
        if (!pNv)
                return;
 
+#ifdef XORG_WAYLAND
+       if (pNv->xwl_screen)
+               xwl_screen_destroy(pNv->xwl_screen);
+#endif
+
        NVCloseDRM(pScrn);
 
        free(pScrn->driverPrivate);
@@ -568,10 +676,16 @@ NVPreInitDRM(ScrnInfoPtr pScrn)
        NVPtr pNv = NVPTR(pScrn);
        char *bus_id;
        int ret;
+       int drm_fd;
 
        if (!NVDRIGetVersion(pScrn))
                return FALSE;
 
+#ifdef XORG_WAYLAND
+       if (pNv->xwl_screen)
+               drm_fd = xwl_screen_get_drm_fd(pNv->xwl_screen);
+       else {
+#endif
        /* Load the kernel module, and open the DRM */
        bus_id = DRICreatePCIBusID(pNv->PciInfo);
        ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, bus_id, "nouveau");
@@ -582,8 +696,13 @@ NVPreInitDRM(ScrnInfoPtr pScrn)
                return FALSE;
        }
 
+       drm_fd = DRIMasterFD(pScrn);
+#ifdef XORG_WAYLAND
+       }
+#endif
+
        /* Initialise libdrm_nouveau */
-       ret = nouveau_device_wrap(DRIMasterFD(pScrn), 1, &pNv->dev);
+       ret = nouveau_device_wrap(drm_fd, 1, &pNv->dev);
        if (ret) {
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                           "[drm] error creating device\n");
@@ -594,7 +713,7 @@ NVPreInitDRM(ScrnInfoPtr pScrn)
        if (ret)
                return FALSE;
 
-       pNv->drm_device_name = drmGetDeviceNameFromFd(DRIMasterFD(pScrn));
+       pNv->drm_device_name = drmGetDeviceNameFromFd(drm_fd);
 
        return TRUE;
 }
@@ -610,6 +729,9 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
        uint64_t v;
        int ret;
        int defaultDepth = 0;
+#ifdef XORG_WAYLAND
+       struct xwl_screen *xwl_screen = pScrn->driverPrivate;
+#endif
 
        if (flags & PROBE_DETECT) {
                EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
@@ -643,6 +765,10 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
        if (!(pScrn->driverPrivate = xnfcalloc(1, sizeof(NVRec))))
                return FALSE;
        pNv = NVPTR(pScrn);
+       
+#ifdef XORG_WAYLAND
+       pNv->xwl_screen = xwl_screen;
+#endif
 
        /* Get the entity, and make sure it is PCI. */
        pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
@@ -780,6 +906,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
        memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
        xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
 
+#ifdef XORG_WAYLAND
+       if (xwl_screen) {
+               if (!xwl_screen_pre_init(pScrn, xwl_screen, 0, &xwl_driver)) {
+                       NVPreInitFail("Failed to initialise xwayland\n");
+               }
+       }
+#endif
+
        from = X_DEFAULT;
 
        pNv->HWCursor = TRUE;
@@ -887,8 +1021,8 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
        xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed 
%d]%s\n",
                   pNv->swap_limit, pNv->max_swap_limit, reason);
 
-       ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3);
-       if (ret == FALSE)
+       if (!xwl_screen && 
+               !drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 
3))
                NVPreInitFail("Kernel modesetting failed to initialize\n");
 
        /*
@@ -1267,6 +1401,9 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 
char **argv)
        if (serverGeneration == 1)
                xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
+#ifdef XORG_WAYLAND
+       if (!pNv->xwl_screen)
+#endif
        drmmode_screen_init(pScreen);
        return TRUE;
 }
diff --git a/src/nv_type.h b/src/nv_type.h
index 49150ba..4e36b7f 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -15,6 +15,9 @@
 #else
 #error "This driver requires a DRI-enabled X server"
 #endif
+#ifdef XORG_WAYLAND
+#include <xwayland.h>
+#endif
 
 #define NV_ARCH_03  0x03
 #define NV_ARCH_04  0x04
@@ -76,6 +79,10 @@ typedef struct _NVRec {
 
        void *drmmode; /* for KMS */
 
+#ifdef XORG_WAYLAND
+       struct xwl_screen *xwl_screen;
+#endif
+
        /* DRM interface */
        struct nouveau_device *dev;
        char *drm_device_name;
-- 
1.7.10

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to