targets/egl: Support driver name lookup using pci lists
authorBenjamin Franzke <benjaminfranzke@googlemail.com>
Mon, 30 May 2011 07:55:14 +0000 (09:55 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 7 Jun 2011 14:28:20 +0000 (10:28 -0400)
Make use of this in drm and wayland st/egl backends.

Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
src/gallium/state_trackers/egl/drm/native_drm.c
src/gallium/state_trackers/egl/wayland/native_drm.c
src/gallium/targets/egl/egl.c

index c89a6d4767e0abd325e8c443de34d51e1fb192b3..725fe28e4e23147926bd65fe42ed28a4fdc88e92 100644 (file)
 
 #include "native_drm.h"
 
-/* see get_drm_screen_name */
-#include <radeon_drm.h>
-#include "radeon/drm/radeon_drm_public.h"
-
 #ifdef HAVE_LIBUDEV
 #include <libudev.h>
 #endif
@@ -140,27 +136,6 @@ drm_display_destroy(struct native_display *ndpy)
    FREE(drmdpy);
 }
 
-static const char *
-get_drm_screen_name(int fd, drmVersionPtr version)
-{
-   const char *name = version->name;
-
-   if (name && !strcmp(name, "radeon")) {
-      int chip_id;
-      struct drm_radeon_info info;
-
-      memset(&info, 0, sizeof(info));
-      info.request = RADEON_INFO_DEVICE_ID;
-      info.value = pointer_to_intptr(&chip_id);
-      if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
-         return NULL;
-
-      name = is_r3xx(chip_id) ? "r300" : "r600";
-   }
-
-   return name;
-}
-
 /**
  * Initialize KMS and pipe screen.
  */
@@ -169,7 +144,6 @@ drm_display_init_screen(struct native_display *ndpy)
 {
    struct drm_display *drmdpy = drm_display(ndpy);
    drmVersionPtr version;
-   const char *name;
 
    version = drmGetVersion(drmdpy->fd);
    if (!version) {
@@ -177,11 +151,8 @@ drm_display_init_screen(struct native_display *ndpy)
       return FALSE;
    }
 
-   name = get_drm_screen_name(drmdpy->fd, version);
-   if (name) {
-      drmdpy->base.screen =
-         drmdpy->event_handler->new_drm_screen(&drmdpy->base, name, drmdpy->fd);
-   }
+   drmdpy->base.screen =
+      drmdpy->event_handler->new_drm_screen(&drmdpy->base, NULL, drmdpy->fd);
    drmFreeVersion(version);
 
    if (!drmdpy->base.screen) {
index f643c7cbbbaff6bcf000b3230ec9d1a5e8967875..15383e8930115a8d7fe069d2f7a47c1e8a6812c5 100644 (file)
 
 #include "native_wayland.h"
 
-/* see get_drm_screen_name */
-#include <radeon_drm.h>
-#include "radeon/drm/radeon_drm_public.h"
-
 #include <wayland-client.h>
 #include "wayland-drm-client-protocol.h"
 #include "wayland-egl-priv.h"
@@ -143,27 +139,6 @@ wayland_create_drm_buffer(struct wayland_display *display,
                                width, height, wsh.stride, visual);
 }
 
-static const char *
-get_drm_screen_name(int fd, drmVersionPtr version)
-{
-   const char *name = version->name;
-
-   if (name && !strcmp(name, "radeon")) {
-      int chip_id;
-      struct drm_radeon_info info;
-
-      memset(&info, 0, sizeof(info));
-      info.request = RADEON_INFO_DEVICE_ID;
-      info.value = pointer_to_intptr(&chip_id);
-      if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
-         return NULL;
-
-      name = is_r3xx(chip_id) ? "r300" : "r600";
-   }
-
-   return name;
-}
-
 static void
 drm_handle_device(void *data, struct wl_drm *drm, const char *device)
 {
@@ -202,8 +177,6 @@ static boolean
 wayland_drm_display_init_screen(struct native_display *ndpy)
 {
    struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
-   drmVersionPtr version;
-   const char *driver_name;
    uint32_t id;
 
    id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1);
@@ -226,20 +199,9 @@ wayland_drm_display_init_screen(struct native_display *ndpy)
    if (!drmdpy->authenticated)
       return FALSE;
 
-   version = drmGetVersion(drmdpy->fd);
-   if (!version) {
-      _eglLog(_EGL_WARNING, "invalid fd %d", drmdpy->fd);
-      return FALSE;
-   }
-
-   /* FIXME: share this with native_drm or egl_dri2 */
-   driver_name = get_drm_screen_name(drmdpy->fd, version);
-
    drmdpy->base.base.screen =
       drmdpy->event_handler->new_drm_screen(&drmdpy->base.base,
-                                            driver_name, drmdpy->fd);
-   drmFreeVersion(version);
-
+                                            NULL, drmdpy->fd);
    if (!drmdpy->base.base.screen) {
       _eglLog(_EGL_WARNING, "failed to create DRM screen");
       return FALSE;
index 61fe5069e919c6edc857ee9fc1d979d9d6abe4a0..3467aea9991215862ed41826dd472a7326de69e9 100644 (file)
 #include "state_tracker/drm_driver.h"
 #include "common/egl_g3d_loader.h"
 
+#ifdef HAVE_LIBUDEV
+#include <libudev.h>
+#define DRIVER_MAP_GALLIUM_ONLY
+#include "pci_ids/pci_id_driver_map.h"
+#endif
+
 #include "egl.h"
 
 struct egl_g3d_loader egl_g3d_loader;
@@ -306,10 +312,83 @@ get_pipe_module(const char *name)
    return pmod;
 }
 
+static char *
+drm_fd_get_screen_name(int fd)
+{
+   char *driver = NULL;
+#ifdef HAVE_LIBUDEV
+   struct udev *udev;
+   struct udev_device *device, *parent;
+   struct stat buf;
+   const char *pci_id;
+   int vendor_id, chip_id, i, j;
+
+   udev = udev_new();
+   if (fstat(fd, &buf) < 0) {
+      _eglLog(_EGL_WARNING, "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,
+              "could not create udev device for fd %d", fd);
+      return NULL;
+   }
+
+   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");
+      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_WARNING,
+                 "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_WARNING,
+                    "pci id for %d: %04x:%04x, driver %s",
+                    fd, vendor_id, chip_id, driver);
+            goto out;
+         }
+   }
+
+out:
+   udev_device_unref(device);
+   udev_unref(udev);
+
+#endif
+   return driver;
+}
+
 static struct pipe_screen *
 create_drm_screen(const char *name, int fd)
 {
-   struct pipe_module *pmod = get_pipe_module(name);
+   struct pipe_module *pmod;
+   const char *screen_name = name;
+   
+   if (screen_name == NULL)
+      if ((screen_name = drm_fd_get_screen_name(fd)) == NULL)
+         return NULL;
+   pmod = get_pipe_module(screen_name);
+
    return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ?
       pmod->drmdd->create_screen(fd) : NULL;
 }