static __GLXDRIscreen * driCreateScreen(__GLXscreenConfigs * psc, int screen, __GLXdisplayPrivate * priv) { __GLXDRIscreen *psp; const __DRIconfig **driver_configs; const __DRIextension **extensions; const char *driverName = "swrast"; int i; psp = Xcalloc(1, sizeof *psp); if (psp == NULL) return NULL; psc->driver = driOpenDriver(driverName); if (psc->driver == NULL) 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_SWRAST) == 0) psc->swrast = (__DRIswrastExtension *) extensions[i]; } if (psc->core == NULL || psc->swrast == NULL) { ErrorMessageF("core dri extension not found\n"); goto handle_error; } psc->__driScreen = psc->swrast->createNewScreen(screen, loader_extensions, &driver_configs, psc); if (psc->__driScreen == NULL) { ErrorMessageF("failed to create dri screen\n"); goto handle_error; } driBindExtensions(psc); driBindCommonExtensions(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 = driDestroyScreen; psp->createContext = driCreateContext; psp->createDrawable = driCreateDrawable; psp->swapBuffers = driSwapBuffers; psp->waitX = NULL; psp->waitGL = NULL; return psp; handle_error: Xfree(psp); if (psc->driver) dlclose(psc->driver); ErrorMessageF("reverting to indirect rendering\n"); return NULL; }
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; /* Initialize per screen dynamic client GLX extensions */ psc->ext_list_first_time = GL_TRUE; if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen), &driverName, &deviceName)) 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)); return NULL; } if (drmGetMagic(psc->fd, &magic)) { ErrorMessageF("failed to get magic\n"); return NULL; } if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) { ErrorMessageF("failed to authenticate magic %d\n", magic); return NULL; } /* 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"); return NULL; } driBindExtensions(psc, 1); 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; /* 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); /* FIXME: clean up here */ return NULL; }