[Mesa-dev] [PATCH 6/8] gbm: Add gallium (drm) backend

Benjamin Franzke benjaminfranzke at googlemail.com
Wed Jun 22 06:30:13 PDT 2011


---
 configure.ac                                       |   23 ++
 src/gallium/state_trackers/gbm/Makefile            |   46 ++++
 src/gallium/state_trackers/gbm/gbm_drm.c           |  225 ++++++++++++++++++++
 .../state_trackers/gbm/gbm_gallium_drmint.h        |   74 +++++++
 src/gallium/targets/gbm/Makefile                   |   32 +++
 src/gallium/targets/gbm/gbm.c                      |   61 ++++++
 src/gallium/targets/gbm/pipe_loader.c              |  192 +++++++++++++++++
 src/gallium/targets/gbm/pipe_loader.h              |   48 ++++
 src/gbm/main/backend.c                             |    1 +
 9 files changed, 702 insertions(+), 0 deletions(-)
 create mode 100644 src/gallium/state_trackers/gbm/Makefile
 create mode 100644 src/gallium/state_trackers/gbm/gbm_drm.c
 create mode 100644 src/gallium/state_trackers/gbm/gbm_gallium_drmint.h
 create mode 100644 src/gallium/targets/gbm/Makefile
 create mode 100644 src/gallium/targets/gbm/gbm.c
 create mode 100644 src/gallium/targets/gbm/pipe_loader.c
 create mode 100644 src/gallium/targets/gbm/pipe_loader.h

diff --git a/configure.ac b/configure.ac
index 249a689..dbf8fe5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -559,6 +559,13 @@ AC_ARG_ENABLE([gallium_egl],
          @<:@default=disable@:>@])],
     [enable_gallium_egl="$enableval"],
     [enable_gallium_egl=no])
+AC_ARG_ENABLE([gallium_gbm],
+    [AS_HELP_STRING([--enable-gallium-gbm],
+        [enable optional gbm state tracker (not required for
+         gbm support in Gallium)
+         @<:@default=disable@:>@])],
+    [enable_gallium_gbm="$enableval"],
+    [enable_gallium_gbm=no])
 
 # Option for Gallium drivers
 GALLIUM_DRIVERS_DEFAULT="r300,r600,swrast"
@@ -1305,6 +1312,22 @@ if test "x$enable_gallium_egl" = xyes; then
 fi
 
 dnl
+dnl gbm Gallium configuration
+dnl
+if test "x$enable_gallium_gbm" = xyes; then
+    if test "x$with_gallium_drivers" = x; then
+        AC_MSG_ERROR([cannot enable gbm_gallium without Gallium])
+    fi
+    if test "x$enable_gbm" = xno; then
+        AC_MSG_ERROR([cannot enable gbm_gallium without gbm])
+    fi
+
+    GALLIUM_STATE_TRACKERS_DIRS="gbm $GALLIUM_STATE_TRACKERS_DIRS"
+    GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS gbm"
+    HAVE_ST_GBM="yes"
+fi
+
+dnl
 dnl X.Org DDX configuration
 dnl
 if test "x$enable_xorg" = xyes; then
