This doesn't look like a "winsys" per se, but rather an auxiliary library to create winsys and screens, meant to be used by state trackers. Is this right?
If so then I believe the right place would be somewhere src/gallium/auxiliary . Jose ----- Original Message ----- > The goal is to have a uniform interface to create winsys and > pipe_screen instances for any driver, exposing the device enumeration > capabilities that might be supported by the operating system (for now > there's a "drm" back-end using udev and a "sw" back-end that always > returns the same built-in devices). > > The typical use case of this library will be: > > > > struct ws_loader_device devs[n]; > > struct pipe_screen *screen; > > > > ws_loader_probe(&devs, n); > >[pick some device from the array...] > > > > screen = ws_loader_create_screen(dev, library_search_path); > >[do something with screen...] > > > > screen->destroy(screen); > > ws_loader_release(&devs, N); > > > > A part of the code was taken from targets/gbm/pipe_loader.c, which > will be removed and replaced with calls into this library by a future > commit. > --- > configure.ac | 7 + > src/gallium/winsys/loader/Makefile.am | 34 +++++ > src/gallium/winsys/loader/ws_loader.c | 102 +++++++++++++ > src/gallium/winsys/loader/ws_loader.h | 136 +++++++++++++++++ > src/gallium/winsys/loader/ws_loader_drm.c | 218 > ++++++++++++++++++++++++++++ > src/gallium/winsys/loader/ws_loader_priv.h | 47 ++++++ > src/gallium/winsys/loader/ws_loader_sw.c | 107 ++++++++++++++ > 7 files changed, 651 insertions(+) > create mode 100644 src/gallium/winsys/loader/Makefile.am > create mode 100644 src/gallium/winsys/loader/ws_loader.c > create mode 100644 src/gallium/winsys/loader/ws_loader.h > create mode 100644 src/gallium/winsys/loader/ws_loader_drm.c > create mode 100644 src/gallium/winsys/loader/ws_loader_priv.h > create mode 100644 src/gallium/winsys/loader/ws_loader_sw.c > > diff --git a/configure.ac b/configure.ac > index bf5330d..a28052c 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -1936,6 +1936,10 @@ if test "x$NEED_G3DVL_DRI" = xyes; then > GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS g3dvl/dri" > fi > > +if test "x$enable_gallium_loader" = xyes; then > + GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS loader/" > +fi > + > dnl Tell Automake which drivers to build > for driver in $GALLIUM_DRIVERS_DIRS; do > case "x$driver" in > @@ -1957,6 +1961,8 @@ done > AM_CONDITIONAL(HAVE_GALAHAD_GALLIUM, test x$HAVE_GALAHAD_GALLIUM = > xyes) > AM_CONDITIONAL(HAVE_IDENTITY_GALLIUM, test x$HAVE_IDENTITY_GALLIUM = > xyes) > AM_CONDITIONAL(HAVE_NOOP_GALLIUM, test x$HAVE_NOOP_GALLIUM = xyes) > +AM_CONDITIONAL(HAVE_DRM_LOADER_GALLIUM, test > x$enable_gallium_drm_loader = xyes) > +AM_CONDITIONAL(HAVE_XLIB_LOADER_GALLIUM, test x$HAVE_WINSYS_XLIB = > xyes) > AC_SUBST([GALLIUM_MAKE_DIRS]) > > dnl prepend CORE_DIRS to SRC_DIRS > @@ -1974,6 +1980,7 @@ dnl Substitute the config > AC_CONFIG_FILES([configs/autoconf > src/gallium/winsys/sw/null/Makefile > src/gallium/winsys/sw/xlib/Makefile > + src/gallium/winsys/loader/Makefile > src/gallium/drivers/Makefile > src/gallium/drivers/r300/Makefile > src/gbm/Makefile > diff --git a/src/gallium/winsys/loader/Makefile.am > b/src/gallium/winsys/loader/Makefile.am > new file mode 100644 > index 0000000..45e34da > --- /dev/null > +++ b/src/gallium/winsys/loader/Makefile.am > @@ -0,0 +1,34 @@ > +AUTOMAKE_OPTIONS = subdir-objects > + > +AM_CPPFLAGS = $(DEFINES) \ > + -I$(top_srcdir)/include \ > + -I$(top_srcdir)/src/gallium/include \ > + -I$(top_srcdir)/src/gallium/auxiliary \ > + -I$(top_srcdir)/src/gallium/winsys > + > +AM_CFLAGS = $(PIC_FLAGS) > + > +noinst_LTLIBRARIES = libws_loader.la > + > +libws_loader_la_SOURCES = \ > + ws_loader.h \ > + ws_loader_priv.h \ > + ws_loader.c \ > + ws_loader_sw.c > + > +libws_loader_la_LIBADD = \ > + $(top_srcdir)/src/gallium/winsys/sw/null/libws_null.la > + > +if HAVE_XLIB_LOADER_GALLIUM > +libws_loader_la_LIBADD += \ > + $(top_srcdir)/src/gallium/winsys/sw/xlib/libws_xlib.la > +AM_CFLAGS += -DHAVE_WS_LOADER_XLIB > +endif > + > +if HAVE_DRM_LOADER_GALLIUM > +libws_loader_la_SOURCES += ws_loader_drm.c > +AM_CFLAGS += -DHAVE_WS_LOADER_DRM $(LIBDRM_CFLAGS) > +endif > + > +# FIXME: Remove when the rest of Gallium is converted to automake. > +default: all > diff --git a/src/gallium/winsys/loader/ws_loader.c > b/src/gallium/winsys/loader/ws_loader.c > new file mode 100644 > index 0000000..7071fc7 > --- /dev/null > +++ b/src/gallium/winsys/loader/ws_loader.c > @@ -0,0 +1,102 @@ > +/************************************************************************** > + * > + * Copyright 2012 Francisco Jerez > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person > obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, > including > + * without limitation the rights to use, copy, modify, merge, > publish, > + * distribute, sub license, and/or sell copies of the Software, and > to > + * permit persons to whom the Software is furnished to do so, > subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including > the > + * next paragraph) shall be included in all copies or substantial > portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > NON-INFRINGEMENT. > + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE > LIABLE FOR > + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF > CONTRACT, > + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE > + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + > **************************************************************************/ > + > +#include "loader/ws_loader_priv.h" > + > +#include "util/u_inlines.h" > +#include "util/u_memory.h" > +#include "util/u_string.h" > +#include "util/u_dl.h" > + > +#define MODULE_PREFIX "pipe_" > + > +static int (*backends[])(struct ws_loader_device **, int) = { > +#ifdef HAVE_WS_LOADER_DRM > + &ws_loader_drm_probe, > +#endif > + &ws_loader_sw_probe > +}; > + > +int > +ws_loader_probe(struct ws_loader_device **devs, int ndev) > +{ > + int i, n = 0; > + > + for (i = 0; i < Elements(backends); i++) > + n += backends[i](&devs[n], MAX2(0, ndev - n)); > + > + return n; > +} > + > +void > +ws_loader_release(struct ws_loader_device **devs, int ndev) > +{ > + int i; > + > + for (i = 0; i < ndev; i++) > + devs[i]->ops->release(&devs[i]); > +} > + > +struct pipe_screen * > +ws_loader_create_screen(struct ws_loader_device *dev, > + const char *library_paths) > +{ > + return dev->ops->create_screen(dev, library_paths); > +} > + > +struct util_dl_library * > +ws_loader_find_module(struct ws_loader_device *dev, > + const char *library_paths) > +{ > + struct util_dl_library *lib; > + const char *next; > + char path[PATH_MAX]; > + int len, ret; > + > + for (next = library_paths; *next; library_paths = next + 1) { > + next = util_strchrnul(library_paths, ':'); > + len = next - library_paths; > + > + if (len) > + ret = util_snprintf(path, sizeof(path), "%.*s/%s%s%s", > + len, library_paths, > + MODULE_PREFIX, dev->driver_name, > UTIL_DL_EXT); > + else > + ret = util_snprintf(path, sizeof(path), "%s%s%s", > + MODULE_PREFIX, dev->driver_name, > UTIL_DL_EXT); > + > + if (ret > 0 && ret < sizeof(path)) { > + lib = util_dl_open(path); > + if (lib) { > + debug_printf("loaded %s\n", path); > + return lib; > + } > + } > + } > + > + return NULL; > +} > diff --git a/src/gallium/winsys/loader/ws_loader.h > b/src/gallium/winsys/loader/ws_loader.h > new file mode 100644 > index 0000000..2554da5 > --- /dev/null > +++ b/src/gallium/winsys/loader/ws_loader.h > @@ -0,0 +1,136 @@ > +/************************************************************************** > + * > + * Copyright 2012 Francisco Jerez > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person > obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, > including > + * without limitation the rights to use, copy, modify, merge, > publish, > + * distribute, sub license, and/or sell copies of the Software, and > to > + * permit persons to whom the Software is furnished to do so, > subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including > the > + * next paragraph) shall be included in all copies or substantial > portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > NON-INFRINGEMENT. > + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE > LIABLE FOR > + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF > CONTRACT, > + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE > + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + > **************************************************************************/ > + > +/** > + * \file Winsys that provides device enumeration and multiplexing of > + * other winsys. > + */ > + > +#ifndef WS_LOADER_H > +#define WS_LOADER_H > + > +#include "pipe/p_compiler.h" > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +struct pipe_screen; > + > +enum ws_loader_device_type { > + WS_LOADER_DEVICE_SOFTWARE, > + WS_LOADER_DEVICE_PCI, > + NUM_WS_LOADER_DEVICE_TYPES > +}; > + > +/** > + * A device known to the winsys loader. > + */ > +struct ws_loader_device { > + enum ws_loader_device_type type; > + > + union { > + struct { > + int vendor_id; > + int chip_id; > + } pci; > + }; /**< Discriminated by \a type */ > + > + const char *driver_name; > + const struct ws_loader_ops *ops; > +}; > + > +/** > + * Get a list of known devices. > + * > + * \param devs Array that will be filled with pointers to the > devices > + * available in the system. > + * \param ndev Maximum number of devices to return. > + * \return Number of devices available in the system. > + */ > +int > +ws_loader_probe(struct ws_loader_device **devs, int ndev); > + > +/** > + * Create a pipe_screen for the specified device. > + * > + * \param dev Device the screen will be created for. > + * \param library_paths Colon-separated list of filesystem paths > that > + * will be used to look for the pipe driver > + * module that handles this device. > + */ > +struct pipe_screen * > +ws_loader_create_screen(struct ws_loader_device *dev, > + const char *library_paths); > + > +/** > + * Release resources allocated for a list of devices. > + * > + * Should be called when the specified devices are no longer in use > to > + * release any resources allocated by ws_loader_probe. > + * > + * \param devs Devices to release. > + * \param ndev Number of devices to release. > + */ > +void > +ws_loader_release(struct ws_loader_device **devs, int ndev); > + > +/** > + * Get a list of known software devices. > + * > + * This function is platform-specific. > + * > + * \sa ws_loader_probe > + */ > +int > +ws_loader_sw_probe(struct ws_loader_device **devs, int ndev); > + > +/** > + * Get a list of known DRM devices. > + * > + * This function is platform-specific. > + * > + * \sa ws_loader_probe > + */ > +int > +ws_loader_drm_probe(struct ws_loader_device **devs, int ndev); > + > +/** > + * Initialize a DRM device in an already opened fd. > + * > + * This function is platform-specific. > + * > + * \sa ws_loader_probe > + */ > +boolean > +ws_loader_drm_probe_fd(struct ws_loader_device **dev, int fd); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* WS_LOADER_H */ > diff --git a/src/gallium/winsys/loader/ws_loader_drm.c > b/src/gallium/winsys/loader/ws_loader_drm.c > new file mode 100644 > index 0000000..817872b > --- /dev/null > +++ b/src/gallium/winsys/loader/ws_loader_drm.c > @@ -0,0 +1,218 @@ > +/************************************************************************** > + * > + * Copyright 2011 Intel Corporation > + * Copyright 2012 Francisco Jerez > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person > obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, > including > + * without limitation the rights to use, copy, modify, merge, > publish, > + * distribute, sub license, and/or sell copies of the Software, and > to > + * permit persons to whom the Software is furnished to do so, > subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including > the > + * next paragraph) shall be included in all copies or substantial > portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > NON-INFRINGEMENT. > + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE > LIABLE FOR > + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF > CONTRACT, > + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE > + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: > + * Kristian Høgsberg <k...@bitplanet.net> > + * Benjamin Franzke <benjaminfran...@googlemail.com> > + * > + > **************************************************************************/ > + > +#include <fcntl.h> > +#include <stdio.h> > +#include <libudev.h> > +#include <xf86drm.h> > + > +#include "state_tracker/drm_driver.h" > +#include "loader/ws_loader_priv.h" > + > +#include "util/u_memory.h" > +#include "util/u_dl.h" > +#include "util/u_debug.h" > + > +#define DRIVER_MAP_GALLIUM_ONLY > +#include "pci_ids/pci_id_driver_map.h" > + > +struct ws_loader_drm_device { > + struct ws_loader_device base; > + struct util_dl_library *lib; > + int fd; > +}; > + > +#define ws_loader_drm_device(dev) ((struct ws_loader_drm_device > *)dev) > + > +static boolean > +find_drm_pci_id(struct ws_loader_drm_device *ddev) > +{ > + struct udev *udev = NULL; > + struct udev_device *parent, *device = NULL; > + struct stat stat; > + const char *pci_id; > + > + if (fstat(ddev->fd, &stat) < 0) > + goto fail; > + > + udev = udev_new(); > + if (!udev) > + goto fail; > + > + device = udev_device_new_from_devnum(udev, 'c', stat.st_rdev); > + if (!device) > + goto fail; > + > + parent = udev_device_get_parent(device); > + if (!parent) > + goto fail; > + > + pci_id = udev_device_get_property_value(parent, "PCI_ID"); > + if (!pci_id || > + sscanf(pci_id, "%x:%x", &ddev->base.pci.vendor_id, > + &ddev->base.pci.chip_id) != 2) > + goto fail; > + > + return TRUE; > + > + fail: > + if (device) > + udev_device_unref(device); > + if (udev) > + udev_unref(udev); > + > + debug_printf("pci id for fd %d not found\n", ddev->fd); > + return FALSE; > +} > + > +static boolean > +find_drm_driver_name(struct ws_loader_drm_device *ddev) > +{ > + struct ws_loader_device *dev = &ddev->base; > + int i, j; > + > + for (i = 0; driver_map[i].driver; i++) { > + if (dev->pci.vendor_id != driver_map[i].vendor_id) > + continue; > + > + if (driver_map[i].num_chips_ids == -1) { > + dev->driver_name = driver_map[i].driver; > + goto found; > + } > + > + for (j = 0; j < driver_map[i].num_chips_ids; j++) { > + if (dev->pci.chip_id == driver_map[i].chip_ids[j]) { > + dev->driver_name = driver_map[i].driver; > + goto found; > + } > + } > + } > + > + return FALSE; > + > + found: > + debug_printf("driver for %04x:%04x: %s\n", dev->pci.vendor_id, > + dev->pci.chip_id, dev->driver_name); > + return TRUE; > +} > + > +static struct ws_loader_ops ws_loader_drm_ops; > + > +boolean > +ws_loader_drm_probe_fd(struct ws_loader_device **dev, int fd) > +{ > + struct ws_loader_drm_device *ddev = > CALLOC_STRUCT(ws_loader_drm_device); > + > + ddev->base.type = WS_LOADER_DEVICE_PCI; > + ddev->base.ops = &ws_loader_drm_ops; > + ddev->fd = fd; > + > + if (!find_drm_pci_id(ddev)) > + goto fail; > + > + if (!find_drm_driver_name(ddev)) > + goto fail; > + > + *dev = &ddev->base; > + return TRUE; > + > + fail: > + FREE(ddev); > + return FALSE; > +} > + > +static int > +open_drm_minor(int minor) > +{ > + char path[PATH_MAX]; > + snprintf(path, sizeof(path), DRM_DEV_NAME, DRM_DIR_NAME, minor); > + return open(path, O_RDWR, 0); > +} > + > +int > +ws_loader_drm_probe(struct ws_loader_device **devs, int ndev) > +{ > + int i, j, fd; > + > + for (i = 0, j = 0; i < DRM_MAX_MINOR; i++) { > + fd = open_drm_minor(i); > + if (fd < 0) > + continue; > + > + if (j >= ndev || !ws_loader_drm_probe_fd(&devs[j], fd)) > + close(fd); > + > + j++; > + } > + > + return j; > +} > + > +static void > +ws_loader_drm_release(struct ws_loader_device **dev) > +{ > + struct ws_loader_drm_device *ddev = ws_loader_drm_device(*dev); > + > + if (ddev->lib) > + util_dl_close(ddev->lib); > + > + close(ddev->fd); > + FREE(ddev); > + *dev = NULL; > +} > + > +static struct pipe_screen * > +ws_loader_drm_create_screen(struct ws_loader_device *dev, > + const char *library_paths) > +{ > + struct ws_loader_drm_device *ddev = ws_loader_drm_device(dev); > + const struct drm_driver_descriptor *dd; > + > + if (!ddev->lib) > + ddev->lib = ws_loader_find_module(dev, library_paths); > + if (!ddev->lib) > + return NULL; > + > + dd = (const struct drm_driver_descriptor *) > + util_dl_get_proc_address(ddev->lib, "driver_descriptor"); > + > + /* sanity check on the name */ > + if (!dd || strcmp(dd->name, ddev->base.driver_name) != 0) > + return NULL; > + > + return dd->create_screen(ddev->fd); > +} > + > +static struct ws_loader_ops ws_loader_drm_ops = { > + .create_screen = ws_loader_drm_create_screen, > + .release = ws_loader_drm_release > +}; > diff --git a/src/gallium/winsys/loader/ws_loader_priv.h > b/src/gallium/winsys/loader/ws_loader_priv.h > new file mode 100644 > index 0000000..0de33d7 > --- /dev/null > +++ b/src/gallium/winsys/loader/ws_loader_priv.h > @@ -0,0 +1,47 @@ > +/************************************************************************** > + * > + * Copyright 2012 Francisco Jerez > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person > obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, > including > + * without limitation the rights to use, copy, modify, merge, > publish, > + * distribute, sub license, and/or sell copies of the Software, and > to > + * permit persons to whom the Software is furnished to do so, > subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including > the > + * next paragraph) shall be included in all copies or substantial > portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > NON-INFRINGEMENT. > + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE > LIABLE FOR > + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF > CONTRACT, > + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE > + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + > **************************************************************************/ > + > +#ifndef WS_LOADER_PRIV_H > +#define WS_LOADER_PRIV_H > + > +#include "ws_loader.h" > + > +struct ws_loader_ops { > + struct pipe_screen *(*create_screen)(struct ws_loader_device > *dev, > + const char *library_paths); > + > + void (*release)(struct ws_loader_device **dev); > +}; > + > +/** > + * Open the pipe driver module that handles a specified device. > + */ > +struct util_dl_library * > +ws_loader_find_module(struct ws_loader_device *dev, > + const char *library_paths); > + > +#endif /* WS_LOADER_PRIV_H */ > diff --git a/src/gallium/winsys/loader/ws_loader_sw.c > b/src/gallium/winsys/loader/ws_loader_sw.c > new file mode 100644 > index 0000000..b3f925e > --- /dev/null > +++ b/src/gallium/winsys/loader/ws_loader_sw.c > @@ -0,0 +1,107 @@ > +/************************************************************************** > + * > + * Copyright 2012 Francisco Jerez > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person > obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, > including > + * without limitation the rights to use, copy, modify, merge, > publish, > + * distribute, sub license, and/or sell copies of the Software, and > to > + * permit persons to whom the Software is furnished to do so, > subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including > the > + * next paragraph) shall be included in all copies or substantial > portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > NON-INFRINGEMENT. > + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE > LIABLE FOR > + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF > CONTRACT, > + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE > + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + > **************************************************************************/ > + > +#include "loader/ws_loader_priv.h" > + > +#include "util/u_memory.h" > +#include "util/u_dl.h" > +#include "sw/null/null_sw_winsys.h" > +#include "target-helpers/inline_sw_helper.h" > +#include "state_tracker/xlib_sw_winsys.h" > + > +struct ws_loader_sw_device { > + struct ws_loader_device base; > + struct util_dl_library *lib; > + struct sw_winsys *ws; > +}; > + > +#define ws_loader_sw_device(dev) ((struct ws_loader_sw_device *)dev) > + > +static struct ws_loader_ops ws_loader_sw_ops; > + > +static struct sw_winsys *(*backends[])() = { > +#ifdef HAVE_WINSYS_XLIB > + x11_sw_create, > +#endif > + null_sw_create > +}; > + > +int > +ws_loader_sw_probe(struct ws_loader_device **devs, int ndev) > +{ > + int i; > + > + for (i = 0; i < Elements(backends); i++) { > + if (i < ndev) { > + struct ws_loader_sw_device *sdev = > CALLOC_STRUCT(ws_loader_sw_device); > + > + sdev->base.type = WS_LOADER_DEVICE_SOFTWARE; > + sdev->base.driver_name = "swrast"; > + sdev->base.ops = &ws_loader_sw_ops; > + sdev->ws = backends[i](); > + devs[i] = &sdev->base; > + } > + } > + > + return i; > +} > + > +static void > +ws_loader_sw_release(struct ws_loader_device **dev) > +{ > + struct ws_loader_sw_device *sdev = ws_loader_sw_device(*dev); > + > + if (sdev->lib) > + util_dl_close(sdev->lib); > + > + FREE(sdev); > + *dev = NULL; > +} > + > +static struct pipe_screen * > +ws_loader_sw_create_screen(struct ws_loader_device *dev, > + const char *library_paths) > +{ > + struct ws_loader_sw_device *sdev = ws_loader_sw_device(dev); > + struct pipe_screen *(*init)(struct sw_winsys *); > + > + if (!sdev->lib) > + sdev->lib = ws_loader_find_module(dev, library_paths); > + if (!sdev->lib) > + return NULL; > + > + init = (void *)util_dl_get_proc_address(sdev->lib, > "swrast_create_screen"); > + if (!init) > + return NULL; > + > + return init(sdev->ws); > +} > + > +static struct ws_loader_ops ws_loader_sw_ops = { > + .create_screen = ws_loader_sw_create_screen, > + .release = ws_loader_sw_release > +}; > -- > 1.7.9.2 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev