diff options
Diffstat (limited to 'xorg-server/glx/glxdricommon.c')
-rw-r--r-- | xorg-server/glx/glxdricommon.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/xorg-server/glx/glxdricommon.c b/xorg-server/glx/glxdricommon.c index 5b12520d3..a51d6621a 100644 --- a/xorg-server/glx/glxdricommon.c +++ b/xorg-server/glx/glxdricommon.c @@ -33,6 +33,7 @@ #include <stdint.h>
#include <errno.h>
+#include <dlfcn.h>
#include <sys/time.h>
#include <GL/gl.h>
#include <GL/glxtokens.h>
@@ -43,6 +44,10 @@ #include "glxscreens.h"
#include "glxdricommon.h"
+#ifdef _MSC_VER
+#define dlerror() "Getting loadlibrary error string not implemented"
+#endif
+
static int
getUST(int64_t *ust)
{
@@ -212,3 +217,79 @@ glxConvertConfigs(const __DRIcoreExtension *core, return head.next;
}
+
+static const char dri_driver_path[] = DRI_DRIVER_PATH;
+
+void *
+glxProbeDriver(const char *driverName,
+ void **coreExt, const char *coreName, int coreVersion,
+ void **renderExt, const char *renderName, int renderVersion)
+{
+ int i;
+ void *driver;
+ char filename[PATH_MAX];
+ const __DRIextension **extensions;
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+#define DLLNAME "%s%s_dri_dbg.dll"
+#else
+#define DLLNAME "%s%s_dri.dll"
+#endif
+ snprintf(filename, sizeof filename, DLLNAME,
+ dri_driver_path, driverName);
+
+ driver = LoadLibrary(filename);
+#else
+ snprintf(filename, sizeof filename, "%s/%s_dri.so",
+ dri_driver_path, driverName);
+
+ driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+#endif
+ if (driver == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+ filename, dlerror());
+ goto cleanup_failure;
+ }
+
+#ifdef _MSC_VER
+ extensions = (const __DRIextension **)GetProcAddress(driver, __DRI_DRIVER_EXTENSIONS);
+#else
+ extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
+#endif
+ 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 = (void *)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;
+ }
+ return driver;
+
+cleanup_failure:
+ if (driver)
+#ifdef _MSC_VER
+ FreeLibrary(driver);
+#else
+ dlclose(driver);
+#endif
+ *coreExt = *renderExt = NULL;
+ return NULL;
+}
|