diff --git a/src/gallium/state_trackers/gbm/Makefile b/src/gallium/state_trackers/gbm/Makefile
new file mode 100644
index 0000000..1d96eb2
--- /dev/null
+++ b/src/gallium/state_trackers/gbm/Makefile
@@ -0,0 +1,46 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+gbm_INCLUDES = \
+	-I. \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/auxiliary \
+	-I$(TOP)/src/gbm/main \
+	-I$(TOP)/include
+
+gbm_SOURCES = $(wildcard *.c)
+gbm_OBJECTS = $(gbm_SOURCES:.c=.o)
+
+ALL_INCLUDES = $(gbm_INCLUDES)
+ALL_SOURCES = $(gbm_SOURCES)
+
+GBM_OBJECTS = $(gbm_OBJECTS)
+GBM_CPPFLAGS = $(gbm_INCLUDES)
+
+##### TARGETS #####
+
+default: depend libgbm.a
+
+libgbm.a: $(GBM_OBJECTS) Makefile
+	$(MKLIB) -o gbm -static $(GBM_OBJECTS)
+
+depend: 
+	rm -f depend
+	touch depend
+	$(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null
+
+clean:
+	rm -f libgbm.a
+	rm -f $(GBM_OBJECTS)
+	rm -f depend depend.bak
+
+# Dummy target
+install:
+	@echo -n ""
+
+##### RULES #####
+
+$(gbm_OBJECTS): %.o: %.c
+	$(CC) -c $(GBM_CPPFLAGS) $(DEFINES) $(CFLAGS) $< -o $@
+
+sinclude depend
diff --git a/src/gallium/state_trackers/gbm/gbm_drm.c b/src/gallium/state_trackers/gbm/gbm_drm.c
new file mode 100644
index 0000000..39cea7a
--- /dev/null
+++ b/src/gallium/state_trackers/gbm/gbm_drm.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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:
+ *    Benjamin Franzke <benjaminfranzke at googlemail.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "state_tracker/drm_driver.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "gbm_gallium_drmint.h"
+
+static INLINE enum pipe_format
+gbm_format_to_gallium(enum gbm_bo_format format)
+{
+   switch (format) {
+   case GBM_BO_FORMAT_XRGB8888:
+      return PIPE_FORMAT_B8G8R8X8_UNORM;
+   case GBM_BO_FORMAT_ARGB8888:
+      return PIPE_FORMAT_B8G8R8A8_UNORM;
+   default:
+      return PIPE_FORMAT_NONE;
+   }
+
+   return PIPE_FORMAT_NONE;
+}
+
+static INLINE uint
+gbm_usage_to_gallium(uint usage)
+{
+   uint resource_usage = 0;
+
+   if (usage & GBM_BO_USE_SCANOUT)
+      resource_usage |= PIPE_BIND_SCANOUT;
+
+   if (usage & GBM_BO_USE_RENDERING)
+      resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+
+   if (usage & GBM_BO_USE_CURSOR_64X64)
+      resource_usage |= PIPE_BIND_CURSOR;
+
+   return resource_usage;
+}
+
+static int
+gbm_gallium_drm_is_format_supported(struct gbm_device *gbm,
+                                    enum gbm_bo_format format,
+                                    uint32_t usage)
+{
+   struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+   enum pipe_format pf;
+
+   pf = gbm_format_to_gallium(format);
+   if (pf == PIPE_FORMAT_NONE)
+      return 0;
+
+   if (!gdrm->screen->is_format_supported(gdrm->screen, PIPE_TEXTURE_2D, pf, 0,
+                                          gbm_usage_to_gallium(usage)))
+      return 0;
+
+   if (usage & GBM_BO_USE_SCANOUT && format != GBM_BO_FORMAT_XRGB8888)
+      return 0;
+
+   return 1;
+}
+
+static void
+gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo)
+{
+   struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo);
+
+   pipe_resource_reference(&bo->resource, NULL);
+   free(bo);
+}
+
+static struct gbm_bo *
+gbm_gallium_drm_bo_create_from_egl_image(struct gbm_device *gbm,
+                                         void *egl_dpy, void *egl_image,
+                                         uint32_t width, uint32_t height)
+{
+   struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+   struct gbm_gallium_drm_bo *bo;
+   struct winsys_handle whandle;
+
+   if (!gdrm->lookup_egl_image)
+      return NULL;
+
+   bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
+   if (bo == NULL)
+      return NULL;
+
+   bo->resource = gdrm->lookup_egl_image(gdrm->lookup_egl_image_data,
+                                         egl_image);
+   if (bo->resource == NULL) {
+      FREE(bo);
+      return NULL;
+   }
+
+   bo->base.base.gbm = gbm;
+   bo->base.base.width = width;
+   bo->base.base.height = height;
+
+   memset(&whandle, 0, sizeof(whandle));
+   whandle.type = DRM_API_HANDLE_TYPE_KMS;
+   gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
+
+   bo->base.base.handle.u32 = whandle.handle;
+   bo->base.base.pitch      = whandle.stride;
+
+   return &bo->base.base;
+}
+
+static struct gbm_bo *
+gbm_gallium_drm_bo_create(struct gbm_device *gbm,
+                          uint32_t width, uint32_t height,
+                          enum gbm_bo_format format, uint32_t usage)
+{
+   struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+   struct gbm_gallium_drm_bo *bo;
+   struct pipe_resource templ;
+   struct winsys_handle whandle;
+   enum pipe_format pf;
+
+   bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
+   if (bo == NULL)
+      return NULL;
+
+   bo->base.base.gbm = gbm;
+   bo->base.base.width = width;
+   bo->base.base.height = height;
+
+   pf = gbm_format_to_gallium(format);
+   if (pf == PIPE_FORMAT_NONE)
+      return NULL;
+
+   memset(&templ, 0, sizeof(templ));
+   templ.bind = gbm_usage_to_gallium(usage);
+   templ.format = pf;
+   templ.target = PIPE_TEXTURE_2D;
+   templ.last_level = 0;
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
+   templ.array_size = 1;
+
+   bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ);
+   if (bo->resource == NULL) {
+      FREE(bo);
+      return NULL;
+   }
+
+   memset(&whandle, 0, sizeof(whandle));
+   whandle.type = DRM_API_HANDLE_TYPE_KMS;
+   gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
+
+   bo->base.base.handle.u32 = whandle.handle;
+   bo->base.base.pitch      = whandle.stride;
+
+   return &bo->base.base;
+}
+
+static void
+gbm_gallium_drm_destroy(struct gbm_device *gbm)
+{
+   struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+
+   gdrm->screen->destroy(gdrm->screen);
+
+   FREE(gdrm->base.driver_name);
+
+   FREE(gdrm);
+}
+
+struct gbm_device *
+gbm_gallium_drm_device_create(int fd)
+{
+   struct gbm_gallium_drm_device *gdrm;
+   int ret;
+
+   gdrm = calloc(1, sizeof *gdrm);
+
+   gdrm->base.base.fd = fd;
+   gdrm->base.base.bo_create = gbm_gallium_drm_bo_create;
+   gdrm->base.base.bo_create_from_egl_image =
+      gbm_gallium_drm_bo_create_from_egl_image;
+   gdrm->base.base.bo_destroy = gbm_gallium_drm_bo_destroy;
+   gdrm->base.base.is_format_supported = gbm_gallium_drm_is_format_supported;
+   gdrm->base.base.destroy = gbm_gallium_drm_destroy;
+
+   gdrm->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM;
+   gdrm->base.base.name = "drm";
+
+   ret = gallium_screen_create(gdrm);
+   if (ret) {
+      free(gdrm);
+      return NULL;
+   }
+
+   return &gdrm->base.base;
+}
diff --git a/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h b/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h
new file mode 100644
index 0000000..6277b8d
--- /dev/null
+++ b/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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:
+ *    Benjamin Franzke <benjaminfranzke at googlemail.com>
+ */
+
+#ifndef _GBM_GALLIUM_DRMINT_H_
+#define _GBM_GALLIUM_DRMINT_H_
+
+#include "pipe/p_state.h"
+
+#include "gbmint.h"
+
+#include "common.h"
+#include "common_drm.h"
+
+struct gbm_gallium_drm_device {
+   struct gbm_drm_device base;
+
+   struct pipe_screen *screen;
+   void *driver;
+
+   struct pipe_resource *(*lookup_egl_image)(void *data,
+                                             void *egl_image);
+   void *lookup_egl_image_data;
+
+};
+
+struct gbm_gallium_drm_bo {
+   struct gbm_drm_bo base;
+
+   struct pipe_resource *resource;
+};
+
+static inline struct gbm_gallium_drm_device *
+gbm_gallium_drm_device(struct gbm_device *gbm)
+{
+   return (struct gbm_gallium_drm_device *) gbm;
+}
+
+static inline struct gbm_gallium_drm_bo *
+gbm_gallium_drm_bo(struct gbm_bo *bo)
+{
+   return (struct gbm_gallium_drm_bo *) bo;
+}
+
+struct gbm_device *
+gbm_gallium_drm_device_create(int fd);
+
+int
+gallium_screen_create(struct gbm_gallium_drm_device *gdrm);
+
+#endif
diff --git a/src/gallium/targets/gbm/Makefile b/src/gallium/targets/gbm/Makefile
new file mode 100644
index 0000000..74a0232
--- /dev/null
+++ b/src/gallium/targets/gbm/Makefile
@@ -0,0 +1,32 @@
+# src/gallium/targets/gbm/Makefile
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+PIPE_PREFIX := pipe_
+
+GBM_BACKEND = gbm_gallium_drm
+GBM_SOURCES = gbm.c pipe_loader.c
+
+GBM_INCLUDES = \
+	       -I$(TOP)/include \
+	       -I$(TOP)/src/gallium/state_trackers/gbm \
+	       -I$(TOP)/src/gbm/main \
+	       -I$(TOP)/src/gallium/auxiliary \
+	       -I$(TOP)/src/gallium/include \
+
+GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) \
+	   $(TOP)/src/gallium/state_trackers/gbm/libgbm.a \
+	   $(TOP)/src/gallium/drivers/identity/libidentity.a \
+	   $(TOP)/src/gallium/drivers/trace/libtrace.a \
+	   $(TOP)/src/gallium/drivers/rbug/librbug.a \
+	   $(GALLIUM_AUXILIARIES)
+
+
+GBM_CFLAGS = \
+	     -D_EGL_GALLIUM_DRIVER_SEARCH_DIR=\"$(EGL_DRIVER_INSTALL_DIR)\" \
+	     -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" \
+	     $(LIBUDEV_CFLAGS) \
+	     $(LIBDRM_CFLAGS)  
+
+include $(TOP)/src/gbm/backends/Makefile.template
diff --git a/src/gallium/targets/gbm/gbm.c b/src/gallium/targets/gbm/gbm.c
new file mode 100644
index 0000000..e840fc5
--- /dev/null
+++ b/src/gallium/targets/gbm/gbm.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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:
+ *    Benjamin Franzke <benjaminfranzke at googlemail.com>
+ */
+
+#include "util/u_inlines.h"
+
+#include "gbm_gallium_drmint.h"
+#include "pipe_loader.h"
+
+static struct pipe_screen *
+create_drm_screen(const char *name, int fd)
+{
+   struct pipe_module *pmod = get_pipe_module(name);
+ 
+   return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ?
+      pmod->drmdd->create_screen(fd) : NULL;
+}
+
+int
+gallium_screen_create(struct gbm_gallium_drm_device *gdrm)
+{
+   gdrm->base.driver_name = drm_fd_get_screen_name(gdrm->base.base.fd);
+   if (gdrm->base.driver_name == NULL)
+      return -1;
+
+   gdrm->screen = create_drm_screen(gdrm->base.driver_name, gdrm->base.base.fd);
+   if (gdrm->screen == NULL) {
+      debug_printf("failed to load driver: %s\n", gdrm->base.driver_name);
+      return -1;
+   };
+
+   return 0;
+}
+
+GBM_EXPORT struct gbm_backend gbm_backend = {
+   .backend_name = "gallium_drm",
+   .create_device = gbm_gallium_drm_device_create,
+};
diff --git a/src/gallium/targets/gbm/pipe_loader.c b/src/gallium/targets/gbm/pipe_loader.c
new file mode 100644
index 0000000..472614c
--- /dev/null
+++ b/src/gallium/targets/gbm/pipe_loader.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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 <stdio.h>
+#include "util/u_string.h"
+#include "util/u_memory.h"
+
+#include <libudev.h>
+
+#include "gbm_gallium_drmint.h"
+#include "pipe_loader.h"
+#define DRIVER_MAP_GALLIUM_ONLY
+#include "pci_ids/pci_id_driver_map.h"
+
+static struct pipe_module pipe_modules[16];
+
+static INLINE char *
+loader_strdup(const char *str)
+{
+   return mem_dup(str, strlen(str) + 1);
+}
+
+char *
+drm_fd_get_screen_name(int fd)
+{
+   struct udev *udev;
+   struct udev_device *device, *parent;
+   const char *pci_id;
+   char *driver = NULL;
+   int vendor_id, chip_id, i, j;
+
+   udev = udev_new();
+   device = _gbm_udev_device_new_from_fd(udev, fd);
+   if (device == NULL)
+      return NULL;
+
+   parent = udev_device_get_parent(device);
+   if (parent == NULL) {
+      fprintf(stderr, "gbm: could not get parent device");
+      goto out;
+   }
+
+   pci_id = udev_device_get_property_value(parent, "PCI_ID");
+   if (pci_id == NULL ||
+       sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
+      fprintf(stderr, "gbm: malformed or no PCI ID");
+      goto out;
+   }
+
+   for (i = 0; driver_map[i].driver; i++) {
+      if (vendor_id != driver_map[i].vendor_id)
+         continue;
+      if (driver_map[i].num_chips_ids == -1) {
+         driver = loader_strdup(driver_map[i].driver);
+         _gbm_log("pci id for %d: %04x:%04x, driver %s",
+                  fd, vendor_id, chip_id, driver);
+         goto out;
+      }
+
+      for (j = 0; j < driver_map[i].num_chips_ids; j++)
+         if (driver_map[i].chip_ids[j] == chip_id) {
+            driver = loader_strdup(driver_map[i].driver);
+            _gbm_log("pci id for %d: %04x:%04x, driver %s",
+                     fd, vendor_id, chip_id, driver);
+            goto out;
+         }
+   }
+
+out:
+   udev_device_unref(device);
+   udev_unref(udev);
+
+   return driver;
+}
+
+static void
+find_pipe_module(struct pipe_module *pmod, const char *name)
+{
+   char *search_paths, *end, *next, *p;
+   char path[PATH_MAX];
+   int ret;
+   
+   search_paths = NULL;
+   if (geteuid() == getuid()) {
+      /* don't allow setuid apps to use EGL_DRIVERS_PATH */
+      search_paths = getenv("EGL_DRIVERS_PATH");
+   }
+   if (search_paths == NULL)
+      search_paths = _EGL_GALLIUM_DRIVER_SEARCH_DIR;
+
+   end = search_paths + strlen(search_paths);
+   for (p = search_paths; p < end && pmod->lib == NULL; p = next + 1) {
+      int len;
+      next = strchr(p, ':');
+      if (next == NULL)
+         next = end;
+
+      len = next - p;
+
+      if (len) {
+         ret = util_snprintf(path, sizeof(path),
+                             "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, p, 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);
+         debug_printf("loaded %s\n", path);
+      }
+
+   }
+}
+
+static boolean
+load_pipe_module(struct pipe_module *pmod, const char *name)
+{
+   pmod->name = loader_strdup(name);
+   if (!pmod->name)
+      return FALSE;
+
+   find_pipe_module(pmod, name);
+
+   if (pmod->lib) {
+      pmod->drmdd = (const struct drm_driver_descriptor *)
+         util_dl_get_proc_address(pmod->lib, "driver_descriptor");
+
+      /* sanity check on the name */
+      if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0)
+         pmod->drmdd = NULL;
+
+      if (!pmod->drmdd) {
+         util_dl_close(pmod->lib);
+         pmod->lib = NULL;
+      }
+   }
+
+   return (pmod->drmdd != NULL);
+}
+
+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;
+}
diff --git a/src/gallium/targets/gbm/pipe_loader.h b/src/gallium/targets/gbm/pipe_loader.h
new file mode 100644
index 0000000..2e4cd99
--- /dev/null
+++ b/src/gallium/targets/gbm/pipe_loader.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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:
+ *    Benjamin Franzke <benjaminfranzke at googlemail.com>
+ */
+
+#ifndef _PIPE_LOADER_H_
+#define _PIPE_LOADER_H_
+
+#include "pipe/p_compiler.h"
+#include "util/u_dl.h"
+#include "state_tracker/drm_driver.h"
+
+struct pipe_module {
+   boolean initialized;
+   char *name;
+   struct util_dl_library *lib;
+   const struct drm_driver_descriptor *drmdd;
+};
+
+struct pipe_module *
+get_pipe_module(const char *name);
+
+char *
+drm_fd_get_screen_name(int fd);
+
+#endif
diff --git a/src/gbm/main/backend.c b/src/gbm/main/backend.c
index 84db9e8..aceb662 100644
--- a/src/gbm/main/backend.c
+++ b/src/gbm/main/backend.c
@@ -45,6 +45,7 @@ struct backend_desc {
 
 static const struct backend_desc backends[] = {
    { "gbm_dri.so", &gbm_dri_backend },
+   { "gbm_gallium_drm.so", NULL },
 };
 
 static const void *
-- 
1.7.3.4



More information about the mesa-dev mailing list