On Wed, 23 May 2012 13:08:08 +0100, Christopher James Halse Rogers
<[email protected]> wrote:
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.
Hi Chris
Thanks for the patch although it does not build on my system.
Comments inline
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);
Consider moving the free() before the conditional, or it will leak memory
+
+#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 &&
xwl_screen is undefined on a non wayland build, resulting build failure
Regards
Emil
+ !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;
_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau