summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBenjamin Franzke <[email protected]>2011-05-30 09:55:14 +0200
committerKristian Høgsberg <[email protected]>2011-06-07 10:28:20 -0400
commita433755ec5c48088a0d8a340851a1a8be9e58897 (patch)
treeec07d218e029d03b609ff3d391a32cb07fdffbb2 /src
parent7f881c43dfb4f1aeeab3a84125b5c106c191a43f (diff)
targets/egl: Support driver name lookup using pci lists
Make use of this in drm and wayland st/egl backends. Reviewed-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.c33
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_drm.c40
-rw-r--r--src/gallium/targets/egl/egl.c81
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 c89a6d4767e..725fe28e4e2 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 <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) {
diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c
index f643c7cbbba..15383e89301 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 <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;
diff --git a/src/gallium/targets/egl/egl.c b/src/gallium/targets/egl/egl.c
index 61fe5069e91..3467aea9991 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 <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;
}