aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c79
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 92378892e5b..b43e91130c0 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);