[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