[Mesa-dev] [PATCH 1/2] loader: refactor duplicated code into loader util lib
Rob Clark
robdclark at gmail.com
Sat Dec 14 11:28:32 PST 2013
From: Rob Clark <robclark at freedesktop.org>
All the various window system integration layers duplicate roughly the
same code for figuring out device and driver name, pci-id's, etc. Which
is sad. So extract it out into a loader util lib.
Signed-off-by: Rob Clark <robclark at freedesktop.org>
---
configure.ac | 1 +
include/pci_ids/pci_id_driver_map.h | 29 ++-
src/Makefile.am | 2 +-
src/egl/drivers/dri2/Makefile.am | 5 +-
src/egl/drivers/dri2/common.c | 144 -----------
src/egl/drivers/dri2/egl_dri2.h | 5 -
src/egl/drivers/dri2/platform_android.c | 105 +-------
src/egl/drivers/dri2/platform_drm.c | 5 +-
src/egl/drivers/dri2/platform_wayland.c | 5 +-
src/gallium/auxiliary/pipe-loader/Makefile.am | 4 +
src/gallium/auxiliary/pipe-loader/pipe_loader.h | 1 +
.../auxiliary/pipe-loader/pipe_loader_drm.c | 92 +------
src/gallium/state_trackers/clover/core/device.cpp | 2 +
src/gallium/targets/egl-static/Makefile.am | 2 +
src/gallium/targets/egl-static/egl.c | 186 +--------------
src/gbm/Makefile.am | 10 +-
src/gbm/backends/dri/driver_name.c | 89 -------
src/gbm/backends/dri/gbm_dri.c | 3 +-
src/gbm/backends/dri/gbm_driint.h | 3 -
src/glx/dri3_common.c | 146 ------------
src/glx/dri3_glx.c | 3 +-
src/glx/dri3_priv.h | 3 -
src/loader/Makefile.am | 37 +++
src/loader/loader.c | 264 +++++++++++++++++++++
src/loader/loader.h | 57 +++++
25 files changed, 430 insertions(+), 773 deletions(-)
delete mode 100644 src/egl/drivers/dri2/common.c
delete mode 100644 src/gbm/backends/dri/driver_name.c
delete mode 100644 src/glx/dri3_common.c
create mode 100644 src/loader/Makefile.am
create mode 100644 src/loader/loader.c
create mode 100644 src/loader/loader.h
diff --git a/configure.ac b/configure.ac
index c14d39a..8f7e34b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2052,6 +2052,7 @@ AC_CONFIG_FILES([Makefile
src/glx/Makefile
src/glx/tests/Makefile
src/gtest/Makefile
+ src/loader/Makefile
src/mapi/Makefile
src/mapi/es1api/Makefile
src/mapi/es1api/glesv1_cm.pc
diff --git a/include/pci_ids/pci_id_driver_map.h b/include/pci_ids/pci_id_driver_map.h
index 8a97c6f..3ada357 100644
--- a/include/pci_ids/pci_id_driver_map.h
+++ b/include/pci_ids/pci_id_driver_map.h
@@ -3,10 +3,16 @@
#include <stddef.h>
+#include "loader.h"
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
+#ifndef __IS_LOADER
+# error "Only include from loader.c"
+#endif
+
static const int i915_chip_ids[] = {
#define CHIPSET(chip, desc, name) chip,
#include "pci_ids/i915_pci_ids.h"
@@ -19,7 +25,6 @@ static const int i965_chip_ids[] = {
#undef CHIPSET
};
-#ifndef DRIVER_MAP_GALLIUM_ONLY
static const int r100_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/radeon_pci_ids.h"
@@ -31,7 +36,6 @@ static const int r200_chip_ids[] = {
#include "pci_ids/r200_pci_ids.h"
#undef CHIPSET
};
-#endif
static const int r300_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
@@ -62,18 +66,17 @@ static const struct {
const char *driver;
const int *chip_ids;
int num_chips_ids;
+ unsigned driver_types;
} driver_map[] = {
- { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids) },
- { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids) },
-#ifndef DRIVER_MAP_GALLIUM_ONLY
- { 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids) },
- { 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids) },
-#endif
- { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids) },
- { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) },
- { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids) },
- { 0x10de, "nouveau", NULL, -1 },
- { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) },
+ { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids), _LOADER_DRI | _LOADER_GALLIUM },
+ { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids), _LOADER_DRI | _LOADER_GALLIUM },
+ { 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids), _LOADER_DRI },
+ { 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids), _LOADER_DRI },
+ { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids), _LOADER_GALLIUM },
+ { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids), _LOADER_GALLIUM },
+ { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids), _LOADER_GALLIUM},
+ { 0x10de, "nouveau", NULL, -1, _LOADER_GALLIUM },
+ { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids), _LOADER_GALLIUM },
{ 0x0000, NULL, NULL, 0 },
};
diff --git a/src/Makefile.am b/src/Makefile.am
index 76280a0..5b2549d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,7 +19,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-SUBDIRS = gtest mapi
+SUBDIRS = gtest loader mapi
if NEED_OPENGL_COMMON
SUBDIRS += glsl mesa
diff --git a/src/egl/drivers/dri2/Makefile.am b/src/egl/drivers/dri2/Makefile.am
index 823ef5e..6a9ae50 100644
--- a/src/egl/drivers/dri2/Makefile.am
+++ b/src/egl/drivers/dri2/Makefile.am
@@ -22,6 +22,7 @@
AM_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/egl/main \
+ -I$(top_srcdir)/src/loader \
-I$(top_srcdir)/src/gbm/main \
-I$(top_srcdir)/src/gbm/backends/dri \
-I$(top_srcdir)/src/egl/wayland/wayland-egl \
@@ -37,10 +38,10 @@ AM_CFLAGS = \
noinst_LTLIBRARIES = libegl_dri2.la
libegl_dri2_la_SOURCES = \
- egl_dri2.c \
- common.c
+ egl_dri2.c
libegl_dri2_la_LIBADD = \
+ $(top_builddir)/src/loader/libloader.la \
$(EGL_LIB_DEPS)
if HAVE_SHARED_GLAPI
diff --git a/src/egl/drivers/dri2/common.c b/src/egl/drivers/dri2/common.c
deleted file mode 100644
index a889484..0000000
--- a/src/egl/drivers/dri2/common.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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 <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "egl_dri2.h"
-
-#ifdef HAVE_LIBUDEV
-
-#define DRIVER_MAP_DRI2_ONLY
-#include "pci_ids/pci_id_driver_map.h"
-
-#include <libudev.h>
-
-static struct udev_device *
-dri2_udev_device_new_from_fd(struct udev *udev, int fd)
-{
- struct udev_device *device;
- struct stat buf;
-
- if (fstat(fd, &buf) < 0) {
- _eglLog(_EGL_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
- return NULL;
- }
-
- device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
- if (device == NULL) {
- _eglLog(_EGL_WARNING,
- "EGL-DRI2: could not create udev device for fd %d", fd);
- return NULL;
- }
-
- return device;
-}
-
-char *
-dri2_get_device_name_for_fd(int fd)
-{
- struct udev *udev;
- struct udev_device *device;
- const char *const_device_name;
- char *device_name = NULL;
-
- udev = udev_new();
- device = dri2_udev_device_new_from_fd(udev, fd);
- if (device == NULL)
- return NULL;
-
- const_device_name = udev_device_get_devnode(device);
- if (!const_device_name)
- goto out;
- device_name = strdup(const_device_name);
-
-out:
- udev_device_unref(device);
- udev_unref(udev);
-
- return device_name;
-}
-
-char *
-dri2_get_driver_for_fd(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 = dri2_udev_device_new_from_fd(udev, fd);
- if (device == NULL)
- return NULL;
-
- parent = udev_device_get_parent(device);
- if (parent == NULL) {
- _eglLog(_EGL_WARNING, "DRI2: 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) {
- _eglLog(_EGL_WARNING, "EGL-DRI2: 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 = strdup(driver_map[i].driver);
- _eglLog(_EGL_DEBUG, "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 = strdup(driver_map[i].driver);
- _eglLog(_EGL_DEBUG, "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;
-}
-
-#endif /* HAVE_LIBUDEV */
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index d29dd98..dfc5927 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -271,9 +271,4 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp);
EGLBoolean
dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp);
-char *
-dri2_get_driver_for_fd(int fd);
-char *
-dri2_get_device_name_for_fd(int fd);
-
#endif /* EGL_DRI2_INCLUDED */
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 2c20de7..de147ad 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -34,11 +34,7 @@
#include <sync/sync.h>
#endif
-/* for droid_get_pci_id */
-#include <xf86drm.h>
-#include <i915_drm.h>
-#include <radeon_drm.h>
-
+#include "loader.h"
#include "egl_dri2.h"
#include "gralloc_drm.h"
@@ -602,103 +598,6 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
return (count != 0);
}
-static EGLBoolean
-droid_get_pci_id(int fd, int *vendor_id, int *chip_id)
-{
- drmVersionPtr version;
-
- *chip_id = -1;
-
- version = drmGetVersion(fd);
- if (!version) {
- _eglLog(_EGL_WARNING, "invalid drm fd");
- return EGL_FALSE;
- }
- if (!version->name) {
- _eglLog(_EGL_WARNING, "unable to determine the driver name");
- drmFreeVersion(version);
- return EGL_FALSE;
- }
-
- if (strcmp(version->name, "i915") == 0) {
- struct drm_i915_getparam gp;
- int ret;
-
- *vendor_id = 0x8086;
-
- memset(&gp, 0, sizeof(gp));
- gp.param = I915_PARAM_CHIPSET_ID;
- gp.value = chip_id;
- ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
- if (ret) {
- _eglLog(_EGL_WARNING, "failed to get param for i915");
- *chip_id = -1;
- }
- }
- else if (strcmp(version->name, "radeon") == 0) {
- struct drm_radeon_info info;
- int ret;
-
- *vendor_id = 0x1002;
-
- memset(&info, 0, sizeof(info));
- info.request = RADEON_INFO_DEVICE_ID;
- info.value = (unsigned long) chip_id;
- ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
- if (ret) {
- _eglLog(_EGL_WARNING, "failed to get info for radeon");
- *chip_id = -1;
- }
- }
- else if (strcmp(version->name, "nouveau") == 0) {
- *vendor_id = 0x10de;
- /* not used */
- *chip_id = 0;
- }
- else if (strcmp(version->name, "vmwgfx") == 0) {
- *vendor_id = 0x15ad;
- /* assume SVGA II */
- *chip_id = 0x0405;
- }
-
- drmFreeVersion(version);
-
- return (*chip_id >= 0);
-}
-
-#define DRIVER_MAP_DRI2_ONLY
-#include "pci_ids/pci_id_driver_map.h"
-static const char *
-droid_get_driver_name(int fd)
-{
- int vendor_id = -1, chip_id = -1;
- int idx, i;
- char *name;
-
- if (!droid_get_pci_id(fd, &vendor_id, &chip_id))
- return NULL;
-
- for (idx = 0; driver_map[idx].driver; idx++) {
- if (vendor_id != driver_map[idx].vendor_id)
- continue;
-
- if (driver_map[idx].num_chips_ids == -1)
- break;
-
- for (i = 0; i < driver_map[idx].num_chips_ids; i++) {
- if (driver_map[idx].chip_ids[i] == chip_id)
- break;
- }
- if (i < driver_map[idx].num_chips_ids)
- break;
- }
-
- _eglLog(_EGL_INFO, "pci id for fd %d: %04x:%04x, driver %s",
- fd, vendor_id, chip_id, driver_map[idx].driver);
-
- return driver_map[idx].driver;
-}
-
static int
droid_open_device(void)
{
@@ -773,7 +672,7 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy)
goto cleanup_display;
}
- dri2_dpy->driver_name = (char *) droid_get_driver_name(dri2_dpy->fd);
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
if (dri2_dpy->driver_name == NULL) {
err = "DRI2: failed to get driver name";
goto cleanup_device;
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 181b29d..a2b387d 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -36,6 +36,7 @@
#include <unistd.h>
#include "egl_dri2.h"
+#include "loader.h"
static struct gbm_bo *
lock_front_buffer(struct gbm_surface *_surf)
@@ -447,6 +448,8 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
int fd = -1;
int i;
+ loader_set_logger(_eglLog);
+
dri2_dpy = calloc(1, sizeof *dri2_dpy);
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
@@ -482,7 +485,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
}
dri2_dpy->fd = fd;
- dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
+ dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name;
dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen;
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 5c8440d..50750a9 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -36,6 +36,7 @@
#include <xf86drm.h>
#include "egl_dri2.h"
+#include "loader.h"
#include <wayland-client.h>
#include "wayland-drm-client-protocol.h"
@@ -962,6 +963,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 };
static const unsigned int rgb565_masks[4] = { 0xf800, 0x07e0, 0x001f, 0 };
+ loader_set_logger(_eglLog);
+
drv->API.CreateWindowSurface = dri2_create_window_surface;
drv->API.DestroySurface = dri2_destroy_surface;
drv->API.SwapBuffers = dri2_swap_buffers;
@@ -1006,7 +1009,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
if (roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated)
goto cleanup_fd;
- dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
if (dri2_dpy->driver_name == NULL) {
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
goto cleanup_fd;
diff --git a/src/gallium/auxiliary/pipe-loader/Makefile.am b/src/gallium/auxiliary/pipe-loader/Makefile.am
index 9a8094f..7e89ea7 100644
--- a/src/gallium/auxiliary/pipe-loader/Makefile.am
+++ b/src/gallium/auxiliary/pipe-loader/Makefile.am
@@ -3,6 +3,7 @@ AUTOMAKE_OPTIONS = subdir-objects
AM_CPPFLAGS = $(DEFINES) \
$(GALLIUM_PIPE_LOADER_DEFINES) \
-I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/loader \
-I$(top_srcdir)/src/gallium/include \
-I$(top_srcdir)/src/gallium/auxiliary \
-I$(top_srcdir)/src/gallium/winsys
@@ -12,6 +13,9 @@ noinst_LTLIBRARIES =
if HAVE_LOADER_GALLIUM
noinst_LTLIBRARIES += libpipe_loader.la
+libpipe_loader_la_LIBADD = \
+ $(top_builddir)/src/loader/libloader.la
+
libpipe_loader_la_SOURCES = \
pipe_loader.h \
pipe_loader_priv.h \
diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader.h b/src/gallium/auxiliary/pipe-loader/pipe_loader.h
index 444bdf1..e915c63 100644
--- a/src/gallium/auxiliary/pipe-loader/pipe_loader.h
+++ b/src/gallium/auxiliary/pipe-loader/pipe_loader.h
@@ -44,6 +44,7 @@ struct pipe_screen;
enum pipe_loader_device_type {
PIPE_LOADER_DEVICE_SOFTWARE,
PIPE_LOADER_DEVICE_PCI,
+ PIPE_LOADER_DEVICE_PLATFORM,
NUM_PIPE_LOADER_DEVICE_TYPES
};
diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
index 927fb24..fda0ab1 100644
--- a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
+++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
@@ -48,8 +48,7 @@
#include "util/u_dl.h"
#include "util/u_debug.h"
-#define DRIVER_MAP_GALLIUM_ONLY
-#include "pci_ids/pci_id_driver_map.h"
+#include "loader.h"
struct pipe_loader_drm_device {
struct pipe_loader_device base;
@@ -59,78 +58,6 @@ struct pipe_loader_drm_device {
#define pipe_loader_drm_device(dev) ((struct pipe_loader_drm_device *)dev)
-static boolean
-find_drm_pci_id(struct pipe_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.u.pci.vendor_id,
- &ddev->base.u.pci.chip_id) != 2)
- goto fail;
-
- udev_device_unref(device);
- udev_unref(udev);
-
- return TRUE;
-
- fail:
- if (device)
- udev_device_unref(device);
- if (udev)
- udev_unref(udev);
-
- return FALSE;
-}
-
-static boolean
-find_drm_driver_name(struct pipe_loader_drm_device *ddev)
-{
- struct pipe_loader_device *dev = &ddev->base;
- int i, j;
-
- for (i = 0; driver_map[i].driver; i++) {
- if (dev->u.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->u.pci.chip_id == driver_map[i].chip_ids[j]) {
- dev->driver_name = driver_map[i].driver;
- goto found;
- }
- }
- }
-
- return FALSE;
-
- found:
- return TRUE;
-}
-
static struct pipe_loader_ops pipe_loader_drm_ops;
static void
@@ -190,17 +117,22 @@ boolean
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
{
struct pipe_loader_drm_device *ddev = CALLOC_STRUCT(pipe_loader_drm_device);
-
- ddev->base.type = PIPE_LOADER_DEVICE_PCI;
+ int vendor_id, chip_id;
+
+ if (loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {
+ ddev->base.type = PIPE_LOADER_DEVICE_PCI;
+ ddev->base.u.pci.vendor_id = vendor_id;
+ ddev->base.u.pci.chip_id = chip_id;
+ } else {
+ ddev->base.type = PIPE_LOADER_DEVICE_PLATFORM;
+ }
ddev->base.ops = &pipe_loader_drm_ops;
ddev->fd = fd;
pipe_loader_drm_x_auth(fd);
- if (!find_drm_pci_id(ddev))
- goto fail;
-
- if (!find_drm_driver_name(ddev))
+ ddev->base.driver_name = loader_get_driver_for_fd(fd, _LOADER_GALLIUM);
+ if (!ddev->base.driver_name)
goto fail;
*dev = &ddev->base;
diff --git a/src/gallium/state_trackers/clover/core/device.cpp b/src/gallium/state_trackers/clover/core/device.cpp
index e5e429a..76a49d0 100644
--- a/src/gallium/state_trackers/clover/core/device.cpp
+++ b/src/gallium/state_trackers/clover/core/device.cpp
@@ -63,6 +63,7 @@ device::type() const {
case PIPE_LOADER_DEVICE_SOFTWARE:
return CL_DEVICE_TYPE_CPU;
case PIPE_LOADER_DEVICE_PCI:
+ case PIPE_LOADER_DEVICE_PLATFORM:
return CL_DEVICE_TYPE_GPU;
default:
assert(0);
@@ -74,6 +75,7 @@ cl_uint
device::vendor_id() const {
switch (ldev->type) {
case PIPE_LOADER_DEVICE_SOFTWARE:
+ case PIPE_LOADER_DEVICE_PLATFORM:
return 0;
case PIPE_LOADER_DEVICE_PCI:
return ldev->u.pci.vendor_id;
diff --git a/src/gallium/targets/egl-static/Makefile.am b/src/gallium/targets/egl-static/Makefile.am
index fdd5a1d..73bb795 100644
--- a/src/gallium/targets/egl-static/Makefile.am
+++ b/src/gallium/targets/egl-static/Makefile.am
@@ -36,6 +36,7 @@ AM_CFLAGS = $(PTHREAD_CFLAGS)
AM_CPPFLAGS = \
$(GALLIUM_CFLAGS) \
-I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/loader \
-I$(top_srcdir)/src/gallium/drivers \
-I$(top_srcdir)/src/gallium/winsys \
-I$(top_srcdir)/src/gallium/include \
@@ -60,6 +61,7 @@ egl_gallium_la_LIBADD = \
$(top_builddir)/src/gallium/drivers/rbug/librbug.la \
$(top_builddir)/src/gallium/state_trackers/egl/libegl.la \
$(top_builddir)/src/egl/main/libEGL.la \
+ $(top_builddir)/src/loader/libloader.la \
$(CLOCK_LIB) \
$(LIBUDEV_LIBS) \
$(DLOPEN_LIBS) \
diff --git a/src/gallium/targets/egl-static/egl.c b/src/gallium/targets/egl-static/egl.c
index 0b59bdb..7b515ef 100644
--- a/src/gallium/targets/egl-static/egl.c
+++ b/src/gallium/targets/egl-static/egl.c
@@ -28,14 +28,7 @@
#include "common/egl_g3d_loader.h"
#include "egldriver.h"
#include "egllog.h"
-
-#ifdef HAVE_LIBUDEV
-#include <stdio.h> /* for sscanf */
-#include <libudev.h>
-#endif
-
-#define DRIVER_MAP_GALLIUM_ONLY
-#include "pci_ids/pci_id_driver_map.h"
+#include "loader.h"
#include "egl_pipe.h"
#include "egl_st.h"
@@ -60,180 +53,14 @@ get_st_api(enum st_api_type api)
return stmod->stapi;
}
-#ifdef HAVE_LIBUDEV
-
-static boolean
-drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
-{
- struct udev *udev = NULL;
- struct udev_device *device = NULL, *parent;
- struct stat buf;
- const char *pci_id;
-
- *chip_id = -1;
-
- udev = udev_new();
- if (fstat(fd, &buf) < 0) {
- _eglLog(_EGL_WARNING, "failed to stat fd %d", fd);
- goto out;
- }
-
- device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
- if (device == NULL) {
- _eglLog(_EGL_WARNING,
- "could not create udev device for fd %d", fd);
- goto out;
- }
-
- parent = udev_device_get_parent(device);
- if (parent == NULL) {
- _eglLog(_EGL_WARNING, "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) {
- _eglLog(_EGL_WARNING, "malformed or no PCI ID");
- *chip_id = -1;
- goto out;
- }
-
-out:
- if (device)
- udev_device_unref(device);
- if (udev)
- udev_unref(udev);
-
- return (*chip_id >= 0);
-}
-
-#elif defined(PIPE_OS_ANDROID) && !defined(_EGL_NO_DRM)
-
-#include <xf86drm.h>
-/* for i915 */
-#include <i915_drm.h>
-/* for radeon */
-#include <radeon_drm.h>
-/* for util_strcmp */
-#include "util/u_string.h"
-
-static boolean
-drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
-{
- drmVersionPtr version;
-
- *chip_id = -1;
-
- version = drmGetVersion(fd);
- if (!version) {
- _eglLog(_EGL_WARNING, "invalid drm fd");
- return FALSE;
- }
- if (!version->name) {
- _eglLog(_EGL_WARNING, "unable to determine the driver name");
- drmFreeVersion(version);
- return FALSE;
- }
-
- if (util_strcmp(version->name, "i915") == 0) {
- struct drm_i915_getparam gp;
- int ret;
-
- *vendor_id = 0x8086;
-
- memset(&gp, 0, sizeof(gp));
- gp.param = I915_PARAM_CHIPSET_ID;
- gp.value = chip_id;
- ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
- if (ret) {
- _eglLog(_EGL_WARNING, "failed to get param for i915");
- *chip_id = -1;
- }
- }
- else if (util_strcmp(version->name, "radeon") == 0) {
- struct drm_radeon_info info;
- int ret;
-
- *vendor_id = 0x1002;
-
- memset(&info, 0, sizeof(info));
- info.request = RADEON_INFO_DEVICE_ID;
- info.value = (unsigned long) chip_id;
- ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
- if (ret) {
- _eglLog(_EGL_WARNING, "failed to get info for radeon");
- *chip_id = -1;
- }
- }
- else if (util_strcmp(version->name, "nouveau") == 0) {
- *vendor_id = 0x10de;
- /* not used */
- *chip_id = 0;
- }
- else if (util_strcmp(version->name, "vmwgfx") == 0) {
- *vendor_id = 0x15ad;
- /* assume SVGA II */
- *chip_id = 0x0405;
- }
-
- drmFreeVersion(version);
-
- return (*chip_id >= 0);
-}
-
-#else
-
-static boolean
-drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
-{
- return FALSE;
-}
-
-#endif /* HAVE_LIBUDEV */
-
-static const char *
-drm_fd_get_screen_name(int fd)
-{
- int vendor_id, chip_id;
- int idx, i;
-
- if (!drm_fd_get_pci_id(fd, &vendor_id, &chip_id)) {
- _eglLog(_EGL_WARNING, "failed to get driver name for fd %d", fd);
- return NULL;
- }
-
- for (idx = 0; driver_map[idx].driver; idx++) {
- if (vendor_id != driver_map[idx].vendor_id)
- continue;
-
- /* done if no chip id */
- if (driver_map[idx].num_chips_ids == -1)
- break;
-
- for (i = 0; i < driver_map[idx].num_chips_ids; i++) {
- if (driver_map[idx].chip_ids[i] == chip_id)
- break;
- }
- /* matched! */
- if (i < driver_map[idx].num_chips_ids)
- break;
- }
-
- _eglLog((driver_map[idx].driver) ? _EGL_INFO : _EGL_WARNING,
- "pci id for fd %d: %04x:%04x, driver %s",
- fd, vendor_id, chip_id, driver_map[idx].driver);
-
- return driver_map[idx].driver;
-}
-
static struct pipe_screen *
-create_drm_screen(const char *name, int fd)
+create_drm_screen(const char *constname, int fd)
{
struct pipe_screen *screen;
+ char *name = (char *)constname;
if (!name) {
- name = drm_fd_get_screen_name(fd);
+ name = loader_get_driver_for_fd(fd, _LOADER_GALLIUM);
if (!name)
return NULL;
}
@@ -244,6 +71,9 @@ create_drm_screen(const char *name, int fd)
else
_eglLog(_EGL_WARNING, "failed to create a pipe screen for %s", name);
+ if (name != constname)
+ free(name);
+
return screen;
}
@@ -265,6 +95,8 @@ loader_init(void)
egl_g3d_loader.create_drm_screen = create_drm_screen;
egl_g3d_loader.create_sw_screen = create_sw_screen;
+ loader_set_logger(_eglLog);
+
return &egl_g3d_loader;
}
diff --git a/src/gbm/Makefile.am b/src/gbm/Makefile.am
index 9b3fb0d..e7aa706 100644
--- a/src/gbm/Makefile.am
+++ b/src/gbm/Makefile.am
@@ -8,6 +8,7 @@ AM_CFLAGS = \
-DMODULEDIR='"$(libdir)/gbm"' \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/gbm/main \
+ -I$(top_srcdir)/src/loader \
$(LIBUDEV_CFLAGS) \
$(LIBKMS_CFLAGS) \
$(DLOPEN_CFLAGS) \
@@ -21,7 +22,11 @@ libgbm_la_SOURCES = \
main/backend.c \
main/common.c
libgbm_la_LDFLAGS = -version-info 1:0
-libgbm_la_LIBADD = $(LIBUDEV_LIBS) $(LIBKMS_LIBS) $(DLOPEN_LIBS)
+libgbm_la_LIBADD = \
+ $(top_builddir)/src/loader/libloader.la \
+ $(LIBUDEV_LIBS) \
+ $(LIBKMS_LIBS) \
+ $(DLOPEN_LIBS)
if HAVE_EGL_PLATFORM_WAYLAND
AM_CPPFLAGS = -DHAVE_WAYLAND_PLATFORM
@@ -32,8 +37,7 @@ endif
if HAVE_DRI
noinst_LTLIBRARIES = libgbm_dri.la
libgbm_dri_la_SOURCES = \
- backends/dri/gbm_dri.c \
- backends/dri/driver_name.c
+ backends/dri/gbm_dri.c
libgbm_dri_la_CFLAGS = \
$(AM_CFLAGS) \
diff --git a/src/gbm/backends/dri/driver_name.c b/src/gbm/backends/dri/driver_name.c
deleted file mode 100644
index 2ed209f..0000000
--- a/src/gbm/backends/dri/driver_name.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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 <string.h>
-
-#include <libudev.h>
-
-#include "gbm_driint.h"
-#define DRIVER_MAP_DRI2_ONLY
-#include "pci_ids/pci_id_driver_map.h"
-
-char *
-dri_fd_get_driver_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 = 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 = 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;
-}
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index b4b97ac..c13930c 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -44,6 +44,7 @@
#include "gbm_driint.h"
#include "gbmint.h"
+#include "loader.h"
/* For importing wl_buffer */
#if HAVE_WAYLAND_PLATFORM
@@ -270,7 +271,7 @@ dri_screen_create(struct gbm_dri_device *dri)
const __DRIextension **extensions;
int ret = 0;
- dri->base.driver_name = dri_fd_get_driver_name(dri->base.base.fd);
+ dri->base.driver_name = loader_get_driver_for_fd(dri->base.base.fd, 0);
if (dri->base.driver_name == NULL)
return -1;
diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
index fb303a3..c3a47ab 100644
--- a/src/gbm/backends/dri/gbm_driint.h
+++ b/src/gbm/backends/dri/gbm_driint.h
@@ -111,7 +111,4 @@ gbm_dri_surface(struct gbm_surface *surface)
return (struct gbm_dri_surface *) surface;
}
-char *
-dri_fd_get_driver_name(int fd);
-
#endif
diff --git a/src/glx/dri3_common.c b/src/glx/dri3_common.c
deleted file mode 100644
index c758f96..0000000
--- a/src/glx/dri3_common.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright © 2013 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-/*
- * This code is derived from src/egl/drivers/dri2/common.c which
- * carries the following copyright:
- *
- * 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 <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <GL/gl.h>
-#include "glapi.h"
-#include "glxclient.h"
-#include "xf86dri.h"
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include "xf86drm.h"
-#include "dri_common.h"
-#include "dri3_priv.h"
-
-#define DRIVER_MAP_DRI3_ONLY
-#include "pci_ids/pci_id_driver_map.h"
-
-#include <libudev.h>
-
-static struct udev_device *
-dri3_udev_device_new_from_fd(struct udev *udev, int fd)
-{
- struct udev_device *device;
- struct stat buf;
-
- if (fstat(fd, &buf) < 0) {
- ErrorMessageF("DRI3: failed to stat fd %d", fd);
- return NULL;
- }
-
- device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
- if (device == NULL) {
- ErrorMessageF("DRI3: could not create udev device for fd %d", fd);
- return NULL;
- }
-
- return device;
-}
-
-char *
-dri3_get_driver_for_fd(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 = dri3_udev_device_new_from_fd(udev, fd);
- if (device == NULL)
- return NULL;
-
- parent = udev_device_get_parent(device);
- if (parent == NULL) {
- ErrorMessageF("DRI3: 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) {
- ErrorMessageF("DRI3: 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 = strdup(driver_map[i].driver);
- goto out;
- }
-
- for (j = 0; j < driver_map[i].num_chips_ids; j++)
- if (driver_map[i].chip_ids[j] == chip_id) {
- driver = strdup(driver_map[i].driver);
- goto out;
- }
- }
-
-out:
- udev_device_unref(device);
- udev_unref(udev);
-
- return driver;
-}
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index b047cc8..0e4824b 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -78,6 +78,7 @@
#include "xf86drm.h"
#include "dri_common.h"
#include "dri3_priv.h"
+#include "loader.h"
static const struct glx_context_vtable dri3_context_vtable;
@@ -1582,7 +1583,7 @@ dri3_create_screen(int screen, struct glx_display * priv)
}
deviceName = NULL;
- driverName = dri3_get_driver_for_fd(psc->fd);
+ driverName = loader_get_driver_for_fd(psc->fd, 0);
if (!driverName) {
ErrorMessageF("No driver found\n");
goto handle_error;
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index c892800..833db29 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -204,6 +204,3 @@ struct dri3_drawable {
xcb_gcontext_t gc;
xcb_special_event_t *special_event;
};
-
-char *
-dri3_get_driver_for_fd(int fd);
diff --git a/src/loader/Makefile.am b/src/loader/Makefile.am
new file mode 100644
index 0000000..dc62164
--- /dev/null
+++ b/src/loader/Makefile.am
@@ -0,0 +1,37 @@
+ # Copyright © 2012 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.
+
+AUTOMAKE_OPTIONS = subdir-objects
+
+noinst_LTLIBRARIES = libloader.la
+
+libloader_la_CPPFLAGS = \
+ $(DEFINES) \
+ -I$(top_srcdir)/include \
+ $(LIBDRM_CFLAGS) \
+ $(LIBUDEV_LIBS)
+
+libloader_la_LIBADD = \
+ $(LIBDRM_LIBS) \
+ $(LIBUDEV_LIBS)
+
+libloader_la_SOURCES = loader.c
+
diff --git a/src/loader/loader.c b/src/loader/loader.c
new file mode 100644
index 0000000..3e69a59
--- /dev/null
+++ b/src/loader/loader.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2013 Rob Clark <robclark at freedesktop.org>
+ *
+ * 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:
+ * Rob Clark <robclark at freedesktop.org>
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include "loader.h"
+
+#include <xf86drm.h>
+
+#define __IS_LOADER
+#include "pci_ids/pci_id_driver_map.h"
+
+static void default_logger(int level, const char *fmt, ...)
+{
+ if (level >= _LOADER_WARNING) {
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ }
+}
+
+static void (*log)(int level, const char *fmt, ...) = default_logger;
+
+#ifdef HAVE_LIBUDEV
+#include <libudev.h>
+
+static inline struct udev_device *
+udev_device_new_from_fd(struct udev *udev, int fd)
+{
+ struct udev_device *device;
+ struct stat buf;
+
+ if (fstat(fd, &buf) < 0) {
+ log(_LOADER_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
+ return NULL;
+ }
+
+ device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+ if (device == NULL) {
+ log(_LOADER_WARNING,
+ "EGL-DRI2: could not create udev device for fd %d", fd);
+ return NULL;
+ }
+
+ return device;
+}
+
+int
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+{
+ struct udev *udev = NULL;
+ struct udev_device *device = NULL, *parent;
+ struct stat buf;
+ const char *pci_id;
+
+ *chip_id = -1;
+
+ udev = udev_new();
+ device = udev_device_new_from_fd(udev, fd);
+ if (!device)
+ goto out;
+
+ parent = udev_device_get_parent(device);
+ if (parent == NULL) {
+ log(_LOADER_WARNING, "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) {
+ log(_LOADER_WARNING, "malformed or no PCI ID");
+ *chip_id = -1;
+ goto out;
+ }
+
+out:
+ if (device)
+ udev_device_unref(device);
+ if (udev)
+ udev_unref(udev);
+
+ return (*chip_id >= 0);
+}
+
+#elif defined(PIPE_OS_ANDROID) && !defined(_EGL_NO_DRM)
+
+/* for i915 */
+#include <i915_drm.h>
+/* for radeon */
+#include <radeon_drm.h>
+
+int
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+{
+ drmVersionPtr version;
+
+ *chip_id = -1;
+
+ version = drmGetVersion(fd);
+ if (!version) {
+ log(_LOADER_WARNING, "invalid drm fd");
+ return FALSE;
+ }
+ if (!version->name) {
+ log(_LOADER_WARNING, "unable to determine the driver name");
+ drmFreeVersion(version);
+ return FALSE;
+ }
+
+ if (strcmp(version->name, "i915") == 0) {
+ struct drm_i915_getparam gp;
+ int ret;
+
+ *vendor_id = 0x8086;
+
+ memset(&gp, 0, sizeof(gp));
+ gp.param = I915_PARAM_CHIPSET_ID;
+ gp.value = chip_id;
+ ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
+ if (ret) {
+ log(_LOADER_WARNING, "failed to get param for i915");
+ *chip_id = -1;
+ }
+ }
+ else if (strcmp(version->name, "radeon") == 0) {
+ struct drm_radeon_info info;
+ int ret;
+
+ *vendor_id = 0x1002;
+
+ memset(&info, 0, sizeof(info));
+ info.request = RADEON_INFO_DEVICE_ID;
+ info.value = (unsigned long) chip_id;
+ ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+ if (ret) {
+ log(_LOADER_WARNING, "failed to get info for radeon");
+ *chip_id = -1;
+ }
+ }
+ else if (strcmp(version->name, "nouveau") == 0) {
+ *vendor_id = 0x10de;
+ /* not used */
+ *chip_id = 0;
+ }
+ else if (strcmp(version->name, "vmwgfx") == 0) {
+ *vendor_id = 0x15ad;
+ /* assume SVGA II */
+ *chip_id = 0x0405;
+ }
+
+ drmFreeVersion(version);
+
+ return (*chip_id >= 0);
+}
+
+#else
+
+int
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
+{
+ return 0;
+}
+
+#endif
+
+
+char *
+loader_get_device_name_for_fd(int fd)
+{
+ char *device_name = NULL;
+#ifdef HAVE_LIBUDEV
+ struct udev *udev;
+ struct udev_device *device;
+ const char *const_device_name;
+
+ udev = udev_new();
+ device = udev_device_new_from_fd(udev, fd);
+ if (device == NULL)
+ return NULL;
+
+ const_device_name = udev_device_get_devnode(device);
+ if (!const_device_name)
+ goto out;
+ device_name = strdup(const_device_name);
+
+out:
+ udev_device_unref(device);
+ udev_unref(udev);
+#endif
+ return device_name;
+}
+
+char *
+loader_get_driver_for_fd(int fd, unsigned driver_types)
+{
+ int vendor_id, chip_id, i, j;
+ char *driver = NULL;
+
+ if (!driver_types)
+ driver_types = _LOADER_GALLIUM | _LOADER_DRI;
+
+ if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {
+ log(_LOADER_WARNING, "failed to get driver name for fd %d", fd);
+ return NULL;
+ }
+
+ for (i = 0; driver_map[i].driver; i++) {
+ if (vendor_id != driver_map[i].vendor_id)
+ continue;
+
+ if (!(driver_types & driver_map[i].driver_types))
+ continue;
+
+ if (driver_map[i].num_chips_ids == -1) {
+ driver = strdup(driver_map[i].driver);
+ goto out;
+ }
+
+ for (j = 0; j < driver_map[i].num_chips_ids; j++)
+ if (driver_map[i].chip_ids[j] == chip_id) {
+ driver = strdup(driver_map[i].driver);
+ goto out;
+ }
+ }
+
+out:
+ log(driver ? _LOADER_INFO : _LOADER_WARNING,
+ "pci id for fd %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ return driver;
+}
+
+void
+loader_set_logger(void (*logger)(int level, const char *fmt, ...))
+{
+ log = logger;
+}
diff --git a/src/loader/loader.h b/src/loader/loader.h
new file mode 100644
index 0000000..dfd77ba
--- /dev/null
+++ b/src/loader/loader.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 Rob Clark <robclark at freedesktop.org>
+ *
+ * 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:
+ * Rob Clark <robclark at freedesktop.org>
+ */
+
+#ifndef LOADER_H
+#define LOADER_H
+
+/* Helpers to figure out driver and device name, eg. from pci-id, etc. */
+
+#define _LOADER_DRI (1 << 0)
+#define _LOADER_GALLIUM (1 << 1)
+
+int
+loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id);
+
+char *
+loader_get_driver_for_fd(int fd, unsigned driver_types);
+
+char *
+loader_get_device_name_for_fd(int fd);
+
+
+/* for logging.. keep this aligned with egllog.h so we can just use
+ * _eglLog directly.
+ */
+
+#define _LOADER_FATAL 0 /* unrecoverable error */
+#define _LOADER_WARNING 1 /* recoverable error/problem */
+#define _LOADER_INFO 2 /* just useful info */
+#define _LOADER_DEBUG 3 /* useful info for debugging */
+
+void
+loader_set_logger(void (*logger)(int level, const char *fmt, ...));
+
+#endif /* LOADER_H */
--
1.8.4.2
More information about the mesa-dev
mailing list