targets/egl: Support driver name lookup using pci lists

Make use of this in drm and wayland st/egl backends.

Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
This commit is contained in:
Benjamin Franzke 2011-05-30 09:55:14 +02:00 committed by Kristian Høgsberg
parent 7f881c43df
commit a433755ec5
3 changed files with 83 additions and 71 deletions

View file

@ -33,10 +33,6 @@
#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) {

View file

@ -37,10 +37,6 @@
#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;

View file

@ -37,6 +37,12 @@
#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;
}