Example #1
0
static EGLBoolean
haiku_add_configs_for_visuals(_EGLDisplay *dpy)
{
	printf("Adding configs\n");

	struct haiku_egl_config* conf;
	conf = CALLOC_STRUCT(haiku_egl_config);

	_eglInitConfig(&conf->base, dpy, 1);
	_eglLog(_EGL_DEBUG,"Config inited\n");
	_eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_LUMINANCE_SIZE, 0);
	_eglSetConfigKey(&conf->base, EGL_ALPHA_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
	EGLint r = (_eglGetConfigKey(&conf->base, EGL_RED_SIZE) 
		+ _eglGetConfigKey(&conf->base, EGL_GREEN_SIZE)
		+ _eglGetConfigKey(&conf->base, EGL_BLUE_SIZE)
		+ _eglGetConfigKey(&conf->base, EGL_ALPHA_SIZE));
	_eglSetConfigKey(&conf->base, EGL_BUFFER_SIZE, r);
	_eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, EGL_NONE);
	_eglSetConfigKey(&conf->base, EGL_CONFIG_ID, 1);
	_eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
	_eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
	_eglSetConfigKey(&conf->base, EGL_STENCIL_SIZE, 0);
	_eglSetConfigKey(&conf->base, EGL_TRANSPARENT_TYPE, EGL_NONE);
	_eglSetConfigKey(&conf->base, EGL_NATIVE_RENDERABLE, EGL_TRUE); // Let's say yes
	_eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0); // No visual
	_eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); // No visual
	_eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, 0x8);
	_eglSetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_SAMPLES, _eglGetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS) == 0 ? 0 : 0);
	_eglSetConfigKey(&conf->base, EGL_DEPTH_SIZE, 24); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_LEVEL, 0);
	_eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_WIDTH, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_HEIGHT, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/);

	printf("Config configuated\n");
	if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
		_eglLog(_EGL_DEBUG, "Haiku failed to validate config");
		return EGL_FALSE;
	}
	printf("Validated config\n");
   
	_eglLinkConfig(&conf->base);
	if (!_eglGetArraySize(dpy->Configs)) {
		_eglLog(_EGL_WARNING, "Haiku: failed to create any config");
		return EGL_FALSE;
	}
	printf("Config successful!\n");
   
	return EGL_TRUE;
}
Example #2
0
/**
 * Initialize a criteria config from the given attribute list.
 * Return EGL_FALSE if any of the attribute is invalid.
 */
EGLBoolean
_eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy,
                          const EGLint *attrib_list)
{
   EGLint attr, val, i;

   _eglInitConfig(conf, dpy, EGL_DONT_CARE);

   /* reset to default values */
   for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
      attr = _eglValidationTable[i].attr;
      val = _eglValidationTable[i].default_value;
      _eglSetConfigKey(conf, attr, val);
   }

   /* parse the list */
   for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i += 2) {
      attr = attrib_list[i];
      val = attrib_list[i + 1];

      if (!_eglIsConfigAttribValid(conf, attr))
         return EGL_FALSE;

      _eglSetConfigKey(conf, attr, val);
   }

   if (!_eglValidateConfig(conf, EGL_TRUE))
      return EGL_FALSE;

   /* EGL_LEVEL and EGL_MATCH_NATIVE_PIXMAP cannot be EGL_DONT_CARE */
   if (conf->Level == EGL_DONT_CARE ||
       conf->MatchNativePixmap == EGL_DONT_CARE)
      return EGL_FALSE;

   /* ignore other attributes when EGL_CONFIG_ID is given */
   if (conf->ConfigID != EGL_DONT_CARE) {
      for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
         attr = _eglValidationTable[i].attr;
         if (attr != EGL_CONFIG_ID)
            _eglSetConfigKey(conf, attr, EGL_DONT_CARE);
      }
   }
   else {
      if (!(conf->SurfaceType & EGL_WINDOW_BIT))
         conf->NativeVisualType = EGL_DONT_CARE;

      if (conf->TransparentType == EGL_NONE) {
         conf->TransparentRedValue = EGL_DONT_CARE;
         conf->TransparentGreenValue = EGL_DONT_CARE;
         conf->TransparentBlueValue = EGL_DONT_CARE;
      }
   }

   return EGL_TRUE;
}
Example #3
0
/**
 * Create the EGLConfigs.  (one per X visual)
 */
