[Mesa-dev] [PATCH 12/15] gallium: Add winsys loader for device enumeration and driver multiplexing.

Christian König deathsimple at vodafone.de
Mon Mar 26 07:45:56 PDT 2012


On 26.03.2012 14:56, Jose Fonseca wrote:
> 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
The same is true for winsys/g3dvl, and I'm planning to move it under 
auxiliary for quite some time, but unfortunately it has a dependency on 
X libs, and well something like this is a bit sensitive to put under 
auxiliary. The same might be true for this winsys loader.

Christian.

>
> ----- 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<krh at bitplanet.net>
>> + *    Benjamin Franzke<benjaminfranzke at 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 at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev



More information about the mesa-dev mailing list