summaryrefslogtreecommitdiffstats
path: root/src/gallium/targets
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-06-23 21:36:20 +0800
committerChia-I Wu <[email protected]>2010-06-29 17:16:20 +0800
commita81ef14228c6fe2893527b7b5f12855c90db3f8e (patch)
treeaf46c977703847b4f262aee4efa42d198ded78ef /src/gallium/targets
parentd5ab243d5a5bacbd2ba615d40f13c8ab37364745 (diff)
st/egl: Build a single EGL driver.
This change makes st/egl build a single egl_gallium.so and multiple st_<API>.so and pipe_<HW>.so. When a display is initialized, the corresponding pipe driver will be loaded. When a context is created, the corresponding state tracker will be loaded. Unlike DRI drivers, no ABI compatibility is maintained. egl_gallium, pipe drivers and state trackers should always be distributed as a single package. As such, there is only a single src/gallium/targets/egl/ that builds everything for the package.
Diffstat (limited to 'src/gallium/targets')
-rw-r--r--src/gallium/targets/egl/Makefile75
-rw-r--r--src/gallium/targets/egl/SConscript6
-rw-r--r--src/gallium/targets/egl/egl.c165
-rw-r--r--src/gallium/targets/egl/pipe_i965.c1
-rw-r--r--src/gallium/targets/egl/pipe_nouveau.c1
-rw-r--r--src/gallium/targets/egl/pipe_radeon.c1
-rw-r--r--src/gallium/targets/egl/pipe_swrast.c18
-rw-r--r--src/gallium/targets/egl/pipe_vmwgfx.c1
8 files changed, 205 insertions, 63 deletions
diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile
index 80f9c605599..b9db6bc2c9f 100644
--- a/src/gallium/targets/egl/Makefile
+++ b/src/gallium/targets/egl/Makefile
@@ -2,8 +2,9 @@
#
# 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
#
@@ -16,7 +17,7 @@ TOP = ../../../..
include $(TOP)/configs/current
ST_PREFIX := st_
-PIPE_PREFIX := egl_gallium_
+PIPE_PREFIX := pipe_
common_CPPFLAGS := \
-I$(TOP)/src/gallium/auxiliary \
@@ -34,11 +35,9 @@ common_LIBS := \
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
@@ -67,13 +66,6 @@ egl_CPPFLAGS += -DFEATURE_VG=1
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
@@ -112,9 +104,17 @@ vmwgfx_LIBS := \
$(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)
@@ -158,21 +158,14 @@ endif
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) $< \
@@ -180,24 +173,28 @@ $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
$(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)
diff --git a/src/gallium/targets/egl/SConscript b/src/gallium/targets/egl/SConscript
index f2bcb6e684f..1643867f605 100644
--- a/src/gallium/targets/egl/SConscript
+++ b/src/gallium/targets/egl/SConscript
@@ -25,13 +25,13 @@ if env['platform'] == 'windows':
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,
diff --git a/src/gallium/targets/egl/egl.c b/src/gallium/targets/egl/egl.c
index 831adf7c765..d9d89485c3c 100644
--- a/src/gallium/targets/egl/egl.c
+++ b/src/gallium/targets/egl/egl.c
@@ -34,21 +34,38 @@
#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)
{
@@ -81,7 +98,7 @@ load_st_module(struct st_module *stmod,
{
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
@@ -99,12 +116,77 @@ load_st_module(struct st_module *stmod,
}
}
- 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)
{
@@ -206,27 +288,47 @@ guess_gl_api(void)
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 *
@@ -273,9 +375,30 @@ loader_fini(void)
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
diff --git a/src/gallium/targets/egl/pipe_i965.c b/src/gallium/targets/egl/pipe_i965.c
index cf96214e83e..43bf646e825 100644
--- a/src/gallium/targets/egl/pipe_i965.c
+++ b/src/gallium/targets/egl/pipe_i965.c
@@ -27,4 +27,5 @@ create_screen(int fd)
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen)
diff --git a/src/gallium/targets/egl/pipe_nouveau.c b/src/gallium/targets/egl/pipe_nouveau.c
index e725a4d9b7a..0c9081bc713 100644
--- a/src/gallium/targets/egl/pipe_nouveau.c
+++ b/src/gallium/targets/egl/pipe_nouveau.c
@@ -17,4 +17,5 @@ create_screen(int fd)
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
diff --git a/src/gallium/targets/egl/pipe_radeon.c b/src/gallium/targets/egl/pipe_radeon.c
index 5a0a8dc5738..35550bcb263 100644
--- a/src/gallium/targets/egl/pipe_radeon.c
+++ b/src/gallium/targets/egl/pipe_radeon.c
@@ -23,4 +23,5 @@ create_screen(int fd)
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
diff --git a/src/gallium/targets/egl/pipe_swrast.c b/src/gallium/targets/egl/pipe_swrast.c
index 1ad4e25a6eb..b2e3289c5d3 100644
--- a/src/gallium/targets/egl/pipe_swrast.c
+++ b/src/gallium/targets/egl/pipe_swrast.c
@@ -1,4 +1,22 @@
+#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;
+}
diff --git a/src/gallium/targets/egl/pipe_vmwgfx.c b/src/gallium/targets/egl/pipe_vmwgfx.c
index 15089d6db26..22a28fa858a 100644
--- a/src/gallium/targets/egl/pipe_vmwgfx.c
+++ b/src/gallium/targets/egl/pipe_vmwgfx.c
@@ -23,4 +23,5 @@ create_screen(int fd)
return screen;
}
+PUBLIC
DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)