static void
create_configs(_EGLDriver *drv, EGLDisplay dpy)
{
   static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
                                   EGL_OPENGL_ES2_BIT |
                                   EGL_OPENVG_BIT |
                                   EGL_OPENGL_BIT);
   _EGLDisplay *disp = _eglLookupDisplay(dpy);
   XVisualInfo *visInfo, visTemplate;
   int num_visuals, i;

   /* get list of all X visuals, create an EGL config for each */
   visTemplate.screen = DefaultScreen(disp->Xdpy);
   visInfo = XGetVisualInfo(disp->Xdpy, VisualScreenMask,
                            &visTemplate, &num_visuals);
   if (!visInfo) {
      printf("egl_xlib.c: couldn't get any X visuals\n");
      abort();
   }

   for (i = 0; i < num_visuals; i++) {
      _EGLConfig *config = calloc(1, sizeof(_EGLConfig));
      int id = i + 1;
      int rbits = bitcount(visInfo[i].red_mask);
      int gbits = bitcount(visInfo[i].green_mask);
      int bbits = bitcount(visInfo[i].blue_mask);
      int abits = bbits == 8 ? 8 : 0;
      int zbits = 24;
      int sbits = 8;
      int visid = visInfo[i].visualid;
#if defined(__cplusplus) || defined(c_plusplus)
      int vistype = visInfo[i].c_class;
#else
      int vistype = visInfo[i].class;
#endif

      _eglInitConfig(config, id);
      SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, rbits + gbits + bbits + abits);
      SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, rbits);
      SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, gbits);
      SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, bbits);
      SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, abits);
      SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, zbits);
      SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits);
      SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid);
      SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype);
      SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE);
      SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis);
      SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis);
      SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);

      _eglAddConfig(disp, config);
   }
}
/**
 * Add configs to display and return the next config ID.
 */
static EGLint
egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
{
   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
   const struct native_config **native_configs;
   enum pipe_format depth_stencil_formats[8];
   int num_formats, num_configs, i, j;
   int preserve_buffer, max_swap_interval, premultiplied_alpha;

   native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
   if (!num_configs) {
      if (native_configs)
         FREE(native_configs);
      return id;
   }

   preserve_buffer =
      gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER);
   max_swap_interval =
      gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL);
   premultiplied_alpha =
      gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PREMULTIPLIED_ALPHA);

   num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
         depth_stencil_formats);

   for (i = 0; i < num_configs; i++) {
      for (j = 0; j < num_formats; j++) {
         struct egl_g3d_config *gconf;

         gconf = CALLOC_STRUCT(egl_g3d_config);
         if (gconf) {
            _eglInitConfig(&gconf->base, dpy, id);
            if (!egl_g3d_init_config(drv, dpy, &gconf->base,
                     native_configs[i], depth_stencil_formats[j],
                     preserve_buffer, max_swap_interval,
                     premultiplied_alpha)) {
               FREE(gconf);
               break;
            }

            _eglLinkConfig(&gconf->base);
            id++;
         }
      }
   }

   FREE(native_configs);
   return id;
}
Example #5
0
static EGLBoolean
convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m)
{
   static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
                                   EGL_OPENGL_ES2_BIT |
                                   EGL_OPENVG_BIT |
                                   EGL_OPENGL_BIT);
   EGLint val;

   _eglInitConfig(conf, id);
   if (!_eglConfigFromContextModesRec(conf, m, all_apis, all_apis))
      return EGL_FALSE;

   if (m->doubleBufferMode) {
      /* pixmap and pbuffer surfaces are always single-buffered */
      val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
      val &= ~(EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
      SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, val);
   }
   else {
      /* EGL requires OpenGL ES context to be double-buffered */
      val = GET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE);
      val &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
      SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, val);
   }
   /* skip "empty" config */
   if (!val)
      return EGL_FALSE;

   val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
   if (!(val & EGL_PBUFFER_BIT)) {
      /* bind-to-texture cannot be EGL_TRUE without pbuffer bit */
      SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
      SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
   }

   /* EGL_NATIVE_RENDERABLE is a boolean */
   val = GET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE);
   if (val != EGL_TRUE)
      SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_FALSE);

   return _eglValidateConfig(conf, EGL_FALSE);
}
Example #6
0
/**
 * Typical fallback routine for eglChooseConfig
 */
