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.tags/mesa-7.9-rc1
/* XXX Need to decide how to do dynamic name lookup on Windows */ | /* XXX Need to decide how to do dynamic name lookup on Windows */ | ||||
static const char *DefaultDriverNames[] = { | static const char *DefaultDriverNames[] = { | ||||
"egl_gallium_swrast" | |||||
"egl_gallium" | |||||
}; | }; | ||||
typedef HMODULE lib_handle; | typedef HMODULE lib_handle; | ||||
static const char *DefaultDriverNames[] = { | static const char *DefaultDriverNames[] = { | ||||
"egl_gallium", | |||||
"egl_dri2", | "egl_dri2", | ||||
"egl_glx" | "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 | * Run the preload function on each driver directory and return the number of | ||||
* drivers loaded. | * 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. | * Preload drivers. | ||||
* | * | ||||
return EGL_TRUE; | return EGL_TRUE; | ||||
} | } | ||||
loaded = (_eglPreloadUserDriver() || | |||||
_eglPreloadGalliumDrivers()); | |||||
loaded = _eglPreloadUserDriver(); | |||||
_eglUnlockMutex(_eglGlobal.Mutex); | _eglUnlockMutex(_eglGlobal.Mutex); | ||||
#include "state_tracker/drm_driver.h" | #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 * | static struct native_display * | ||||
native_create_display(void *dpy, struct native_event_handler *event_handler, | native_create_display(void *dpy, struct native_event_handler *event_handler, | ||||
void *user_data) | void *user_data) | ||||
static const struct native_platform x11_platform = { | static const struct native_platform x11_platform = { | ||||
"X11", /* name */ | "X11", /* name */ | ||||
x11_create_probe, | |||||
x11_get_probe_result, | |||||
NULL, /* create_probe */ | |||||
NULL, /* get_probe_result */ | |||||
native_create_display | native_create_display | ||||
}; | }; | ||||
# | # | ||||
# This is the Makefile for EGL Gallium driver package. The package consists of | # 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 | # The following variables are examined | ||||
# | # | ||||
include $(TOP)/configs/current | include $(TOP)/configs/current | ||||
ST_PREFIX := st_ | ST_PREFIX := st_ | ||||
PIPE_PREFIX := egl_gallium_ | |||||
PIPE_PREFIX := pipe_ | |||||
common_CPPFLAGS := \ | common_CPPFLAGS := \ | ||||
-I$(TOP)/src/gallium/auxiliary \ | -I$(TOP)/src/gallium/auxiliary \ | ||||
egl_CPPFLAGS := \ | egl_CPPFLAGS := \ | ||||
-I$(TOP)/src/gallium/state_trackers/egl \ | -I$(TOP)/src/gallium/state_trackers/egl \ | ||||
-I$(TOP)/src/egl/main \ | -I$(TOP)/src/egl/main \ | ||||
-DST_PREFIX=\"$(ST_PREFIX)\" | |||||
-DPIPE_PREFIX=\"$(PIPE_PREFIX)\" -DST_PREFIX=\"$(ST_PREFIX)\" | |||||
egl_SYS := -lm -ldl -lEGL | 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)),) | ifneq ($(findstring x11, $(EGL_PLATFORMS)),) | ||||
egl_SYS += -lX11 -lXext -lXfixes | egl_SYS += -lX11 -lXext -lXfixes | ||||
endif | endif | ||||
egl_CPPFLAGS := $(sort $(egl_CPPFLAGS)) | 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 pipe driver | ||||
i915_CPPFLAGS := | i915_CPPFLAGS := | ||||
i915_SYS := -ldrm_intel | i915_SYS := -ldrm_intel | ||||
$(TOP)/src/gallium/drivers/svga/libsvga.a | $(TOP)/src/gallium/drivers/svga/libsvga.a | ||||
# swrast (pseudo) pipe driver | # 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 | # OpenGL state tracker | ||||
GL_CPPFLAGS := -I$(TOP)/src/mesa $(API_DEFINES) | GL_CPPFLAGS := -I$(TOP)/src/mesa $(API_DEFINES) | ||||
OUTPUTS += swrast | OUTPUTS += swrast | ||||
OUTPUTS := $(addprefix $(PIPE_PREFIX), $(OUTPUTS)) | 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 := $(addsuffix .so, $(OUTPUTS)) | ||||
OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS)) | OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS)) | ||||
default: $(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 | define mklib | ||||
$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ | $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ | ||||
-install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \ | -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \ | ||||
$(common_SYS) $($(1)_SYS) | $(common_SYS) $($(1)_SYS) | ||||
endef | 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 | # state trackers | ||||
$(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS) | $(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS) |
drivers += [llvmpipe] | drivers += [llvmpipe] | ||||
drivers += [identity, trace, rbug] | 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'], | source = ['egl.c', 'pipe_swrast.c'], | ||||
LIBS = st_egl_gdi + ws_gdi + drivers + gallium + egl + env['LIBS'], | LIBS = st_egl_gdi + ws_gdi + drivers + gallium + egl + env['LIBS'], | ||||
) | ) | ||||
env.InstallSharedLibrary(egl_gallium_swrast) | |||||
env.InstallSharedLibrary(egl_gallium) | |||||
api_libs = { | api_libs = { | ||||
'OpenVG': vgapi + st_vega, | 'OpenVG': vgapi + st_vega, |
#include "egllog.h" | #include "egllog.h" | ||||
#include "state_tracker/st_api.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 "state_tracker/drm_driver.h" | ||||
#include "common/egl_g3d_loader.h" | |||||
struct egl_g3d_loader egl_g3d_loader; | struct egl_g3d_loader egl_g3d_loader; | ||||
static struct st_module { | static struct st_module { | ||||
boolean initialized; | boolean initialized; | ||||
const char *name; | |||||
char *name; | |||||
struct util_dl_library *lib; | struct util_dl_library *lib; | ||||
struct st_api *stapi; | struct st_api *stapi; | ||||
} st_modules[ST_API_COUNT]; | } 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 | static EGLBoolean | ||||
dlopen_st_module_cb(const char *dir, size_t len, void *callback_data) | dlopen_st_module_cb(const char *dir, size_t len, void *callback_data) | ||||
{ | { | ||||
{ | { | ||||
struct st_api *(*create_api)(void); | struct st_api *(*create_api)(void); | ||||
stmod->name = name; | |||||
stmod->name = loader_strdup(name); | |||||
if (stmod->name) | if (stmod->name) | ||||
_eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod); | _eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod); | ||||
else | else | ||||
} | } | ||||
} | } | ||||
if (!stmod->stapi) | |||||
if (!stmod->stapi) { | |||||
FREE(stmod->name); | |||||
stmod->name = NULL; | stmod->name = NULL; | ||||
} | |||||
return (stmod->stapi != 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 * | static struct st_api * | ||||
get_st_api(enum st_api_type api) | get_st_api(enum st_api_type api) | ||||
{ | { | ||||
return stapi; | 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 * | static struct pipe_screen * | ||||
create_drm_screen(const char *name, int fd) | 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 * | static struct pipe_screen * | ||||
create_sw_screen(struct sw_winsys *ws) | 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 * | static const struct egl_g3d_loader * | ||||
util_dl_close(stmod->lib); | util_dl_close(stmod->lib); | ||||
stmod->lib = NULL; | stmod->lib = NULL; | ||||
} | } | ||||
stmod->name = NULL; | |||||
if (stmod->name) { | |||||
FREE(stmod->name); | |||||
stmod->name = NULL; | |||||
} | |||||
stmod->initialized = FALSE; | 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 | static void |
return screen; | return screen; | ||||
} | } | ||||
PUBLIC | |||||
DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen) | DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen) |
return screen; | return screen; | ||||
} | } | ||||
PUBLIC | |||||
DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen) | DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen) |
return screen; | return screen; | ||||
} | } | ||||
PUBLIC | |||||
DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen) | 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" | #include "state_tracker/drm_driver.h" | ||||
PUBLIC struct pipe_screen * | |||||
swrast_create_screen(struct sw_winsys *ws); | |||||
PUBLIC | |||||
DRM_DRIVER_DESCRIPTOR("swrast", NULL, NULL) | 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; | return screen; | ||||
} | } | ||||
PUBLIC | |||||
DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen) | DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen) |