Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}