EGLBoolean
_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
                 EGLConfig *configs, EGLint config_size, EGLint *num_configs)
{
   _EGLConfig **configList, criteria;
   EGLint i, count;

   if (!num_configs)
      return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs");

   _eglInitConfig(&criteria, disp, 0);
   if (!_eglParseConfigAttribList(&criteria, attrib_list))
      return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");

   /* allocate array of config pointers */
   configList = (_EGLConfig **)
      malloc(disp->NumConfigs * sizeof(_EGLConfig *));
   if (!configList)
      return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");

   /* perform selection of configs */
   count = 0;
   for (i = 0; i < disp->NumConfigs; i++) {
      if (_eglMatchConfig(disp->Configs[i], &criteria))
         configList[count++] = disp->Configs[i];
   }

   /* perform sorting of configs */
   if (configs && count) {
      _eglSortConfigs((const _EGLConfig **) configList, count,
                      _eglFallbackCompare, (void *) &criteria);
      count = MIN2(count, config_size);
      for (i = 0; i < count; i++)
         configs[i] = _eglGetConfigHandle(configList[i]);
   }

   free(configList);

   *num_configs = count;

   return EGL_TRUE;
}
Example #7
0
EGLBoolean
drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
{
	struct drm_device *dev;
	struct drm_screen *screen = NULL;
	drmModeConnectorPtr connector = NULL;
	drmModeResPtr res = NULL;
	unsigned count_connectors = 0;
	int num_screens = 0;
	EGLint i;
	int fd;
	_EGLConfig *config;

	dev = (struct drm_device *) calloc(1, sizeof(struct drm_device));
	if (!dev)
		return EGL_FALSE;
	dev->api = drm_api_create();

	/* try the first node */
	fd = drm_open_minor(0);
	if (fd < 0)
		goto err_fd;

	dev->drmFD = fd;
	drm_get_device_id(dev);

	dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL);
	if (!dev->screen)
		goto err_screen;
	dev->winsys = dev->screen->winsys;

	driInitExtensions(NULL, NULL, GL_FALSE);

	drm_update_res(dev);
	res = dev->res;
	if (res)
		count_connectors = res->count_connectors;
	else
		_eglLog(_EGL_WARNING, "Could not retrive kms information\n");

	for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
		connector = drmModeGetConnector(fd, res->connectors[i]);

		if (!connector)
			continue;

		if (connector->connection != DRM_MODE_CONNECTED) {
			drmModeFreeConnector(connector);
			continue;
		}

		screen = malloc(sizeof(struct drm_screen));
		memset(screen, 0, sizeof(*screen));
		screen->connector = connector;
		screen->connectorID = connector->connector_id;
		_eglInitScreen(&screen->base);
		_eglAddScreen(disp, &screen->base);
		drm_add_modes_from_connector(&screen->base, connector);
		drm_find_dpms(dev, screen);
		dev->screens[num_screens++] = screen;
	}
	dev->count_screens = num_screens;

	disp->DriverData = dev;

	/* for now we only have one config */
	config = calloc(1, sizeof(*config));
	memset(config, 1, sizeof(*config));
	_eglInitConfig(config, 1);
	_eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
	_eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
	_eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
	_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
	_eglAddConfig(disp, config);

	disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
	/* enable supported extensions */
	disp->Extensions.MESA_screen_surface = EGL_TRUE;
	disp->Extensions.MESA_copy_context = EGL_TRUE;

	*major = 1;
	*minor = 4;

	return EGL_TRUE;

