From 39fce8aec4eb6250da476cdc10623fa72e3c69d0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 25 Aug 2012 20:09:33 +0200 Subject: vmwgfx: Primitive support for XWayland --- src/vmware_bootstrap.c | 18 +++++++ vmwgfx/vmwgfx_dri2.c | 26 ++++++++- vmwgfx/vmwgfx_driver.c | 141 +++++++++++++++++++++++++++++++++++++++++-------- vmwgfx/vmwgfx_driver.h | 11 ++++ vmwgfx/vmwgfx_saa.c | 3 +- vmwgfx/vmwgfx_saa.h | 1 + 6 files changed, 175 insertions(+), 25 deletions(-) diff --git a/src/vmware_bootstrap.c b/src/vmware_bootstrap.c index ea5be19..75606fa 100644 --- a/src/vmware_bootstrap.c +++ b/src/vmware_bootstrap.c @@ -49,6 +49,10 @@ #include #endif +#ifdef XORG_WAYLAND +#include "xf86Priv.h" +#endif + #ifdef HaveDriverFuncs #define VMWARE_DRIVER_FUNC HaveDriverFuncs #else @@ -224,6 +228,15 @@ VMwarePreinitStub(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Driver was compiled without KMS- and 3D support.\n"); #endif /* defined(BUILD_VMWGFX) */ + +#ifdef XORG_WAYLAND + if (xorgWayland) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Can not fallback to vmwlegacy in XWalyand.\n"); + return FALSE; + } +#endif + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling 3D support.\n"); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -424,6 +437,11 @@ VMWareDriverFunc(ScrnInfoPtr pScrn, if (flag) { *flag = HW_IO | HW_MMIO; + +#ifdef XORG_WAYLAND + if (xorgWayland) + *flag = HW_SKIP_CONSOLE; +#endif } return TRUE; case RR_GET_MODE_MM: diff --git a/vmwgfx/vmwgfx_dri2.c b/vmwgfx/vmwgfx_dri2.c index 7de0772..a53cadd 100644 --- a/vmwgfx/vmwgfx_dri2.c +++ b/vmwgfx/vmwgfx_dri2.c @@ -44,6 +44,10 @@ #include "wsbm_util.h" #include +#ifdef XORG_WAYLAND +#include +#endif + #define VMWGFX_FD_PATH_LEN 80 typedef struct { @@ -368,6 +372,21 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, FreeScratchGC(gc); } +#ifdef XORG_WAYLAND +static int dri2_auth_magic2(ScreenPtr pScreen, uint32_t magic) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(pScrn); + + /* Not wayland, go stragight to drm */ + if (!xorgWayland) + return drmAuthMagic(ms->fd, magic); + + /* Forward the request to our host */ + return xwl_drm_authenticate(ms->xwl_screen, magic); +} +#endif + Bool xorg_dri2_init(ScreenPtr pScreen) { @@ -386,7 +405,7 @@ xorg_dri2_init(ScreenPtr pScreen) minor = 0; } - dri2info.version = min(DRI2INFOREC_VERSION, 3); + dri2info.version = min(DRI2INFOREC_VERSION, 4); dri2info.fd = ms->fd; dri2info.driverName = "vmwgfx"; @@ -414,6 +433,11 @@ xorg_dri2_init(ScreenPtr pScreen) dri2info.CopyRegion = dri2_copy_region; dri2info.Wait = NULL; +#ifdef XORG_WAYLAND + dri2info.version = 3; + dri2info.AuthMagic2 = dri2_auth_magic2; +#endif + return DRI2ScreenInit(pScreen, &dri2info); } diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c index 9959ffb..2fed554 100644 --- a/vmwgfx/vmwgfx_driver.c +++ b/vmwgfx/vmwgfx_driver.c @@ -282,6 +282,41 @@ drv_init_drm(ScrnInfoPtr pScrn) return TRUE; } +#ifdef XORG_WAYLAND +static int vmwgfx_create_window_buffer(struct xwl_window *xwl_window, + PixmapPtr pixmap) +{ + struct vmwgfx_saa_pixmap *vpix = NULL; + struct xa_surface *srf = NULL; + uint32_t name, pitch, flags; + + fprintf(stderr, "cwb2: enter\n"); + + if (!vmwgfx_hw_dri2_validate(pixmap, 0)) + return BadDrawable; + + vpix = vmwgfx_saa_pixmap(pixmap); + if (vpix == NULL) + return BadDrawable; + + vpix->hw_is_xwayland = 1; + + srf = vpix->hw; + if (srf == NULL || xa_surface_handle(srf, &name, &pitch) != 0) + return BadDrawable; + + fprintf(stderr, "cwb2: %u %u\n", name, pitch); + + return xwl_create_window_buffer_drm(xwl_window, pixmap, name); +} + +static struct xwl_driver xwl_driver = { + .version = 1, + .use_drm = 1, + .create_window_buffer = vmwgfx_create_window_buffer +}; +#endif + /** * vmwgfx_set_topology - Set the GUI topology according to an option string * @@ -374,9 +409,65 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); xf86SetPrimInitDone(pScrn->entityList[0]); - ms->fd = -1; - if (!drv_init_drm(pScrn)) - goto out_err_bus; + /* Need to do this before xwl_screen_pre_init */ + pScrn->monitor = pScrn->confScreen->monitor; + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + + if (!xf86SetDepthBpp + (pScrn, 0, 0, 0, + PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set depth and bpp.\n"); + goto out_depth; + } + + ms->xwl_screen = NULL; +#ifdef XORG_WAYLAND + if (xorgWayland) { + fprintf(stderr, "Calling xwl_screen_create()\n"); + ms->xwl_screen = xwl_screen_create(); + if (!ms->xwl_screen) { + xfDrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize xwayland.\n"); + goto out_err_bus; + } + + fprintf(stderr, "Calling xwl_screen_pre_init()\n"); + if (!xwl_screen_pre_init(pScrn, ms->xwl_screen, + 0, &xwl_driver)) { + xfDrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize xwayland.\n"); + xwl_screen_destroy(ms->xwl_screen); + goto out_err_bus; + } + + fprintf(stderr, "Calling xwl_screen_get_fb()\n"); + ms->fd = xwl_screen_get_drm_fd(ms->xwl_screen); + /* XXX check for 3D */ + + if (ms->fd >= 0) { + drmVersionPtr ver = drmGetVersion(ms->fd); + + if (ver == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not determine DRM version.\n"); + goto out_err_bus; + } + + ms->drm_major = ver->version_major; + ms->drm_minor = ver->version_minor; + ms->drm_patch = ver->version_patchlevel; + + drmFreeVersion(ver); + } + } +#endif + + if (!ms->xwl_screen) { + ms->fd = -1; + if (!drv_init_drm(pScrn)) + goto out_err_bus; + } if (ms->drm_major != DRM_VERSION_MAJOR_REQUIRED || ms->drm_minor < DRM_VERSION_MINOR_REQUIRED) { @@ -397,17 +488,6 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) ms->check_fb_size = (vmwgfx_max_fb_size(ms->fd, &ms->max_fb_size) == 0); - pScrn->monitor = pScrn->confScreen->monitor; - pScrn->progClock = TRUE; - pScrn->rgbBits = 8; - - if (!xf86SetDepthBpp - (pScrn, 0, 0, 0, - PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set depth and bpp.\n"); - goto out_depth; - } - if (vmwgfx_get_param(ms->fd, DRM_VMW_PARAM_HW_CAPS, &cap) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to detect device " "screen object capability.\n"); @@ -522,10 +602,12 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Falied parsing or setting " "gui topology from config file.\n"); - xorg_crtc_init(pScrn); - xorg_output_init(pScrn); + if (!ms->xwl_screen) { + xorg_crtc_init(pScrn); + xorg_output_init(pScrn); + } - if (!xf86InitialConfiguration(pScrn, TRUE)) { + if (!ms->xwl_screen && !xf86InitialConfiguration(pScrn, TRUE)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); goto out_modes; } @@ -639,10 +721,17 @@ void xorg_flush(ScreenPtr pScreen) struct vmwgfx_saa_pixmap *vpix; int i; xf86CrtcPtr crtc; - PixmapPtr *pixmaps = calloc(config->num_crtc, sizeof(*pixmaps)); + PixmapPtr *pixmaps; unsigned int num_scanout = 0; unsigned int j; + if (ms->xwl_screen) { + xwl_screen_post_damage(ms->xwl_screen); + return; + } + + pixmaps = calloc(config->num_crtc, sizeof(*pixmaps)); + if (!pixmaps) { LogMessage(X_ERROR, "Failed memory allocation during screen " "update.\n"); @@ -733,7 +822,12 @@ drv_create_screen_resources(ScreenPtr pScreen) if (!ret) return ret; - drv_adjust_frame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); + if (!ms->xwl_screen) + drv_adjust_frame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); +#ifdef XORG_WAYLAND + else + xwl_screen_init(ms->xwl_screen, pScreen); +#endif return drv_enter_vt(VT_FUNC_ARGS); } @@ -906,7 +1000,7 @@ drv_screen_init(SCREEN_INIT_ARGS_DECL) modesettingPtr ms = modesettingPTR(pScrn); VisualPtr visual; - if (!drv_set_master(pScrn)) + if (!ms->xwl_screen && !drv_set_master(pScrn)) return FALSE; pScrn->pScreen = pScreen; @@ -1117,7 +1211,7 @@ drv_leave_vt(VT_FUNC_ARGS_DECL) vmwgfx_cursor_bypass(ms->fd, 0, 0); vmwgfx_disable_scanout(pScrn); - if (drmDropMaster(ms->fd)) + if (!ms->xwl_screen && drmDropMaster(ms->fd)) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "drmDropMaster failed: %s\n", strerror(errno)); @@ -1132,11 +1226,12 @@ static Bool drv_enter_vt(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); + modesettingPtr ms = modesettingPTR(pScrn); - if (!drv_set_master(pScrn)) + if (!ms->xwl_screen && !drv_set_master(pScrn)) return FALSE; - if (!xf86SetDesiredModes(pScrn)) + if (!ms->xwl_screen && !xf86SetDesiredModes(pScrn)) return FALSE; return TRUE; diff --git a/vmwgfx/vmwgfx_driver.h b/vmwgfx/vmwgfx_driver.h index f78a85f..a47ebb4 100644 --- a/vmwgfx/vmwgfx_driver.h +++ b/vmwgfx/vmwgfx_driver.h @@ -46,6 +46,11 @@ #include #include +#ifdef XORG_WAYLAND +#include +#include "xf86Priv.h" +#endif + #include "../src/compat-api.h" #ifdef DRI2 #include @@ -135,6 +140,12 @@ typedef struct _modesettingRec Bool dri2_available; char dri2_device_name[VMWGFX_DRI_DEVICE_LEN]; #endif + +#ifdef XORG_WAYLAND + struct xwl_screen *xwl_screen; +#else + void *xwl_screen; +#endif } modesettingRec, *modesettingPtr; #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c index 63df3a1..9c39e21 100644 --- a/vmwgfx/vmwgfx_saa.c +++ b/vmwgfx/vmwgfx_saa.c @@ -1208,7 +1208,8 @@ vmwgfx_operation_complete(struct saa_driver *driver, * case a flush would deadlock in the kernel. */ - if (vpix->hw && vpix->hw_is_dri2_fronts) { + if (vpix->hw && (vpix->hw_is_dri2_fronts || + vpix->hw_is_xwayland)) { if (1 && pScrn->vtSema && vmwgfx_upload_to_hw(driver, pixmap, &spix->dirty_shadow)) { diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h index bb8ec96..b8a58bf 100644 --- a/vmwgfx/vmwgfx_saa.h +++ b/vmwgfx/vmwgfx_saa.h @@ -52,6 +52,7 @@ struct vmwgfx_saa_pixmap { struct xa_surface *hw; uint32_t fb_id; int hw_is_dri2_fronts; + int hw_is_xwayland; struct _WsbmListHead sync_x_head; struct _WsbmListHead scanout_list; -- cgit v1.2.3