loader: Factor out the common driver opening logic from each loader.
I copied the code from egl_dri2.c, but the functionality was equivalent between all the loaders other than their particular environment variables. v2: Drop the logging function equivalent to loader_default_logger() (requested by Eric, Emil). Move the SCons workaround across. Drop the now-unused driGetDriverExtensions() declaration that was lost in a rebase. Reviewed-by: Eric Engestrom <eric.engestrom@intel.com> (v1) Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v1)
This commit is contained in:
@@ -119,8 +119,7 @@ AM_CFLAGS += \
|
|||||||
-I$(top_srcdir)/src/egl/drivers/dri2 \
|
-I$(top_srcdir)/src/egl/drivers/dri2 \
|
||||||
-I$(top_srcdir)/src/gbm/backends/dri \
|
-I$(top_srcdir)/src/gbm/backends/dri \
|
||||||
-I$(top_builddir)/src/egl/wayland/wayland-drm \
|
-I$(top_builddir)/src/egl/wayland/wayland-drm \
|
||||||
-I$(top_srcdir)/src/egl/wayland/wayland-drm \
|
-I$(top_srcdir)/src/egl/wayland/wayland-drm
|
||||||
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\"
|
|
||||||
|
|
||||||
nodist_libEGL_common_la_SOURCES = \
|
nodist_libEGL_common_la_SOURCES = \
|
||||||
$(dri2_backend_GENERATED_FILES)
|
$(dri2_backend_GENERATED_FILES)
|
||||||
|
@@ -483,75 +483,14 @@ static const __DRIextension **
|
|||||||
dri2_open_driver(_EGLDisplay *disp)
|
dri2_open_driver(_EGLDisplay *disp)
|
||||||
{
|
{
|
||||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
const __DRIextension **extensions = NULL;
|
static const char *search_path_vars[] = {
|
||||||
char path[PATH_MAX], *search_paths, *next, *end;
|
"LIBGL_DRIVERS_PATH",
|
||||||
char *get_extensions_name;
|
NULL,
|
||||||
const __DRIextension **(*get_extensions)(void);
|
};
|
||||||
|
|
||||||
search_paths = NULL;
|
return loader_open_driver(dri2_dpy->driver_name,
|
||||||
if (geteuid() == getuid()) {
|
&dri2_dpy->driver,
|
||||||
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
|
search_path_vars);
|
||||||
search_paths = getenv("LIBGL_DRIVERS_PATH");
|
|
||||||
}
|
|
||||||
if (search_paths == NULL)
|
|
||||||
search_paths = DEFAULT_DRIVER_DIR;
|
|
||||||
|
|
||||||
dri2_dpy->driver = NULL;
|
|
||||||
end = search_paths + strlen(search_paths);
|
|
||||||
for (char *p = search_paths; p < end; p = next + 1) {
|
|
||||||
int len;
|
|
||||||
next = strchr(p, ':');
|
|
||||||
if (next == NULL)
|
|
||||||
next = end;
|
|
||||||
|
|
||||||
len = next - p;
|
|
||||||
#if GLX_USE_TLS
|
|
||||||
snprintf(path, sizeof path,
|
|
||||||
"%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name);
|
|
||||||
dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
|
||||||
#endif
|
|
||||||
if (dri2_dpy->driver == NULL) {
|
|
||||||
snprintf(path, sizeof path,
|
|
||||||
"%.*s/%s_dri.so", len, p, dri2_dpy->driver_name);
|
|
||||||
dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
|
||||||
if (dri2_dpy->driver == NULL)
|
|
||||||
_eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror());
|
|
||||||
}
|
|
||||||
/* not need continue to loop all paths once the driver is found */
|
|
||||||
if (dri2_dpy->driver != NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dri2_dpy->driver == NULL) {
|
|
||||||
_eglLog(_EGL_WARNING,
|
|
||||||
"DRI2: failed to open %s (search paths %s)",
|
|
||||||
dri2_dpy->driver_name, search_paths);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path);
|
|
||||||
|
|
||||||
get_extensions_name = loader_get_extensions_name(dri2_dpy->driver_name);
|
|
||||||
if (get_extensions_name) {
|
|
||||||
get_extensions = dlsym(dri2_dpy->driver, get_extensions_name);
|
|
||||||
if (get_extensions) {
|
|
||||||
extensions = get_extensions();
|
|
||||||
} else {
|
|
||||||
_eglLog(_EGL_DEBUG, "driver does not expose %s(): %s\n",
|
|
||||||
get_extensions_name, dlerror());
|
|
||||||
}
|
|
||||||
free(get_extensions_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!extensions)
|
|
||||||
extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS);
|
|
||||||
if (extensions == NULL) {
|
|
||||||
_eglLog(_EGL_WARNING,
|
|
||||||
"DRI2: driver exports no extensions (%s)", dlerror());
|
|
||||||
dlclose(dri2_dpy->driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
return extensions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLBoolean
|
EGLBoolean
|
||||||
|
@@ -93,9 +93,6 @@ if with_dri2
|
|||||||
'drivers/dri2/egl_dri2.h',
|
'drivers/dri2/egl_dri2.h',
|
||||||
'drivers/dri2/egl_dri2_fallbacks.h',
|
'drivers/dri2/egl_dri2_fallbacks.h',
|
||||||
)
|
)
|
||||||
c_args_for_egl += [
|
|
||||||
'-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path),
|
|
||||||
]
|
|
||||||
|
|
||||||
if with_platform_x11
|
if with_platform_x11
|
||||||
files_egl += files('drivers/dri2/platform_x11.c')
|
files_egl += files('drivers/dri2/platform_x11.c')
|
||||||
|
@@ -42,7 +42,6 @@ libgbm_la_SOURCES += \
|
|||||||
$(gbm_dri_FILES)
|
$(gbm_dri_FILES)
|
||||||
|
|
||||||
AM_CFLAGS += \
|
AM_CFLAGS += \
|
||||||
-DDEFAULT_DRIVER_DIR='"$(DRI_DRIVER_SEARCH_DIR)"' \
|
|
||||||
$(LIBDRM_CFLAGS) \
|
$(LIBDRM_CFLAGS) \
|
||||||
$(PTHREADSTUBS_CFLAGS)
|
$(PTHREADSTUBS_CFLAGS)
|
||||||
|
|
||||||
|
@@ -304,28 +304,6 @@ dri_bind_extensions(struct gbm_dri_device *dri,
|
|||||||
static const __DRIextension **
|
static const __DRIextension **
|
||||||
dri_open_driver(struct gbm_dri_device *dri)
|
dri_open_driver(struct gbm_dri_device *dri)
|
||||||
{
|
{
|
||||||
const __DRIextension **extensions = NULL;
|
|
||||||
char path[PATH_MAX], *search_paths, *p, *next, *end;
|
|
||||||
char *get_extensions_name;
|
|
||||||
|
|
||||||
search_paths = NULL;
|
|
||||||
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH or GBM_DRIVERS_PATH */
|
|
||||||
if (geteuid() == getuid()) {
|
|
||||||
/* Read GBM_DRIVERS_PATH first for compatibility, but LIBGL_DRIVERS_PATH
|
|
||||||
* is recommended over GBM_DRIVERS_PATH.
|
|
||||||
*/
|
|
||||||
search_paths = getenv("GBM_DRIVERS_PATH");
|
|
||||||
|
|
||||||
/* Read LIBGL_DRIVERS_PATH if GBM_DRIVERS_PATH was not set.
|
|
||||||
* LIBGL_DRIVERS_PATH is recommended over GBM_DRIVERS_PATH.
|
|
||||||
*/
|
|
||||||
if (search_paths == NULL) {
|
|
||||||
search_paths = getenv("LIBGL_DRIVERS_PATH");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (search_paths == NULL)
|
|
||||||
search_paths = DEFAULT_DRIVER_DIR;
|
|
||||||
|
|
||||||
/* Temporarily work around dri driver libs that need symbols in libglapi
|
/* Temporarily work around dri driver libs that need symbols in libglapi
|
||||||
* but don't automatically link it in.
|
* but don't automatically link it in.
|
||||||
*/
|
*/
|
||||||
@@ -334,56 +312,18 @@ dri_open_driver(struct gbm_dri_device *dri)
|
|||||||
*/
|
*/
|
||||||
dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
|
dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
|
||||||
dri->driver = NULL;
|
static const char *search_path_vars[] = {
|
||||||
end = search_paths + strlen(search_paths);
|
/* Read GBM_DRIVERS_PATH first for compatibility, but LIBGL_DRIVERS_PATH
|
||||||
for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) {
|
* is recommended over GBM_DRIVERS_PATH.
|
||||||
int len;
|
*/
|
||||||
next = strchr(p, ':');
|
"GBM_DRIVERS_PATH"
|
||||||
if (next == NULL)
|
/* Read LIBGL_DRIVERS_PATH if GBM_DRIVERS_PATH was not set.
|
||||||
next = end;
|
* LIBGL_DRIVERS_PATH is recommended over GBM_DRIVERS_PATH.
|
||||||
|
*/
|
||||||
len = next - p;
|
"LIBGL_DRIVERS_PATH",
|
||||||
#if GLX_USE_TLS
|
NULL
|
||||||
snprintf(path, sizeof path,
|
};
|
||||||
"%.*s/tls/%s_dri.so", len, p, dri->driver_name);
|
return loader_open_driver(dri->driver_name, &dri->driver, search_path_vars);
|
||||||
dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
|
||||||
#endif
|
|
||||||
if (dri->driver == NULL) {
|
|
||||||
snprintf(path, sizeof path,
|
|
||||||
"%.*s/%s_dri.so", len, p, dri->driver_name);
|
|
||||||
dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
|
||||||
}
|
|
||||||
/* not need continue to loop all paths once the driver is found */
|
|
||||||
if (dri->driver != NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dri->driver == NULL) {
|
|
||||||
fprintf(stderr, "gbm: failed to open any driver (search paths %s)\n",
|
|
||||||
search_paths);
|
|
||||||
fprintf(stderr, "gbm: Last dlopen error: %s\n", dlerror());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_extensions_name = loader_get_extensions_name(dri->driver_name);
|
|
||||||
if (get_extensions_name) {
|
|
||||||
const __DRIextension **(*get_extensions)(void);
|
|
||||||
|
|
||||||
get_extensions = dlsym(dri->driver, get_extensions_name);
|
|
||||||
free(get_extensions_name);
|
|
||||||
|
|
||||||
if (get_extensions)
|
|
||||||
extensions = get_extensions();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!extensions)
|
|
||||||
extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS);
|
|
||||||
if (extensions == NULL) {
|
|
||||||
fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror());
|
|
||||||
dlclose(dri->driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
return extensions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@@ -37,7 +37,6 @@ incs_gbm = [
|
|||||||
if with_dri2
|
if with_dri2
|
||||||
files_gbm += files('backends/dri/gbm_dri.c', 'backends/dri/gbm_driint.h')
|
files_gbm += files('backends/dri/gbm_dri.c', 'backends/dri/gbm_driint.h')
|
||||||
deps_gbm += dep_libdrm # TODO: pthread-stubs
|
deps_gbm += dep_libdrm # TODO: pthread-stubs
|
||||||
args_gbm += '-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path)
|
|
||||||
endif
|
endif
|
||||||
if with_platform_wayland
|
if with_platform_wayland
|
||||||
deps_gbm += dep_wayland_server
|
deps_gbm += dep_wayland_server
|
||||||
|
@@ -40,7 +40,6 @@ AM_CFLAGS = \
|
|||||||
$(VISIBILITY_CFLAGS) \
|
$(VISIBILITY_CFLAGS) \
|
||||||
$(EXTRA_DEFINES_XF86VIDMODE) \
|
$(EXTRA_DEFINES_XF86VIDMODE) \
|
||||||
-D_REENTRANT \
|
-D_REENTRANT \
|
||||||
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
|
|
||||||
$(DEFINES) \
|
$(DEFINES) \
|
||||||
$(LIBDRM_CFLAGS) \
|
$(LIBDRM_CFLAGS) \
|
||||||
$(DRI2PROTO_CFLAGS) \
|
$(DRI2PROTO_CFLAGS) \
|
||||||
|
@@ -26,8 +26,6 @@ env.Append(CPPDEFINES = [
|
|||||||
'_REENTRANT',
|
'_REENTRANT',
|
||||||
])
|
])
|
||||||
|
|
||||||
env.Append(CPPDEFINES = ['DEFAULT_DRIVER_DIR=\\"/usr/local/lib/dri\\"'])
|
|
||||||
|
|
||||||
env.Prepend(LIBS = [
|
env.Prepend(LIBS = [
|
||||||
libloader,
|
libloader,
|
||||||
mesautil,
|
mesautil,
|
||||||
|
@@ -77,9 +77,6 @@ dri_message(int level, const char *f, ...)
|
|||||||
#define GL_LIB_NAME "libGL.so.1"
|
#define GL_LIB_NAME "libGL.so.1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const __DRIextension **
|
|
||||||
driGetDriverExtensions(void *handle, const char *driver_name);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to \c dlopen the named driver.
|
* Try to \c dlopen the named driver.
|
||||||
*
|
*
|
||||||
@@ -97,98 +94,23 @@ driGetDriverExtensions(void *handle, const char *driver_name);
|
|||||||
_X_HIDDEN const __DRIextension **
|
_X_HIDDEN const __DRIextension **
|
||||||
driOpenDriver(const char *driverName, void **out_driver_handle)
|
driOpenDriver(const char *driverName, void **out_driver_handle)
|
||||||
{
|
{
|
||||||
void *glhandle, *handle;
|
void *glhandle;
|
||||||
const char *libPaths, *p, *next;
|
|
||||||
char realDriverName[200];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
/* Attempt to make sure libGL symbols will be visible to the driver */
|
/* Attempt to make sure libGL symbols will be visible to the driver */
|
||||||
glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL);
|
glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL);
|
||||||
|
|
||||||
libPaths = NULL;
|
static const char *search_path_vars[] = {
|
||||||
if (geteuid() == getuid()) {
|
"LIBGL_DRIVERS_PATH",
|
||||||
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
|
"LIBGL_DRIVERS_DIR", /* deprecated */
|
||||||
libPaths = getenv("LIBGL_DRIVERS_PATH");
|
NULL
|
||||||
if (!libPaths)
|
};
|
||||||
libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
|
|
||||||
}
|
|
||||||
if (libPaths == NULL)
|
|
||||||
libPaths = DEFAULT_DRIVER_DIR;
|
|
||||||
|
|
||||||
handle = NULL;
|
const __DRIextension **extensions =
|
||||||
for (p = libPaths; *p; p = next) {
|
loader_open_driver(driverName, out_driver_handle, search_path_vars);
|
||||||
next = strchr(p, ':');
|
|
||||||
if (next == NULL) {
|
|
||||||
len = strlen(p);
|
|
||||||
next = p + len;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
len = next - p;
|
|
||||||
next++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GLX_USE_TLS
|
|
||||||
snprintf(realDriverName, sizeof realDriverName,
|
|
||||||
"%.*s/tls/%s_dri.so", len, p, driverName);
|
|
||||||
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
|
|
||||||
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (handle == NULL) {
|
|
||||||
snprintf(realDriverName, sizeof realDriverName,
|
|
||||||
"%.*s/%s_dri.so", len, p, driverName);
|
|
||||||
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
|
|
||||||
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle != NULL)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
InfoMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handle)
|
|
||||||
ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
|
|
||||||
|
|
||||||
if (glhandle)
|
if (glhandle)
|
||||||
dlclose(glhandle);
|
dlclose(glhandle);
|
||||||
|
|
||||||
const __DRIextension **extensions = driGetDriverExtensions(handle,
|
|
||||||
driverName);
|
|
||||||
if (!extensions) {
|
|
||||||
dlclose(handle);
|
|
||||||
handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_driver_handle = handle;
|
|
||||||
return extensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const __DRIextension **
|
|
||||||
driGetDriverExtensions(void *handle, const char *driver_name)
|
|
||||||
{
|
|
||||||
const __DRIextension **extensions = NULL;
|
|
||||||
const __DRIextension **(*get_extensions)(void);
|
|
||||||
char *get_extensions_name = loader_get_extensions_name(driver_name);
|
|
||||||
|
|
||||||
if (get_extensions_name) {
|
|
||||||
get_extensions = dlsym(handle, get_extensions_name);
|
|
||||||
if (get_extensions) {
|
|
||||||
free(get_extensions_name);
|
|
||||||
return get_extensions();
|
|
||||||
} else {
|
|
||||||
InfoMessageF("driver does not expose %s(): %s\n",
|
|
||||||
get_extensions_name, dlerror());
|
|
||||||
free(get_extensions_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extensions = dlsym(handle, __DRI_DRIVER_EXTENSIONS);
|
|
||||||
if (extensions == NULL) {
|
|
||||||
ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return extensions;
|
return extensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -134,7 +134,6 @@ endif
|
|||||||
|
|
||||||
gl_lib_cargs = [
|
gl_lib_cargs = [
|
||||||
'-D_REENTRANT',
|
'-D_REENTRANT',
|
||||||
'-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if dep_xxf86vm.found()
|
if dep_xxf86vm.found()
|
||||||
|
@@ -28,6 +28,7 @@ noinst_LTLIBRARIES = libloader.la
|
|||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(top_builddir)/src/util/ \
|
-I$(top_builddir)/src/util/ \
|
||||||
-DUSE_DRICONF \
|
-DUSE_DRICONF \
|
||||||
|
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
|
||||||
$(DEFINES) \
|
$(DEFINES) \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
-I$(top_srcdir)/include/drm-uapi \
|
-I$(top_srcdir)/include/drm-uapi \
|
||||||
|
@@ -12,6 +12,8 @@ if env['drm']:
|
|||||||
env.PkgUseModules('DRM')
|
env.PkgUseModules('DRM')
|
||||||
env.Append(CPPDEFINES = ['HAVE_LIBDRM'])
|
env.Append(CPPDEFINES = ['HAVE_LIBDRM'])
|
||||||
|
|
||||||
|
env.Append(CPPDEFINES = ['DEFAULT_DRIVER_DIR=\\"/usr/local/lib/dri\\"'])
|
||||||
|
|
||||||
# parse Makefile.sources
|
# parse Makefile.sources
|
||||||
sources = env.ParseSourceList('Makefile.sources', 'LOADER_C_FILES')
|
sources = env.ParseSourceList('Makefile.sources', 'LOADER_C_FILES')
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
* Rob Clark <robclark@freedesktop.org>
|
* Rob Clark <robclark@freedesktop.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#ifdef MAJOR_IN_MKDEV
|
#ifdef MAJOR_IN_MKDEV
|
||||||
#include <sys/mkdev.h>
|
#include <sys/mkdev.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -510,3 +512,91 @@ loader_get_extensions_name(const char *driver_name)
|
|||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a DRI driver using its driver name, returning the __DRIextension
|
||||||
|
* entrypoints.
|
||||||
|
*
|
||||||
|
* \param driverName - a name like "i965", "radeon", "nouveau", etc.
|
||||||
|
* \param out_driver - Address where the dlopen() return value will be stored.
|
||||||
|
* \param search_path_vars - NULL-terminated list of env vars that can be used
|
||||||
|
* to override the DEFAULT_DRIVER_DIR search path.
|
||||||
|
*/
|
||||||
|
const struct __DRIextensionRec **
|
||||||
|
loader_open_driver(const char *driver_name,
|
||||||
|
void **out_driver_handle,
|
||||||
|
const char **search_path_vars)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX], *search_paths, *next, *end;
|
||||||
|
char *get_extensions_name;
|
||||||
|
const struct __DRIextensionRec **extensions = NULL;
|
||||||
|
const struct __DRIextensionRec **(*get_extensions)(void);
|
||||||
|
|
||||||
|
search_paths = NULL;
|
||||||
|
if (geteuid() == getuid() && search_path_vars) {
|
||||||
|
for (int i = 0; search_path_vars[i] != NULL; i++) {
|
||||||
|
search_paths = getenv(search_path_vars[i]);
|
||||||
|
if (search_paths)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (search_paths == NULL)
|
||||||
|
search_paths = DEFAULT_DRIVER_DIR;
|
||||||
|
|
||||||
|
void *driver = NULL;
|
||||||
|
end = search_paths + strlen(search_paths);
|
||||||
|
for (char *p = search_paths; p < end; p = next + 1) {
|
||||||
|
int len;
|
||||||
|
next = strchr(p, ':');
|
||||||
|
if (next == NULL)
|
||||||
|
next = end;
|
||||||
|
|
||||||
|
len = next - p;
|
||||||
|
#if GLX_USE_TLS
|
||||||
|
snprintf(path, sizeof(path), "%.*s/tls/%s_dri.so", len, p, driver_name);
|
||||||
|
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
||||||
|
#endif
|
||||||
|
if (driver == NULL) {
|
||||||
|
snprintf(path, sizeof(path), "%.*s/%s_dri.so", len, p, driver_name);
|
||||||
|
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
||||||
|
if (driver == NULL)
|
||||||
|
log_(_LOADER_DEBUG, "MESA-LOADER: failed to open %s: %s\n",
|
||||||
|
path, dlerror());
|
||||||
|
}
|
||||||
|
/* not need continue to loop all paths once the driver is found */
|
||||||
|
if (driver != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driver == NULL) {
|
||||||
|
log_(_LOADER_WARNING, "MESA-LOADER: failed to open %s (search paths %s)\n",
|
||||||
|
driver_name, search_paths);
|
||||||
|
*out_driver_handle = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path);
|
||||||
|
|
||||||
|
get_extensions_name = loader_get_extensions_name(driver_name);
|
||||||
|
if (get_extensions_name) {
|
||||||
|
get_extensions = dlsym(driver, get_extensions_name);
|
||||||
|
if (get_extensions) {
|
||||||
|
extensions = get_extensions();
|
||||||
|
} else {
|
||||||
|
log_(_LOADER_DEBUG, "MESA-LOADER: driver does not expose %s(): %s\n",
|
||||||
|
get_extensions_name, dlerror());
|
||||||
|
}
|
||||||
|
free(get_extensions_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extensions)
|
||||||
|
extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
|
||||||
|
if (extensions == NULL) {
|
||||||
|
log_(_LOADER_WARNING,
|
||||||
|
"MESA-LOADER: driver exports no extensions (%s)\n", dlerror());
|
||||||
|
dlclose(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_driver_handle = driver;
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
@@ -33,6 +33,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct __DRIextensionRec;
|
||||||
|
|
||||||
/* Helpers to figure out driver and device name, eg. from pci-id, etc. */
|
/* Helpers to figure out driver and device name, eg. from pci-id, etc. */
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -47,6 +49,11 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id);
|
|||||||
char *
|
char *
|
||||||
loader_get_driver_for_fd(int fd);
|
loader_get_driver_for_fd(int fd);
|
||||||
|
|
||||||
|
const struct __DRIextensionRec **
|
||||||
|
loader_open_driver(const char *driver_name,
|
||||||
|
void **out_driver_handle,
|
||||||
|
const char **search_path_vars);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
loader_get_device_name_for_fd(int fd);
|
loader_get_device_name_for_fd(int fd);
|
||||||
|
|
||||||
|
@@ -39,7 +39,9 @@ libloader = static_library(
|
|||||||
'loader',
|
'loader',
|
||||||
['loader.c', 'loader.h', 'pci_id_driver_map.c', 'pci_id_driver_map.h',
|
['loader.c', 'loader.h', 'pci_id_driver_map.c', 'pci_id_driver_map.h',
|
||||||
xmlpool_options_h],
|
xmlpool_options_h],
|
||||||
c_args : [c_vis_args, '-DUSE_DRICONF'],
|
c_args : [c_vis_args, '-DUSE_DRICONF',
|
||||||
|
'-DDEFAULT_DRIVER_DIR="@0@"'.format(dri_search_path),
|
||||||
|
],
|
||||||
include_directories : [inc_include, inc_src, inc_util],
|
include_directories : [inc_include, inc_src, inc_util],
|
||||||
dependencies : [dep_libdrm, dep_thread],
|
dependencies : [dep_libdrm, dep_thread],
|
||||||
build_by_default : false,
|
build_by_default : false,
|
||||||
|
Reference in New Issue
Block a user