diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 79 | 
1 files changed, 52 insertions, 27 deletions
| diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 92378892e5..b43e91130c 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -375,6 +375,56 @@ static const char dri_driver_format[] = "%.*s/%.*s_dri.so";  static const char dri_driver_path[] = DEFAULT_DRIVER_DIR; +struct dri2_extension_match { +   const char *name; +   int version; +   int offset; +}; + +static struct dri2_extension_match dri2_driver_extensions[] = { +   { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, +   { __DRI_DRI2, 1, offsetof(struct dri2_egl_display, dri2) }, +   { NULL } +}; + +static struct dri2_extension_match dri2_core_extensions[] = { +   { __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) }, +   { NULL } +}; + +static EGLBoolean +dri2_bind_extensions(struct dri2_egl_display *dri2_dpy, +		     struct dri2_extension_match *matches, +		     const __DRIextension **extensions) +{ +   int i, j, ret = EGL_TRUE; +   void *field; + +   for (i = 0; extensions[i]; i++) { +      _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name); +      for (j = 0; matches[j].name; j++) { +	 if (strcmp(extensions[i]->name, matches[j].name) == 0 && +	     extensions[i]->version >= matches[j].version) { +	    field = ((char *) dri2_dpy + matches[j].offset); +	    *(const __DRIextension **) field = extensions[i]; +	    _eglLog(_EGL_INFO, "DRI2: found extension %s version %d", +		    extensions[i]->name, extensions[i]->version); +	 } +      } +   } +    +   for (j = 0; matches[j].name; j++) { +      field = ((char *) dri2_dpy + matches[j].offset); +      if (*(const __DRIextension **) field == NULL) { +	 _eglLog(_EGL_FATAL, "DRI2: did not find extension %s version %d", +		 matches[j].name, matches[j].version); +	 ret = EGL_FALSE; +      } +   } + +   return ret; +} +  /**   * Called via eglInitialize(), GLX_drv->API.Initialize().   */ @@ -497,24 +547,8 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,        goto cleanup_driver;     } -   for (i = 0; extensions[i]; i++) { -      _eglLog(_EGL_DEBUG, "DRI2: found driver extension `%s'", -	      extensions[i]->name); -      if (strcmp(extensions[i]->name, __DRI_CORE) == 0) -	 dri2_dpy->core = (__DRIcoreExtension *) extensions[i]; -      if (strcmp(extensions[i]->name, __DRI_DRI2) == 0) -	 dri2_dpy->dri2 = (__DRIdri2Extension *) extensions[i]; -   } - -   if (dri2_dpy->core == NULL) { -      _eglLog(_EGL_FATAL, "DRI2: driver has no core extension"); -      goto cleanup_driver; -   } - -   if (dri2_dpy->dri2 == NULL) { -      _eglLog(_EGL_FATAL, "DRI2: driver has no dri2 extension"); +   if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions))        goto cleanup_driver; -   }     snprintf(path, sizeof path, "%.*s",  	    xcb_dri2_connect_device_name_length (connect), @@ -570,17 +604,8 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,     }     extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); -   for (i = 0; extensions[i]; i++) { -      _eglLog(_EGL_DEBUG, "DRI2: found core extension `%s'", -	      extensions[i]->name); -      if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) -	 dri2_dpy->flush = (__DRI2flushExtension *) extensions[i]; -   } - -   if (dri2_dpy->flush == NULL) { -      _eglLog(_EGL_FATAL, "DRI2: driver doesn't support the flush extension"); +   if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))        goto cleanup_dri_screen; -   }     for (i = 0; driver_configs[i]; i++)        dri2_add_config(disp, driver_configs[i], i + 1); | 
