Bool ephyrDRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd, char **driverName, char **deviceName) { Display *dpy = hostx_get_display () ; return DRI2Connect(dpy, RootWindow(dpy, DefaultScreen(dpy)), driverName, deviceName); }
BOOL DRI2FallbackOpen(Display *dpy, int screen, int *device_fd) { char *device; int fd; Window root = RootWindow(dpy, screen); drm_auth_t auth; if (!DRI2Connect(dpy, root, DRI2DriverDRI, &device)) return FALSE; fd = open(device, O_RDWR); HeapFree(GetProcessHeap(), 0, device); if (fd < 0) return FALSE; if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth) != 0) { close(fd); return FALSE; } if (!DRI2Authenticate(dpy, root, auth.magic)) { close(fd); return FALSE; } *device_fd = fd; return TRUE; }
int dri2_open(Display *dpy) { drm_auth_t auth; char *driver, *device; int fd; if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device)) return -1; fd = open(device, O_RDWR); if (fd < 0) return -1; if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) goto err_fd; if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic)) goto err_fd; return fd; err_fd: close(fd); return -1; }
static int dri2_connect(Display *dpy, char **driver) { int eventBase, errorBase, major, minor; char *device; drm_magic_t magic; Window root; int fd; if (!DRI2InitDisplay(dpy, &ops)) { ERROR_MSG("DRI2InitDisplay failed"); return -1; } if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) { ERROR_MSG("DRI2QueryExtension failed"); return -1; } MSG("DRI2QueryExtension: eventBase=%d, errorBase=%d", eventBase, errorBase); if (!DRI2QueryVersion(dpy, &major, &minor)) { ERROR_MSG("DRI2QueryVersion failed"); return -1; } MSG("DRI2QueryVersion: major=%d, minor=%d", major, minor); root = RootWindow(dpy, DefaultScreen(dpy)); if (!DRI2Connect(dpy, root, driver, &device)) { ERROR_MSG("DRI2Connect failed"); return -1; } MSG("DRI2Connect: driver=%s, device=%s", *driver, device); fd = open(device, O_RDWR); if (fd < 0) { ERROR_MSG("open failed"); return fd; } if (drmGetMagic(fd, &magic)) { ERROR_MSG("drmGetMagic failed"); return -1; } if (!DRI2Authenticate(dpy, root, magic)) { ERROR_MSG("DRI2Authenticate failed"); return -1; } return fd; }
/* * Given a display pointer and screen number, determine the name of * the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc). * Return True for success, False for failure. */ static Bool driGetDriverName(Display * dpy, int scrNum, char **driverName) { int directCapable; Bool b; int event, error; int driverMajor, driverMinor, driverPatch; *driverName = NULL; if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */ if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) { ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n"); return False; } if (!directCapable) { ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n"); return False; } b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, &driverPatch, driverName); if (!b) { ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum); return False; } InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", driverMajor, driverMinor, driverPatch, *driverName, scrNum); return True; } else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */ char *dev; Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev); if (ret) free(dev); return ret; } return False; }
/** * Probe the screen for the DRI2 driver name. */ const char * x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor) { if (!x11_screen_init_dri2(xscr)) return NULL; /* get the driver name and the device name */ if (!xscr->dri_driver) { if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number), &xscr->dri_driver, &xscr->dri_device)) xscr->dri_driver = xscr->dri_device = NULL; } if (major) *major = xscr->dri_major; if (minor) *minor = xscr->dri_minor; return xscr->dri_driver; }
static int dri2_open(Display *dpy) { drm_auth_t auth; char *driver, *device; int fd; if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device)) return -1; printf ("Connecting to %s driver on %s\n", driver, device); fd = open("/dev/dri/card0", O_RDWR); if (fd < 0) return -1; if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -1; if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic)) return -1; return fd; }
static int ProcDRI2Connect(ClientPtr client) { REQUEST(xDRI2ConnectReq); xDRI2ConnectReply rep; DrawablePtr pDraw; int fd, status; const char *driverName; const char *deviceName; REQUEST_SIZE_MATCH(xDRI2ConnectReq); if (!validDrawable(client, stuff->window, DixGetAttrAccess, &pDraw, &status)) return status; rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; rep.driverNameLength = 0; rep.deviceNameLength = 0; if (!DRI2Connect(pDraw->pScreen, stuff->driverType, &fd, &driverName, &deviceName)) goto fail; rep.driverNameLength = strlen(driverName); rep.deviceNameLength = strlen(deviceName); rep.length = (rep.driverNameLength + 3) / 4 + (rep.deviceNameLength + 3) / 4; fail: WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); WriteToClient(client, rep.driverNameLength, driverName); WriteToClient(client, rep.deviceNameLength, deviceName); return Success; }
static int ProcDRI2QueryVersion(ClientPtr client) { REQUEST(xDRI2QueryVersionReq); xDRI2QueryVersionReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .majorVersion = dri2_major, .minorVersion = dri2_minor }; if (client->swapped) swaps(&stuff->length); REQUEST_SIZE_MATCH(xDRI2QueryVersionReq); if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.majorVersion); swapl(&rep.minorVersion); } WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep); return Success; } static int ProcDRI2Connect(ClientPtr client) { REQUEST(xDRI2ConnectReq); xDRI2ConnectReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .driverNameLength = 0, .deviceNameLength = 0 }; DrawablePtr pDraw; int fd, status; const char *driverName; const char *deviceName; REQUEST_SIZE_MATCH(xDRI2ConnectReq); if (!validDrawable(client, stuff->window, DixGetAttrAccess, &pDraw, &status)) return status; if (!DRI2Connect(client, pDraw->pScreen, stuff->driverType, &fd, &driverName, &deviceName)) goto fail; rep.driverNameLength = strlen(driverName); rep.deviceNameLength = strlen(deviceName); rep.length = (rep.driverNameLength + 3) / 4 + (rep.deviceNameLength + 3) / 4; fail: WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); WriteToClient(client, rep.driverNameLength, driverName); WriteToClient(client, rep.deviceNameLength, deviceName); return Success; } static int ProcDRI2Authenticate(ClientPtr client) { REQUEST(xDRI2AuthenticateReq); xDRI2AuthenticateReply rep; DrawablePtr pDraw; int status; REQUEST_SIZE_MATCH(xDRI2AuthenticateReq); if (!validDrawable(client, stuff->window, DixGetAttrAccess, &pDraw, &status)) return status; rep = (xDRI2AuthenticateReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .authenticated = DRI2Authenticate(client, pDraw->pScreen, stuff->magic) }; WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep); return Success; } static void DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id) { ClientPtr client = priv; xDRI2InvalidateBuffers event = { .type = DRI2EventBase + DRI2_InvalidateBuffers, .drawable = id }; WriteEventsToClient(client, 1, (xEvent *) &event); } static int ProcDRI2CreateDrawable(ClientPtr client) { REQUEST(xDRI2CreateDrawableReq); DrawablePtr pDrawable; int status; REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); if (!validDrawable(client, stuff->drawable, DixAddAccess, &pDrawable, &status)) return status; status = DRI2CreateDrawable(client, pDrawable, stuff->drawable, DRI2InvalidateBuffersEvent, client); if (status != Success) return status; return Success; }
static __GLXDRIscreen * dri2CreateScreen(__GLXscreenConfigs * psc, int screen, __GLXdisplayPrivate * priv) { const __DRIconfig **driver_configs; const __DRIextension **extensions; const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *) priv->dri2Display; __GLXDRIscreen *psp; char *driverName, *deviceName; drm_magic_t magic; int i; psp = Xmalloc(sizeof *psp); if (psp == NULL) return NULL; if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen), &driverName, &deviceName)) { XFree(psp); return NULL; } psc->driver = driOpenDriver(driverName); if (psc->driver == NULL) { ErrorMessageF("driver pointer missing\n"); goto handle_error; } extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); if (extensions == NULL) { ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); goto handle_error; } for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_CORE) == 0) psc->core = (__DRIcoreExtension *) extensions[i]; if (strcmp(extensions[i]->name, __DRI_DRI2) == 0) psc->dri2 = (__DRIdri2Extension *) extensions[i]; } if (psc->core == NULL || psc->dri2 == NULL) { ErrorMessageF("core dri or dri2 extension not found\n"); goto handle_error; } psc->fd = open(deviceName, O_RDWR); if (psc->fd < 0) { ErrorMessageF("failed to open drm device: %s\n", strerror(errno)); goto handle_error; } if (drmGetMagic(psc->fd, &magic)) { ErrorMessageF("failed to get magic\n"); goto handle_error; } if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) { ErrorMessageF("failed to authenticate magic %d\n", magic); goto handle_error; } /* If the server does not support the protocol for * DRI2GetBuffersWithFormat, don't supply that interface to the driver. */ psc->__driScreen = psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1) ? loader_extensions_old : loader_extensions), &driver_configs, psc); if (psc->__driScreen == NULL) { ErrorMessageF("failed to create dri screen\n"); goto handle_error; } driBindCommonExtensions(psc); dri2BindExtensions(psc); psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); psc->driver_configs = driver_configs; psp->destroyScreen = dri2DestroyScreen; psp->createContext = dri2CreateContext; psp->createDrawable = dri2CreateDrawable; psp->swapBuffers = dri2SwapBuffers; psp->waitGL = dri2WaitGL; psp->waitX = dri2WaitX; psp->getDrawableMSC = NULL; psp->waitForMSC = NULL; psp->waitForSBC = NULL; psp->setSwapInterval = NULL; psp->getSwapInterval = NULL; if (pdp->driMinor >= 2) { #ifdef X_DRI2GetMSC psp->getDrawableMSC = dri2DrawableGetMSC; #endif #ifdef X_DRI2WaitMSC psp->waitForMSC = dri2WaitForMSC; psp->waitForSBC = dri2WaitForSBC; #endif #ifdef X_DRI2SwapInterval psp->setSwapInterval = dri2SetSwapInterval; psp->getSwapInterval = dri2GetSwapInterval; #endif #if defined(X_DRI2GetMSC) && defined(X_DRI2WaitMSC) && defined(X_DRI2SwapInterval) __glXEnableDirectExtension(psc, "GLX_OML_sync_control"); #endif } /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always * available.*/ psp->copySubBuffer = dri2CopySubBuffer; __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer"); Xfree(driverName); Xfree(deviceName); return psp; handle_error: Xfree(driverName); Xfree(deviceName); XFree(psp); /* FIXME: clean up here */ return NULL; }