st/egl: Build a single EGL driver.
authorChia-I Wu <olv@lunarg.com>
Wed, 23 Jun 2010 13:36:20 +0000 (21:36 +0800)
committerChia-I Wu <olv@lunarg.com>
Tue, 29 Jun 2010 09:16:20 +0000 (17:16 +0800)
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.

src/egl/main/egldriver.c
src/gallium/state_trackers/egl/x11/native_x11.c
src/gallium/targets/egl/Makefile
src/gallium/targets/egl/SConscript
src/gallium/targets/egl/egl.c
src/gallium/targets/egl/pipe_i965.c
src/gallium/targets/egl/pipe_nouveau.c
src/gallium/targets/egl/pipe_radeon.c
src/gallium/targets/egl/pipe_swrast.c
src/gallium/targets/egl/pipe_vmwgfx.c

index c65df286454859a59520679dfe886c1c4f53ebee..71d2ba06d5031ba7830d34eaf4a2ca82b12eb51b 100644 (file)
@@ -39,7 +39,7 @@
 
 /* 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;
@@ -68,6 +68,7 @@ library_suffix(void)
 
 
 static const char *DefaultDriverNames[] = {
+   "egl_gallium",
    "egl_dri2",
    "egl_glx"
 };
@@ -294,71 +295,6 @@ _eglLoaderFile(const char *dir, size_t len, void *loader_data)
 }
 
 
-/**
- * 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.
@@ -463,20 +399,6 @@ _eglPreloadUserDriver(void)
 }
 
 
-/**
- * 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.
  *
@@ -497,8 +419,7 @@ _eglPreloadDrivers(void)
       return EGL_TRUE;
    }
 
-   loaded = (_eglPreloadUserDriver() ||
-             _eglPreloadGalliumDrivers());
+   loaded = _eglPreloadUserDriver();
 
    _eglUnlockMutex(_eglGlobal.Mutex);
 
index f0519405d3d4c83474d05d16450288cb6b505f5f..8dc19d0dd9f5ea58207307c9276bb73ee36f155d 100644 (file)
 
 #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)
@@ -131,8 +59,8 @@ native_create_display(void *dpy, struct native_event_handler *event_handler,
 
 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
 };
 
index 80f9c605599e1573d909322444640afa57dadc4e..b9db6bc2c9f7c65aac818ba91f82aa86a267bdea 100644 (file)
@@ -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)
index f2bcb6e684fe7770d3afad8e29009c4bea4487ff..1643867f60533c47c8f753fc0e168713514513fe 100644 (file)
@@ -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,
index 831adf7c765ba7cce8d4cb2a38dc7a36d0fc2125..d9d89485c3cde1c40a7c9752215c3e0354410e5f 100644 (file)
 #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
index cf96214e83e025ea4d4fb4a1fb0a6872b1acac7d..43bf646e8255094408490233b38b2391cc526786 100644 (file)
@@ -27,4 +27,5 @@ create_screen(int fd)
    return screen;
 }
 
+PUBLIC
 DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen)
index e725a4d9b7a427229ff0119f14608a2a110dd8e4..0c9081bc71306fd155b52b5b1cd4521e6c4fcbc3 100644 (file)
@@ -17,4 +17,5 @@ create_screen(int fd)
    return screen;
 }
 
+PUBLIC
 DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
index 5a0a8dc573839bb2ec6f7213371fc83bd9e19e4d..35550bcb263e53288651b3e503ca616fd3e1df42 100644 (file)
@@ -23,4 +23,5 @@ create_screen(int fd)
    return screen;
 }
 
+PUBLIC
 DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
index 1ad4e25a6ebc958b5477acd000ed73fe8cd9cf2f..b2e3289c5d38e94e2cd47cac95d3617ed66ea45b 100644 (file)
@@ -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;
+}
index 15089d6db264a20126697f4aeb6ee36e2c627e97..22a28fa858ae2cbfec19b4769a5633e98c0ca55a 100644 (file)
@@ -23,4 +23,5 @@ create_screen(int fd)
    return screen;
 }
 
+PUBLIC
 DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)