[RFC PATCH 3/3] glx: Support a colon-separated list of DRI search paths.

Christopher James Halse Rogers christopher.halse.rogers at canonical.com
Sun Mar 6 19:11:47 PST 2011


Mesa's libGL searches a list of paths to find the DRI drivers to load.
It's reasonable for GLX to search in the same paths.

Signed-off-by: Christopher James Halse Rogers <christopher.halse.rogers at canonical.com>
---
This obviously requires a mesa change to actually export mesa's list of search
paths.  I'll send that to mesa-dev after discussion here.

This is a bit over-engineered in that it also handles the case where a
matching DRI2 driver is found but createNewScreen fails, and a DRI driver
later in the search path would suceed.

This can be useful for situations like r300 where the default mesa driver
requires KMS but the classic driver supports UMS.

 configure.ac       |    8 ++++-
 glx/glxdri.c       |    3 +-
 glx/glxdri2.c      |   35 ++++++++++++-----------
 glx/glxdricommon.c |   78 ++++++++++++++++++++++++++++-----------------------
 glx/glxdricommon.h |    2 +-
 glx/glxdriswrast.c |    3 +-
 6 files changed, 73 insertions(+), 56 deletions(-)

diff --git a/configure.ac b/configure.ac
index 681f9d9..58e1ba0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1243,7 +1243,13 @@ AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path]
 AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path])
 AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path])
 dridriverdir=`$PKG_CONFIG --variable=dridriverdir dri`
-AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default DRI driver path])
+drisearchdirs=`$PKG_CONFIG --variable=drisearchdirs dri`
+if test -n "$drisearchdirs" ; then
+	AC_DEFINE_DIR(DRI_DRIVER_PATH, drisearchdirs,
+		      [Default DRI search paths])
+else
+	AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default DRI driver path])
+fi
 AC_DEFINE_UNQUOTED(XVENDORNAME, ["$VENDOR_NAME"], [Vendor name])
 AC_DEFINE_UNQUOTED(XVENDORNAMESHORT, ["$VENDOR_NAME_SHORT"], [Short vendor name])
 AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release])
diff --git a/glx/glxdri.c b/glx/glxdri.c
index 3a57337..4414fa2 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -973,6 +973,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     const __DRIconfig **driConfigs;
+    void *cookie = NULL;
 
     if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
 	!DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
@@ -1047,7 +1048,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 	goto handle_error;
     }
 
