/* XXX Need to decide how to do dynamic name lookup on Windows */
static const char *DefaultDriverNames[] = {
- "egl_gallium_swrast"
+ "egl_gallium"
};
typedef HMODULE lib_handle;
static const char *DefaultDriverNames[] = {
+ "egl_gallium",
"egl_dri2",
"egl_glx"
};
/**
- * A loader function for use with _eglPreloadForEach. The loader data is the
- * pattern (prefix) of the files to look for.
- */
-static EGLBoolean
-_eglLoaderPattern(const char *dir, size_t len, void *loader_data)
-{
-#if defined(_EGL_OS_UNIX)
- const char *prefix, *suffix;
- size_t prefix_len, suffix_len;
- DIR *dirp;
- struct dirent *dirent;
- char path[1024];
-
- if (len + 2 > sizeof(path))
- return EGL_TRUE;
- if (len) {
- memcpy(path, dir, len);
- path[len++] = '/';
- }
- path[len] = '\0';
-
- dirp = opendir(path);
- if (!dirp)
- return EGL_TRUE;
-
- prefix = (const char *) loader_data;
- prefix_len = strlen(prefix);
- suffix = library_suffix();
- suffix_len = (suffix) ? strlen(suffix) : 0;
-
- while ((dirent = readdir(dirp))) {
- _EGLDriver *drv;
- size_t dirent_len = strlen(dirent->d_name);
- const char *p;
-
- /* match the prefix */
- if (strncmp(dirent->d_name, prefix, prefix_len) != 0)
- continue;
- /* match the suffix */
- if (suffix) {
- p = dirent->d_name + dirent_len - suffix_len;
- if (p < dirent->d_name || strcmp(p, suffix) != 0)
- continue;
- }
-
- /* make a full path and load the driver */
- if (len + dirent_len + 1 <= sizeof(path)) {
- strcpy(path + len, dirent->d_name);
- drv = _eglLoadDriver(path, NULL);
- if (drv)
- _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
- }
- }
-
- closedir(dirp);
-
- return EGL_TRUE;
-#else /* _EGL_OS_UNIX */
- /* stop immediately */
- return EGL_FALSE;
-#endif
-}
-
-
-/**
* Run the preload function on each driver directory and return the number of
* drivers loaded.
*
/**
- * Preload Gallium drivers.
- *
- * FIXME This makes libEGL a memory hog if an user driver is not specified and
- * there are many Gallium drivers
- */
-static EGLBoolean
-_eglPreloadGalliumDrivers(void)
-{
- return (_eglPreloadForEach(_eglGetSearchPath(),
- _eglLoaderPattern, (void *) "egl_gallium_") > 0);
-}
-
-
-/**
* Preload drivers.
*
* This function loads the driver modules and creates the corresponding
return EGL_TRUE;
}
- loaded = (_eglPreloadUserDriver() ||
- _eglPreloadGalliumDrivers());
+ loaded = _eglPreloadUserDriver();
_eglUnlockMutex(_eglGlobal.Mutex);
#include "state_tracker/drm_driver.h"
-#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
-
-static void
-x11_probe_destroy(struct native_probe *nprobe)
-{
- if (nprobe->data)
- FREE(nprobe->data);
- FREE(nprobe);
-}
-
-static struct native_probe *
-x11_create_probe(void *dpy)
-{
- struct native_probe *nprobe;
- struct x11_screen *xscr;
- int scr;
- const char *driver_name = NULL;
- Display *xdpy;
-
- nprobe = CALLOC_STRUCT(native_probe);
- if (!nprobe)
- return NULL;
-
- xdpy = dpy;
- if (!xdpy) {
- xdpy = XOpenDisplay(NULL);
- if (!xdpy) {
- FREE(nprobe);
- return NULL;
- }
- }
-
- scr = DefaultScreen(xdpy);
- xscr = x11_screen_create(xdpy, scr);
- if (xscr) {
- if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
- driver_name = x11_screen_probe_dri2(xscr, NULL, NULL);
- if (driver_name)
- nprobe->data = strdup(driver_name);
- }
-
- x11_screen_destroy(xscr);
- }
-
- if (xdpy != dpy)
- XCloseDisplay(xdpy);
-
- nprobe->magic = X11_PROBE_MAGIC;
- nprobe->display = dpy;
-
- nprobe->destroy = x11_probe_destroy;
-
- return nprobe;
-}
-
-static enum native_probe_result
-x11_get_probe_result(struct native_probe *nprobe)
-{
- if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
- return NATIVE_PROBE_UNKNOWN;
-
- /* this is a software driver */
- if (!driver_descriptor.create_screen)
- return NATIVE_PROBE_SUPPORTED;
-
- /* the display does not support DRI2 or the driver mismatches */
- if (!nprobe->data || strcmp(driver_descriptor.name, (const char *) nprobe->data) != 0)
- return NATIVE_PROBE_FALLBACK;
-
- return NATIVE_PROBE_EXACT;
-}
-
static struct native_display *
native_create_display(void *dpy, struct native_event_handler *event_handler,
void *user_data)
static const struct native_platform x11_platform = {
"X11", /* name */
- x11_create_probe,
- x11_get_probe_result,
+ NULL, /* create_probe */
+ NULL, /* get_probe_result */
native_create_display
};
#
# This is the Makefile for EGL Gallium driver package. The package consists of
#
-# egl_gallium_<HW>.so - EGL drivers
-# st_<API>.so - client API state trackers
+# egl_gallium.so - EGL driver
+# pipe_<HW>.so - pipe drivers
+# st_<API>.so - client API state trackers
#
# The following variables are examined
#
include $(TOP)/configs/current
ST_PREFIX := st_
-PIPE_PREFIX := egl_gallium_
+PIPE_PREFIX := pipe_
common_CPPFLAGS := \
-I$(TOP)/src/gallium/auxiliary \
egl_CPPFLAGS := \
-I$(TOP)/src/gallium/state_trackers/egl \
-I$(TOP)/src/egl/main \
- -DST_PREFIX=\"$(ST_PREFIX)\"
+ -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" -DST_PREFIX=\"$(ST_PREFIX)\"
egl_SYS := -lm -ldl -lEGL
-egl_LIBS := \
- $(TOP)/src/gallium/state_trackers/egl/libegl.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+egl_LIBS := $(TOP)/src/gallium/state_trackers/egl/libegl.a
ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
egl_SYS += -lX11 -lXext -lXfixes
endif
egl_CPPFLAGS := $(sort $(egl_CPPFLAGS))
-# LLVM
-ifeq ($(MESA_LLVM),1)
-common_SYS += $(LLVM_LIBS)
-egl_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
-LDFLAGS += $(LLVM_LDFLAGS)
-endif
-
# i915 pipe driver
i915_CPPFLAGS :=
i915_SYS := -ldrm_intel
$(TOP)/src/gallium/drivers/svga/libsvga.a
# swrast (pseudo) pipe driver
-swrast_CPPFLAGS :=
-swrast_SYS :=
-swrast_LIBS :=
+swrast_CPPFLAGS := -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE
+swrast_SYS := -lm
+swrast_LIBS := $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+# LLVM
+ifeq ($(MESA_LLVM),1)
+common_SYS += $(LLVM_LIBS)
+swrast_CPPFLAGS += -DGALLIUM_LLVMPIPE
+swrast_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
+LDFLAGS += $(LLVM_LDFLAGS)
+endif
# OpenGL state tracker
GL_CPPFLAGS := -I$(TOP)/src/mesa $(API_DEFINES)
OUTPUTS += swrast
OUTPUTS := $(addprefix $(PIPE_PREFIX), $(OUTPUTS))
-# state trackers
-OUTPUTS += $(addprefix $(ST_PREFIX), $(EGL_CLIENT_APIS))
+# EGL driver and state trackers
+OUTPUTS += egl_gallium $(addprefix $(ST_PREFIX), $(EGL_CLIENT_APIS))
OUTPUTS := $(addsuffix .so, $(OUTPUTS))
OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS))
default: $(OUTPUTS)
-define mklib-egl
-$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
- -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< egl.o \
- -Wl,--start-group $(common_LIBS) $(egl_LIBS) $($(1)_LIBS) -Wl,--end-group \
- $(common_SYS) $(egl_SYS) $($(1)_SYS)
-endef
-
define mklib
$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \
$(common_SYS) $($(1)_SYS)
endef
-# EGL drivers
-$(OUTPUT_PATH)/$(PIPE_PREFIX)i915.so: pipe_i915.o egl.o $(egl_LIBS) $(i915_LIBS)
- $(call mklib-egl,i915)
+# EGL driver
+$(OUTPUT_PATH)/egl_gallium.so: egl.o $(egl_LIBS)
+ $(call mklib,egl)
+
+# pipe drivers
+$(OUTPUT_PATH)/$(PIPE_PREFIX)i915.so: pipe_i915.o $(i915_LIBS)
+ $(call mklib,i915)
-$(OUTPUT_PATH)/$(PIPE_PREFIX)i965.so: pipe_i965.o egl.o $(egl_LIBS) $(i965_LIBS)
- $(call mklib-egl,i965)
+$(OUTPUT_PATH)/$(PIPE_PREFIX)i965.so: pipe_i965.o $(i965_LIBS)
+ $(call mklib,i965)
-$(OUTPUT_PATH)/$(PIPE_PREFIX)nouveau.so: pipe_nouveau.o egl.o $(egl_LIBS) $(nouveau_LIBS)
- $(call mklib-egl,nouveau)
+$(OUTPUT_PATH)/$(PIPE_PREFIX)nouveau.so: pipe_nouveau.o $(nouveau_LIBS)
+ $(call mklib,nouveau)
-$(OUTPUT_PATH)/$(PIPE_PREFIX)radeon.so: pipe_radeon.o egl.o $(egl_LIBS) $(radeon_LIBS)
- $(call mklib-egl,radeon)
+$(OUTPUT_PATH)/$(PIPE_PREFIX)radeon.so: pipe_radeon.o $(radeon_LIBS)
+ $(call mklib,radeon)
-$(OUTPUT_PATH)/$(PIPE_PREFIX)vmwgfx.so: pipe_vmwgfx.o egl.o $(egl_LIBS) $(vmwgfx_LIBS)
- $(call mklib-egl,vmwgfx)
+$(OUTPUT_PATH)/$(PIPE_PREFIX)vmwgfx.so: pipe_vmwgfx.o $(vmwgfx_LIBS)
+ $(call mklib,vmwgfx)
-$(OUTPUT_PATH)/$(PIPE_PREFIX)swrast.so: pipe_swrast.o egl.o $(egl_LIBS) $(swrast_LIBS)
- $(call mklib-egl,swrast)
+$(OUTPUT_PATH)/$(PIPE_PREFIX)swrast.so: pipe_swrast.o $(swrast_LIBS)
+ $(call mklib,swrast)
# state trackers
$(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS)
drivers += [llvmpipe]
drivers += [identity, trace, rbug]
- egl_gallium_swrast = env.SharedLibrary(
- target ='egl_gallium_swrast',
+ egl_gallium = env.SharedLibrary(
+ target ='egl_gallium',
source = ['egl.c', 'pipe_swrast.c'],
LIBS = st_egl_gdi + ws_gdi + drivers + gallium + egl + env['LIBS'],
)
- env.InstallSharedLibrary(egl_gallium_swrast)
+ env.InstallSharedLibrary(egl_gallium)
api_libs = {
'OpenVG': vgapi + st_vega,
#include "egllog.h"
#include "state_tracker/st_api.h"
-#include "softpipe/sp_public.h"
-#include "llvmpipe/lp_public.h"
-#include "target-helpers/wrap_screen.h"
-#include "common/egl_g3d_loader.h"
#include "state_tracker/drm_driver.h"
+#include "common/egl_g3d_loader.h"
struct egl_g3d_loader egl_g3d_loader;
static struct st_module {
boolean initialized;
- const char *name;
+ char *name;
struct util_dl_library *lib;
struct st_api *stapi;
} st_modules[ST_API_COUNT];
+static struct pipe_module {
+ boolean initialized;
+ char *name;
+ struct util_dl_library *lib;
+ const struct drm_driver_descriptor *drmdd;
+ struct pipe_screen *(*swrast_create_screen)(struct sw_winsys *);
+} pipe_modules[16];
+
+static char *
+loader_strdup(const char *s)
+{
+ size_t len = (s) ? strlen(s) : 0;
+ char *t = MALLOC(len + 1);
+ if (t) {
+ memcpy(t, s, len);
+ t[len] = '\0';
+ }
+ return t;
+}
+
static EGLBoolean
dlopen_st_module_cb(const char *dir, size_t len, void *callback_data)
{
{
struct st_api *(*create_api)(void);
- stmod->name = name;
+ stmod->name = loader_strdup(name);
if (stmod->name)
_eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod);
else
}
}
- if (!stmod->stapi)
+ if (!stmod->stapi) {
+ FREE(stmod->name);
stmod->name = NULL;
+ }
return (stmod->stapi != NULL);
}
+static EGLBoolean
+dlopen_pipe_module_cb(const char *dir, size_t len, void *callback_data)
+{
+ struct pipe_module *pmod = (struct pipe_module *) callback_data;
+ char path[1024];
+ int ret;
+
+ if (len) {
+ ret = util_snprintf(path, sizeof(path),
+ "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, dir, pmod->name);
+ }
+ else {
+ ret = util_snprintf(path, sizeof(path),
+ PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name);
+ }
+ if (ret > 0 && ret < sizeof(path)) {
+ pmod->lib = util_dl_open(path);
+ if (pmod->lib)
+ _eglLog(_EGL_DEBUG, "loaded %s", path);
+ }
+
+ return !(pmod->lib);
+}
+
+static boolean
+load_pipe_module(struct pipe_module *pmod, const char *name)
+{
+ pmod->name = loader_strdup(name);
+ if (!pmod->name)
+ return FALSE;
+
+ _eglSearchPathForEach(dlopen_pipe_module_cb, (void *) pmod);
+ if (pmod->lib) {
+ pmod->drmdd = (const struct drm_driver_descriptor *)
+ util_dl_get_proc_address(pmod->lib, "driver_descriptor");
+ if (pmod->drmdd) {
+ if (pmod->drmdd->driver_name) {
+ /* driver name mismatch */
+ if (strcmp(pmod->drmdd->driver_name, pmod->name) != 0)
+ pmod->drmdd = NULL;
+ }
+ else {
+ /* swrast */
+ pmod->swrast_create_screen =
+ (struct pipe_screen *(*)(struct sw_winsys *))
+ util_dl_get_proc_address(pmod->lib, "swrast_create_screen");
+ if (!pmod->swrast_create_screen)
+ pmod->drmdd = NULL;
+ }
+ }
+
+ if (!pmod->drmdd) {
+ util_dl_close(pmod->lib);
+ pmod->lib = NULL;
+ }
+ }
+
+ if (!pmod->drmdd)
+ pmod->name = NULL;
+
+ return (pmod->drmdd != NULL);
+}
+
static struct st_api *
get_st_api(enum st_api_type api)
{
return stapi;
}
+static struct pipe_module *
+get_pipe_module(const char *name)
+{
+ struct pipe_module *pmod = NULL;
+ int i;
+
+ if (!name)
+ return NULL;
+
+ for (i = 0; i < Elements(pipe_modules); i++) {
+ if (!pipe_modules[i].initialized ||
+ strcmp(pipe_modules[i].name, name) == 0) {
+ pmod = &pipe_modules[i];
+ break;
+ }
+ }
+ if (!pmod)
+ return NULL;
+
+ if (!pmod->initialized) {
+ load_pipe_module(pmod, name);
+ pmod->initialized = TRUE;
+ }
+
+ return pmod;
+}
+
static struct pipe_screen *
create_drm_screen(const char *name, int fd)
{
- return (driver_descriptor.driver_name && name &&
- strcmp(driver_descriptor.driver_name, name) == 0) ?
- driver_descriptor.create_screen(fd) : NULL;
+ struct pipe_module *pmod = get_pipe_module(name);
+ return (pmod && pmod->drmdd->create_screen) ?
+ pmod->drmdd->create_screen(fd) : NULL;
}
static struct pipe_screen *
create_sw_screen(struct sw_winsys *ws)
{
- struct pipe_screen *screen = NULL;
-
-#if defined(GALLIUM_LLVMPIPE)
- if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
- screen = llvmpipe_create_screen(ws);
-#endif
- if (!screen)
- screen = softpipe_create_screen(ws);
-
- return (screen) ? gallium_wrap_screen(screen) : NULL;
+ struct pipe_module *pmod = get_pipe_module("swrast");
+ return (pmod && pmod->swrast_create_screen) ?
+ pmod->swrast_create_screen(ws) : NULL;
}
static const struct egl_g3d_loader *
util_dl_close(stmod->lib);
stmod->lib = NULL;
}
- stmod->name = NULL;
+ if (stmod->name) {
+ FREE(stmod->name);
+ stmod->name = NULL;
+ }
stmod->initialized = FALSE;
}
+ for (i = 0; i < Elements(pipe_modules); i++) {
+ struct pipe_module *pmod = &pipe_modules[i];
+
+ if (!pmod->initialized)
+ break;
+
+ pmod->drmdd = NULL;
+ pmod->swrast_create_screen = NULL;
+ if (pmod->lib) {
+ util_dl_close(pmod->lib);
+ pmod->lib = NULL;
+ }
+ if (pmod->name) {
+ FREE(pmod->name);
+ pmod->name = NULL;
+ }
+ pmod->initialized = FALSE;
+ }
}
static void
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen)
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
+#include "target-helpers/inline_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
#include "state_tracker/drm_driver.h"
+PUBLIC struct pipe_screen *
+swrast_create_screen(struct sw_winsys *ws);
+
+PUBLIC
DRM_DRIVER_DESCRIPTOR("swrast", NULL, NULL)
+
+struct pipe_screen *
+swrast_create_screen(struct sw_winsys *ws)
+{
+ struct pipe_screen *screen;
+
+ screen = sw_screen_create(ws);
+ if (screen)
+ screen = debug_screen_wrap(screen);
+
+ return screen;
+}
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)