From a433755ec5c48088a0d8a340851a1a8be9e58897 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Mon, 30 May 2011 09:55:14 +0200 Subject: [PATCH] targets/egl: Support driver name lookup using pci lists Make use of this in drm and wayland st/egl backends. Reviewed-by: Alex Deucher --- src/gallium/state_trackers/egl/drm/native_drm.c | 33 +-------- .../state_trackers/egl/wayland/native_drm.c | 40 +---------- src/gallium/targets/egl/egl.c | 81 +++++++++++++++++++++- 3 files changed, 83 insertions(+), 71 deletions(-) diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index c89a6d4..725fe28 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -33,10 +33,6 @@ #include "native_drm.h" -/* see get_drm_screen_name */ -#include -#include "radeon/drm/radeon_drm_public.h" - #ifdef HAVE_LIBUDEV #include #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) { diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c index f643c7c..15383e8 100644 --- a/src/gallium/state_trackers/egl/wayland/native_drm.c +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c @@ -37,10 +37,6 @@ #include "native_wayland.h" -/* see get_drm_screen_name */ -#include -#include "radeon/drm/radeon_drm_public.h" - #include #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; diff --git a/src/gallium/targets/egl/egl.c b/src/gallium/targets/egl/egl.c index 61fe506..3467aea 100644 --- a/src/gallium/targets/egl/egl.c +++ b/src/gallium/targets/egl/egl.c @@ -37,6 +37,12 @@ #include "state_tracker/drm_driver.h" #include "common/egl_g3d_loader.h" +#ifdef HAVE_LIBUDEV +#include +#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; } -- 2.7.4