-    screen->driver = glxProbeDriver(driverName,
+    screen->driver = glxProbeDriver(driverName, &cookie,
 				    (void **)&screen->core,
 				    __DRI_CORE, __DRI_CORE_VERSION,
 				    (void **)&screen->legacy,
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 18927d7..9024ff1 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -699,6 +699,7 @@ static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName, *deviceName;
+    void *cookie = NULL;
     __GLXDRIscreen *screen;
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -724,24 +725,24 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 
     __glXInitExtensionEnableBits(screen->glx_enable_bits);
 
-    screen->driver = glxProbeDriver(driverName, (void **)&screen->core, __DRI_CORE, 1,
-				    (void **)&screen->dri2, __DRI_DRI2, 1);
-    if (screen->driver == NULL) {
-        goto handle_error;
-    }
+    do {
+	screen->driver = glxProbeDriver(driverName, &cookie,
+					(void **)&screen->core, __DRI_CORE, 1,
+					(void **)&screen->dri2, __DRI_DRI2, 1);
+	if (screen->driver == NULL) {
+	    goto handle_error;
+	}
     
-    screen->driScreen =
-	(*screen->dri2->createNewScreen)(pScreen->myNum,
-					 screen->fd,
-					 loader_extensions,
-					 &driConfigs,
-					 screen);
-
-    if (screen->driScreen == NULL) {
-	LogMessage(X_ERROR,
-		   "AIGLX error: Calling driver entry point failed\n");
-	goto handle_error;
-    }
+	screen->driScreen =
+	    (*screen->dri2->createNewScreen)(pScreen->myNum,
+					     screen->fd,
+					     loader_extensions,
+					     &driConfigs,
+					     screen);
+	if (screen->driScreen == NULL)
+	    LogMessage(X_INFO,
+		       "AIGLX: Calling driver entry point failed\n");
+    } while (screen->driScreen == NULL);
 
     initializeExtensions(screen);
 
diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c
index f9f7f5b..c2ebe6e 100644
--- a/glx/glxdricommon.c
+++ b/glx/glxdricommon.c
@@ -220,7 +220,7 @@ glxConvertConfigs(const __DRIcoreExtension *core,
 static const char dri_driver_path[] = DRI_DRIVER_PATH;
 
 void *
-glxProbeDriver(const char *driverName,
+glxProbeDriver(const char *driverName, void **cookie,
 	       void **coreExt, const char *coreName, int coreVersion,
 	       void **renderExt, const char *renderName, int renderVersion)
 {
@@ -228,47 +228,55 @@ glxProbeDriver(const char *driverName,
     void *driver;
     char filename[PATH_MAX];
     const __DRIextension **extensions;
+    char *driDriverPath;
+    const char *pathStart = *cookie ? (const char*)*cookie : dri_driver_path;
+    const char *pathEnd = strchr(pathStart, ':');
 
-    snprintf(filename, sizeof filename, "%s/%s_dri.so",
-             dri_driver_path, driverName);
+    for (; *pathStart; pathEnd = strchr(pathStart, ':')) {
+	driDriverPath = strndup(pathStart,
+				pathEnd ? pathEnd - pathStart : sizeof filename);
+	snprintf(filename, sizeof filename, "%s/%s_dri.so",
+		 driDriverPath, driverName);
+	free(driDriverPath);
+	pathStart = pathEnd ? pathEnd + 1 : pathStart + strlen(pathStart);
+	*cookie = (void *)pathStart;
 
-    driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
-    if (driver == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
-		   filename, dlerror());
-	goto cleanup_failure;
-    }
+	driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+	if (driver == NULL) {
+	    LogMessage(X_INFO, "AIGLX: dlopen of %s failed (%s)\n",
+		       filename, dlerror());
+	    continue;
+	}
 
-    extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
-    if (extensions == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
-		   driverName, dlerror());
-	goto cleanup_failure;
-    }
-    
-    for (i = 0; extensions[i]; i++) {
-	if (strcmp(extensions[i]->name, coreName) == 0 &&
-	    extensions[i]->version >= coreVersion) {
-		*coreExt = extensions[i];
+	extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
+	if (extensions == NULL) {
+	    LogMessage(X_INFO, "AIGLX: %s exports no extensions (%s)\n",
+		       driverName, dlerror());
+	    dlclose(driver);
+	    continue;
 	}
+    
+	for (i = 0; extensions[i]; i++) {
+	    if (strcmp(extensions[i]->name, coreName) == 0 &&
+		extensions[i]->version >= coreVersion) {
+		    *coreExt = (void *)extensions[i];
+	    }
 
-	if (strcmp(extensions[i]->name, renderName) == 0 &&
-	    extensions[i]->version >= renderVersion) {
-		*renderExt = extensions[i];
+	    if (strcmp(extensions[i]->name, renderName) == 0 &&
+		extensions[i]->version >= renderVersion) {
+		    *renderExt = (void *)extensions[i];
+	    }
 	}
-    }
 
-    if (*coreExt == NULL || *renderExt == NULL) {
-	LogMessage(X_ERROR,
-		   "AIGLX error: %s does not export required DRI extension\n",
-		   driverName);
-	goto cleanup_failure;
+	if (*coreExt == NULL || *renderExt == NULL) {
+	    LogMessage(X_INFO,
+		       "AIGLX: %s does not export required DRI extension\n",
+		       driverName);
+	    *coreExt = *renderExt = NULL;
+	    dlclose(driver);
+	    continue;
+	}
+	return driver;
     }
-    return driver;
-
-cleanup_failure:
-    if (driver)
-	dlclose(driver);
-    *coreExt = *renderExt = NULL;
     return NULL;
 }
diff --git a/glx/glxdricommon.h b/glx/glxdricommon.h
index 2c55e60..731ddb3 100644
--- a/glx/glxdricommon.h
+++ b/glx/glxdricommon.h
@@ -39,7 +39,7 @@ glxConvertConfigs(const __DRIcoreExtension *core,
 extern const __DRIsystemTimeExtension systemTimeExtension;
 
 void *
-glxProbeDriver(const char *name,
+glxProbeDriver(const char *name, void **cookie,
 	       void **coreExt, const char *coreName, int coreVersion,
 	       void **renderExt, const char *renderName, int renderVersion);
 
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 9de3ba1..4854805 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -431,6 +431,7 @@ static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName = "swrast";
+    void *cookie = NULL;
     __GLXDRIscreen *screen;
     const __DRIconfig **driConfigs;
 
@@ -444,7 +445,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->base.swapInterval   = NULL;
     screen->base.pScreen       = pScreen;
 
-    screen->driver = glxProbeDriver(driverName,
+    screen->driver = glxProbeDriver(driverName, &cookie,
 				    (void **)&screen->core,
 				    __DRI_CORE, __DRI_CORE_VERSION,
 				    (void **)&screen->swrast,
-- 
1.7.4.1



More information about the xorg-devel mailing list