summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@sasori.boston.redhat.com>2009-01-15 12:33:18 -0500
committerKristian Høgsberg <krh@sasori.boston.redhat.com>2009-01-15 12:33:18 -0500
commitb9139086d18011e99bab2617870430d67c7a0771 (patch)
tree5d915d54b70bf8ca9625cc55a46b69548a6062a6
parent28471dbfbb27495ac11f7475b8dbbadd85018a33 (diff)
Use libudev for figuring out which driver to load.
-rw-r--r--configure.ac2
-rw-r--r--eagle-internal.h6
-rw-r--r--eagle.c65
-rw-r--r--eagle.h6
-rw-r--r--intel.c16
-rw-r--r--test.c6
-rw-r--r--x11-dri2.c3
7 files changed, 91 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac
index 4895300..0243253 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ AC_PROG_CC
# FIXME: We should make the x11-dri2 backend optional
PKG_PROG_PKG_CONFIG()
-PKG_CHECK_MODULES(EAGLE, [libdrm dri x11 xfixes xext])
+PKG_CHECK_MODULES(EAGLE, [libdrm dri x11 xfixes xext libudev])
if test $CC = gcc; then
GCC_CFLAGS="-Wall -Wstrict-prototypes -Wmissing-prototypes"
diff --git a/eagle-internal.h b/eagle-internal.h
index ee29d81..c86efe5 100644
--- a/eagle-internal.h
+++ b/eagle-internal.h
@@ -94,8 +94,12 @@ struct EagleBackend {
EGLSurface surface);
};
-int eglInitDisplay(EGLDisplay display, const char *device, const char *driver);
+int eglInitDisplay(EGLDisplay display,
+ struct udev_device *device, const char *driver);
void eglInitSurface(EGLSurface surface, EGLDisplay display, EGLConfig fbconfig,
int width, int height);
+EGLDisplay i915CreateDisplay(struct udev_device *device);
+EGLDisplay i965CreateDisplay(struct udev_device *device);
+
#endif
diff --git a/eagle.c b/eagle.c
index 1a41550..989671d 100644
--- a/eagle.c
+++ b/eagle.c
@@ -34,6 +34,8 @@
#include "eagle.h"
#include "eagle-internal.h"
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof ((a)[0]))
+
/* FIXME: Use TLS. */
static EGLint lastError;
static EGLContext currentContext;
@@ -159,19 +161,23 @@ eglLoadDriver(EGLDisplay display, const char *driverName)
/* Should be eagleCreateDisplay to avoid invading egl namespace?/ */
int
-eglInitDisplay(EGLDisplay display, const char *device, const char *driver)
+eglInitDisplay(EGLDisplay display,
+ struct udev_device *device, const char *driver)
{
const __DRIconfig **configs;
const __DRIextension **extensions;
+ const char *path;
int i;
memset(display, 0, sizeof *display);
display->initialized = EGL_FALSE;
display->next_surface_id = 1;
- display->fd = open(device, O_RDWR);
+
+ path = udev_device_get_devnode(device);
+ display->fd = open(path, O_RDWR);
if (display->fd < 0) {
fprintf(stderr,
- "failed to open drm device %s: %m\n", device);
+ "failed to open drm device %s: %m\n", path);
return -1;
}
@@ -217,6 +223,57 @@ eglInitDisplay(EGLDisplay display, const char *device, const char *driver)
return -1;
}
+static const char *
+get_udev_property(struct udev_device *device, const char *name)
+{
+ struct udev_list_entry *entry;
+
+ udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(device))
+ if (strcmp(udev_list_entry_get_name(entry), name) == 0)
+ return udev_list_entry_get_value(entry);
+
+ return NULL;
+}
+
+struct dri_driver_entry {
+ uint32_t vendor_id;
+ uint32_t chip_id;
+ EGLDisplay (*createDisplay)(struct udev_device *device);
+};
+
+static const struct dri_driver_entry driver_map[] = {
+ /* FIXME: We need to extract this table from the dri drivers
+ * and store it on disk. For now, map my i965 to i965,
+ * anything else intel to i915 and that's that. */
+
+ { 0x8086, 0x2a02, i965CreateDisplay },
+ { 0x8086, ~0, i915CreateDisplay },
+ { 0, }
+};
+
+EGLDisplay
+eglCreateDisplayNative(struct udev_device *device)
+{
+ struct udev_device *parent;
+ const char *pci_id;
+ uint32_t vendor_id, chip_id;
+ int i;
+
+ parent = udev_device_get_parent(device);
+ pci_id = get_udev_property(parent, "PCI_ID");
+ if (sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2)
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
+ if (driver_map[i].vendor_id == vendor_id &&
+ (driver_map[i].chip_id == ~0 || driver_map[i].chip_id == chip_id))
+ return driver_map[i].createDisplay(device);
+ }
+
+ return NULL;
+}
+
+
int
eglGetDisplayFD(EGLDisplay display)
{
@@ -309,8 +366,6 @@ static struct { int egl_attrib, dri_attrib; } attrib_map[] = {
{ EGL_TRANSPARENT_BLUE_VALUE, __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE },
};
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof ((a)[0]))
-
static EGLBoolean
attributeMatches(EGLDisplay display,
EGLConfig config, EGLint attribute, EGLint value)
diff --git a/eagle.h b/eagle.h
index f6c8ce6..cd8ecab 100644
--- a/eagle.h
+++ b/eagle.h
@@ -23,6 +23,9 @@
#ifndef _EAGLE_H_
#define _EAGLE_H_
+#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
+#include <libudev.h>
+
typedef int EGLBoolean;
typedef int EGLint;
typedef struct EGLDisplay *EGLDisplay;
@@ -190,8 +193,7 @@ typedef int EGLenum; /* FIXME: is this part of EGL? */
extern EGLint eglGetError(void);
-extern EGLDisplay eglCreateDisplayNative(const char *device,
- const char *driver);
+extern EGLDisplay eglCreateDisplayNative(struct udev_device *device);
extern EGLSurface eglCreateSurfaceNative(EGLDisplay display,
EGLConfig config,
int x, int y, int width, int height);
diff --git a/intel.c b/intel.c
index ee2899e..a221420 100644
--- a/intel.c
+++ b/intel.c
@@ -272,8 +272,8 @@ nativeInitMemcpy(EGLDisplay display)
printf("Using memcpy swapbuffer\n");
}
-EGLDisplay
-eglCreateDisplayNative(const char *device, const char *driver)
+static EGLDisplay
+intelCreateDisplay(struct udev_device *device, const char *driver)
{
EGLDisplayNative nativeDisplay;
@@ -296,6 +296,18 @@ eglCreateDisplayNative(const char *device, const char *driver)
return &nativeDisplay->base;
}
+EGLDisplay
+i915CreateDisplay(struct udev_device *device)
+{
+ return intelCreateDisplay(device, "i915");
+}
+
+EGLDisplay
+i965CreateDisplay(struct udev_device *device)
+{
+ return intelCreateDisplay(device, "i965");
+}
+
EGLSurface
eglCreateSurfaceForName(EGLDisplay display, EGLConfig config,
uint32_t name, uint32_t width,
diff --git a/test.c b/test.c
index e8565ab..e3ba5c8 100644
--- a/test.c
+++ b/test.c
@@ -228,10 +228,14 @@ static void run_native(int x, int y, int width, int height)
EGLint major, minor;
uint32_t name;
int fb_width, fb_height, fb_stride;
+ struct udev *udev;
+ struct udev_device *device;
const static EGLint attribs[] =
{ EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
- display = eglCreateDisplayNative("/dev/dri/card0", "i965");
+ udev = udev_new();
+ device = udev_device_new_from_syspath(udev, "/sys/class/drm/card0");
+ display = eglCreateDisplayNative(device);
if (display == NULL)
die("failed to create display\n");
diff --git a/x11-dri2.c b/x11-dri2.c
index 3011198..0c6b4dd 100644
--- a/x11-dri2.c
+++ b/x11-dri2.c
@@ -132,7 +132,8 @@ eglCreateDisplayX11(Display *display, Window root)
x11Display->errorBase = errorBase;
x11Display->display = display;
- if (eglInitDisplay(&x11Display->base, deviceName, driverName) < 0) {
+ /* Get ude*/
+ if (eglInitDisplay(&x11Display->base, NULL, driverName) < 0) {
free(x11Display);
return NULL;
}