err_screen:
	drmClose(fd);
err_fd:
	free(dev);
	return EGL_FALSE;
}
Example #8
0
struct dri2_egl_config *
dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
		int depth, EGLint surface_type, const EGLint *attr_list,
		const unsigned int *rgba_masks)
{
   struct dri2_egl_config *conf;
   struct dri2_egl_display *dri2_dpy;
   _EGLConfig base;
   unsigned int attrib, value, double_buffer;
   EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
   unsigned int dri_masks[4] = { 0, 0, 0, 0 };
   _EGLConfig *matching_config;
   EGLint num_configs = 0;
   EGLint config_id;
   int i;

   dri2_dpy = disp->DriverData;
   _eglInitConfig(&base, disp, id);
   
   i = 0;
   double_buffer = 0;
   bind_to_texture_rgb = 0;
   bind_to_texture_rgba = 0;

   while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
      switch (attrib) {
      case __DRI_ATTRIB_RENDER_TYPE:
	 if (value & __DRI_ATTRIB_RGBA_BIT)
	    value = EGL_RGB_BUFFER;
	 else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
	    value = EGL_LUMINANCE_BUFFER;
	 else
	    /* not valid */;
	 _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value);
	 break;	 

      case __DRI_ATTRIB_CONFIG_CAVEAT:
         if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
            value = EGL_NON_CONFORMANT_CONFIG;
         else if (value & __DRI_ATTRIB_SLOW_BIT)
            value = EGL_SLOW_CONFIG;
	 else
	    value = EGL_NONE;
	 _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value);
         break;

      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
	 bind_to_texture_rgb = value;
	 break;

      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
	 bind_to_texture_rgba = value;
	 break;

      case __DRI_ATTRIB_DOUBLE_BUFFER:
	 double_buffer = value;
	 break;

      case __DRI_ATTRIB_RED_MASK:
         dri_masks[0] = value;
         break;

      case __DRI_ATTRIB_GREEN_MASK:
         dri_masks[1] = value;
         break;

      case __DRI_ATTRIB_BLUE_MASK:
         dri_masks[2] = value;
         break;

      case __DRI_ATTRIB_ALPHA_MASK:
         dri_masks[3] = value;
         break;

      default:
	 key = dri2_to_egl_attribute_map[attrib];
	 if (key != 0)
	    _eglSetConfigKey(&base, key, value);
	 break;
      }
   }

   if (attr_list)
      for (i = 0; attr_list[i] != EGL_NONE; i += 2)
         _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]);

   if (depth > 0 && depth != base.BufferSize)
      return NULL;

   if (rgba_masks && memcmp(rgba_masks, dri_masks, sizeof(dri_masks)))
      return NULL;

   base.NativeRenderable = EGL_TRUE;

   base.SurfaceType = surface_type;
   if (surface_type & (EGL_PBUFFER_BIT |
       (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) {
      base.BindToTextureRGB = bind_to_texture_rgb;
      if (base.AlphaSize > 0)
         base.BindToTextureRGBA = bind_to_texture_rgba;
   }

   base.RenderableType = disp->ClientAPIs;
   base.Conformant = disp->ClientAPIs;

   if (!_eglValidateConfig(&base, EGL_FALSE)) {
      _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
      return NULL;
   }

   config_id = base.ConfigID;
   base.ConfigID    = EGL_DONT_CARE;
   base.SurfaceType = EGL_DONT_CARE;
   num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1,
                                 (_EGLArrayForEach) dri2_match_config, &base);

   if (num_configs == 1) {
      conf = (struct dri2_egl_config *) matching_config;

      if (double_buffer && !conf->dri_double_config)
         conf->dri_double_config = dri_config;
      else if (!double_buffer && !conf->dri_single_config)
         conf->dri_single_config = dri_config;
      else
         /* a similar config type is already added (unlikely) => discard */
         return NULL;
   }
   else if (num_configs == 0) {
      conf = malloc(sizeof *conf);
      if (conf == NULL)
         return NULL;

      memcpy(&conf->base, &base, sizeof base);
      if (double_buffer) {
         conf->dri_double_config = dri_config;
         conf->dri_single_config = NULL;
      } else {
         conf->dri_single_config = dri_config;
         conf->dri_double_config = NULL;
      }
      conf->base.SurfaceType = 0;
      conf->base.ConfigID = config_id;

      _eglLinkConfig(&conf->base);
   }
   else {
      assert(0);
      return NULL;
   }

   if (double_buffer) {
      surface_type &= ~EGL_PIXMAP_BIT;

      if (dri2_dpy->swap_available) {
         conf->base.MinSwapInterval = 0;
         conf->base.MaxSwapInterval = 1000; /* XXX arbitrary value */
      }
   }

   conf->base.SurfaceType |= surface_type;

   return conf;
}
Example #9
0
static void
dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
		int depth, xcb_visualtype_t *visual)
{
   struct dri2_egl_config *conf;
   struct dri2_egl_display *dri2_dpy;
   _EGLConfig base;
   unsigned int attrib, value, double_buffer;
   EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
   int i;

   dri2_dpy = disp->DriverData;
   _eglInitConfig(&base, disp, id);
   
   i = 0;
   while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
      switch (attrib) {
      case __DRI_ATTRIB_RENDER_TYPE:
	 if (value & __DRI_ATTRIB_RGBA_BIT)
	    value = EGL_RGB_BUFFER;
	 else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
	    value = EGL_LUMINANCE_BUFFER;
	 else
	    /* not valid */;
	 _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value);
	 break;	 

      case __DRI_ATTRIB_CONFIG_CAVEAT:
         if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
            value = EGL_NON_CONFORMANT_CONFIG;
         else if (value & __DRI_ATTRIB_SLOW_BIT)
            value = EGL_SLOW_CONFIG;
	 else
	    value = EGL_NONE;
	 _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value);
         break;

      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
	 bind_to_texture_rgb = value;
	 break;

      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
	 bind_to_texture_rgba = value;
	 break;

      case __DRI_ATTRIB_DOUBLE_BUFFER:
	 double_buffer = value;
	 break;

      default:
	 key = dri2_to_egl_attribute_map[attrib];
	 if (key != 0)
	    _eglSetConfigKey(&base, key, value);
	 break;
      }
   }

   /* In EGL, double buffer or not isn't a config attribute.  Pixmaps
    * surfaces are always single buffered, pbuffer surfaces are always
    * back buffers and windows can be either, selected by passing an
    * attribute at window surface construction time.  To support this
    * we ignore all double buffer configs and manipulate the buffer we
    * return in the getBuffer callback to get the behaviour we want. */

   if (double_buffer)
      return;

   if (visual != NULL) {
      if (depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE))
	 return;

      _eglSetConfigKey(&base, EGL_SURFACE_TYPE,
		       EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT |
		       EGL_SWAP_BEHAVIOR_PRESERVED_BIT);

      _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_ID, visual->visual_id);
      _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_TYPE, visual->_class);
   } else {
      _eglSetConfigKey(&base, EGL_SURFACE_TYPE,
		       EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
   }

   _eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE);
   _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb);
   if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0)
      _eglSetConfigKey(&base,
		       EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba);

   /* EGL_OPENGL_ES_BIT, EGL_OPENVG_BIT, EGL_OPENGL_ES2_BIT */
   _eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT);
   _eglSetConfigKey(&base, EGL_CONFORMANT, EGL_OPENGL_BIT);

   if (!_eglValidateConfig(&base, EGL_FALSE)) {
      _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
      return;
   }

   conf = malloc(sizeof *conf);
   if (conf != NULL) {
      memcpy(&conf->base, &base, sizeof base);
      conf->dri_config = dri_config;
      _eglAddConfig(disp, &conf->base);
   }
}