summaryrefslogtreecommitdiffstats
path: root/src/egl/drivers
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-07-26 17:47:59 -0700
committerEric Anholt <[email protected]>2010-07-26 17:53:27 -0700
commitafe125e0a18ac3886c45c7e6b02b122fb2d327b5 (patch)
tree78621707e71154c0b388b0baacffc26432b7e992 /src/egl/drivers
parentd64343f1ae84979bd154475badf11af8a9bfc2eb (diff)
parent5403ca79b225605c79f49866a6497c97da53be3b (diff)
Merge remote branch 'origin/master' into glsl2
This pulls in multiple i965 driver fixes which will help ensure better testing coverage during development, and also gets past the conflicts of the src/mesa/shader -> src/mesa/program move. Conflicts: src/mesa/Makefile src/mesa/main/shaderapi.c src/mesa/main/shaderobj.h
Diffstat (limited to 'src/egl/drivers')
-rw-r--r--src/egl/drivers/dri2/Makefile6
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c268
-rw-r--r--src/egl/drivers/glx/egl_glx.c16
3 files changed, 240 insertions, 50 deletions
diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile
index 4e760aec4c8..8a3c9b6a0aa 100644
--- a/src/egl/drivers/dri2/Makefile
+++ b/src/egl/drivers/dri2/Makefile
@@ -11,8 +11,10 @@ EGL_INCLUDES = \
-I$(TOP)/src/egl/main \
-I$(TOP)/src/mapi \
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
- $(EGL_DRI2_CFLAGS)
+ $(XCB_DRI2_CFLAGS) \
+ $(LIBUDEV_CFLAGS) \
+ $(LIBDRM_CFLAGS)
-EGL_LIBS = $(EGL_DRI2_LIBS)
+EGL_LIBS = $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(LIBDRM_LIBS)
include ../Makefile.template
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index aa384cb1172..c6d79a64e8a 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -40,6 +40,12 @@
#include <xcb/dri2.h>
#include <xcb/xfixes.h>
#include <X11/Xlib-xcb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_LIBUDEV
+#include <libudev.h>
+#endif
#include <glapi/glapi.h>
#include "eglconfig.h"
@@ -79,7 +85,6 @@ struct dri2_egl_display
char *driver_name;
__DRIdri2LoaderExtension loader_extension;
- __DRIimageLookupExtension image_lookup_extension;
const __DRIextension *extensions[3];
};
@@ -117,6 +122,10 @@ struct dri2_egl_image
_EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl)
_EGL_DRIVER_TYPECAST(dri2_egl_image, _EGLImage, obj)
+static const __DRIuseInvalidateExtension use_invalidate = {
+ { __DRI_USE_INVALIDATE, 1 }
+};
+
EGLint dri2_to_egl_attribute_map[] = {
0,
EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */
@@ -381,6 +390,11 @@ dri2_lookup_egl_image(__DRIcontext *context, void *image, void *data)
return dri2_img->dri_image;
}
+static const __DRIimageLookupExtension image_lookup_extension = {
+ { __DRI_IMAGE_LOOKUP, 1 },
+ dri2_lookup_egl_image
+};
+
static __DRIbuffer *
dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
int *width, int *height,
@@ -620,7 +634,7 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
xcb_depth_next(&d);
}
- if (!disp->NumConfigs) {
+ if (!_eglGetArraySize(disp->Configs)) {
_eglLog(_EGL_WARNING, "DRI2: failed to create any config");
return EGL_FALSE;
}
@@ -690,27 +704,63 @@ dri2_load_driver(_EGLDisplay *disp)
return EGL_TRUE;
}
-
-/**
- * Called via eglInitialize(), GLX_drv->API.Initialize().
- */
static EGLBoolean
-dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
- EGLint *major, EGLint *minor)
+dri2_create_screen(_EGLDisplay *disp)
{
const __DRIextension **extensions;
struct dri2_egl_display *dri2_dpy;
unsigned int api_mask;
+ dri2_dpy = disp->DriverData;
+ dri2_dpy->dri_screen =
+ dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
+ &dri2_dpy->driver_configs, dri2_dpy);
+
+ if (dri2_dpy->dri_screen == NULL) {
+ _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
+ return EGL_FALSE;
+ }
+
+ extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
+ if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
+ goto cleanup_dri_screen;
+
+ if (dri2_dpy->dri2->base.version >= 2)
+ api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
+ else
+ api_mask = __DRI_API_OPENGL;
+
+ disp->ClientAPIsMask = 0;
+ if (api_mask & (1 <<__DRI_API_OPENGL))
+ disp->ClientAPIsMask |= EGL_OPENGL_BIT;
+ if (api_mask & (1 <<__DRI_API_GLES))
+ disp->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
+ if (api_mask & (1 << __DRI_API_GLES2))
+ disp->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
+
+ return EGL_TRUE;
+
+ cleanup_dri_screen:
+ dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+
+ return EGL_FALSE;
+}
+
+static EGLBoolean
+dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp,
+ EGLint *major, EGLint *minor)
+{
+ struct dri2_egl_display *dri2_dpy;
+
dri2_dpy = malloc(sizeof *dri2_dpy);
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
disp->DriverData = (void *) dri2_dpy;
- if (disp->NativeDisplay == NULL) {
+ if (disp->PlatformDisplay == NULL) {
dri2_dpy->conn = xcb_connect(0, 0);
} else {
- dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
+ dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
}
if (xcb_connection_has_error(dri2_dpy->conn)) {
@@ -754,39 +804,12 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
dri2_dpy->loader_extension.getBuffersWithFormat = NULL;
}
- dri2_dpy->image_lookup_extension.base.name = __DRI_IMAGE_LOOKUP;
- dri2_dpy->image_lookup_extension.base.version = 1;
- dri2_dpy->image_lookup_extension.lookupEGLImage = dri2_lookup_egl_image;
-
dri2_dpy->extensions[0] = &dri2_dpy->loader_extension.base;
- dri2_dpy->extensions[1] = &dri2_dpy->image_lookup_extension.base;
+ dri2_dpy->extensions[1] = &image_lookup_extension.base;
dri2_dpy->extensions[2] = NULL;
- dri2_dpy->dri_screen =
- dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
- &dri2_dpy->driver_configs, dri2_dpy);
-
- if (dri2_dpy->dri_screen == NULL) {
- _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
+ if (!dri2_create_screen(disp))
goto cleanup_fd;
- }
-
- extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
- if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
- goto cleanup_dri_screen;
-
- if (dri2_dpy->dri2->base.version >= 2)
- api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
- else
- api_mask = __DRI_API_OPENGL;
-
- disp->ClientAPIsMask = 0;
- if (api_mask & (1 <<__DRI_API_OPENGL))
- disp->ClientAPIsMask |= EGL_OPENGL_BIT;
- if (api_mask & (1 <<__DRI_API_GLES))
- disp->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
- if (api_mask & (1 << __DRI_API_GLES2))
- disp->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
if (dri2_dpy->conn) {
if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
@@ -808,14 +831,13 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
cleanup_configs:
_eglCleanupDisplay(disp);
- cleanup_dri_screen:
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
cleanup_fd:
close(dri2_dpy->fd);
cleanup_driver:
dlclose(dri2_dpy->driver);
cleanup_conn:
- if (disp->NativeDisplay == NULL)
+ if (disp->PlatformDisplay == NULL)
xcb_disconnect(dri2_dpy->conn);
cleanup_dpy:
free(dri2_dpy);
@@ -823,6 +845,168 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
return EGL_FALSE;
}
+#ifdef HAVE_LIBUDEV
+
+struct dri2_driver_map {
+ int vendor_id;
+ const char *driver;
+ const int *chip_ids;
+ int num_chips_ids;
+};
+
+const int i915_chip_ids[] = {
+ 0x3577, /* PCI_CHIP_I830_M */
+ 0x2562, /* PCI_CHIP_845_G */
+ 0x3582, /* PCI_CHIP_I855_GM */
+ 0x2572, /* PCI_CHIP_I865_G */
+ 0x2582, /* PCI_CHIP_I915_G */
+ 0x258a, /* PCI_CHIP_E7221_G */
+ 0x2592, /* PCI_CHIP_I915_GM */
+ 0x2772, /* PCI_CHIP_I945_G */
+ 0x27a2, /* PCI_CHIP_I945_GM */
+ 0x27ae, /* PCI_CHIP_I945_GME */
+ 0x29b2, /* PCI_CHIP_Q35_G */
+ 0x29c2, /* PCI_CHIP_G33_G */
+ 0x29d2, /* PCI_CHIP_Q33_G */
+};
+
+const int i965_chip_ids[] = {
+ 0x29a2, /* PCI_CHIP_I965_G */
+ 0x2992, /* PCI_CHIP_I965_Q */
+ 0x2982, /* PCI_CHIP_I965_G_1 */
+ 0x2972, /* PCI_CHIP_I946_GZ */
+ 0x2a02, /* PCI_CHIP_I965_GM */
+ 0x2a12, /* PCI_CHIP_I965_GME */
+ 0x2a42, /* PCI_CHIP_GM45_GM */
+ 0x2e02, /* PCI_CHIP_IGD_E_G */
+ 0x2e12, /* PCI_CHIP_Q45_G */
+ 0x2e22, /* PCI_CHIP_G45_G */
+ 0x2e32, /* PCI_CHIP_G41_G */
+};
+
+const struct dri2_driver_map driver_map[] = {
+ { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids) },
+ { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids) },
+};
+
+static char *
+dri2_get_driver_for_fd(int fd)
+{
+ struct udev *udev;
+ struct udev_device *device, *parent;
+ struct stat buf;
+ const char *pci_id;
+ char *driver = NULL;
+ int vendor_id, chip_id, i, j;
+
+ udev = udev_new();
+ if (fstat(fd, &buf) < 0) {
+ _eglLog(_EGL_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
+ goto out;
+ }
+
+ device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+ if (device == NULL) {
+ _eglLog(_EGL_WARNING,
+ "EGL-DRI2: could not create udev device for fd %d", fd);
+ goto out;
+ }
+
+ parent = udev_device_get_parent(device);
+ if (parent == NULL) {
+ _eglLog(_EGL_WARNING, "DRI2: 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, "EGL-DRI2: malformed or no PCI ID");
+ goto out;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
+ if (vendor_id != driver_map[i].vendor_id)
+ continue;
+ 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_DEBUG, "pci id for %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ goto out;
+ }
+ }
+
+ out:
+ udev_device_unref(device);
+ udev_unref(udev);
+
+ return driver;
+}
+
+static EGLBoolean
+dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp,
+ EGLint *major, EGLint *minor)
+{
+ struct dri2_egl_display *dri2_dpy;
+
+ dri2_dpy = malloc(sizeof *dri2_dpy);
+ if (!dri2_dpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+ disp->DriverData = (void *) dri2_dpy;
+ dri2_dpy->fd = (int) disp->PlatformDisplay;
+
+ dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
+ if (dri2_dpy->driver_name == NULL)
+ return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
+
+ if (!dri2_load_driver(disp))
+ goto cleanup_driver_name;
+
+ dri2_dpy->extensions[0] = &image_lookup_extension.base;
+ dri2_dpy->extensions[1] = &use_invalidate.base;
+ dri2_dpy->extensions[2] = NULL;
+
+ if (!dri2_create_screen(disp))
+ goto cleanup_driver;
+
+ disp->Extensions.KHR_image_base = EGL_TRUE;
+ disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
+ disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
+
+ return EGL_TRUE;
+
+ cleanup_driver:
+ dlclose(dri2_dpy->driver);
+ cleanup_driver_name:
+ free(dri2_dpy->driver_name);
+
+ return EGL_FALSE;
+}
+
+#endif
+
+/**
+ * Called via eglInitialize(), GLX_drv->API.Initialize().
+ */
+static EGLBoolean
+dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
+ EGLint *major, EGLint *minor)
+{
+ switch (disp->Platform) {
+ case _EGL_PLATFORM_X11:
+ return dri2_initialize_x11(drv, disp, major, minor);
+
+#ifdef HAVE_LIBUDEV
+ case _EGL_PLATFORM_DRM:
+ return dri2_initialize_drm(drv, disp, major, minor);
+#endif
+
+ default:
+ return EGL_FALSE;
+ }
+}
+
/**
* Called via eglTerminate(), drv->API.Terminate().
*/
@@ -837,7 +1021,7 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
close(dri2_dpy->fd);
dlclose(dri2_dpy->driver);
- if (disp->NativeDisplay == NULL)
+ if (disp->PlatformDisplay == NULL)
xcb_disconnect(dri2_dpy->conn);
free(dri2_dpy);
disp->DriverData = NULL;
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index e08ef5f2228..b4a40d14377 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -498,11 +498,14 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
{
struct GLX_egl_display *GLX_dpy;
+ if (disp->Platform != _EGL_PLATFORM_X11)
+ return EGL_FALSE;
+
GLX_dpy = CALLOC_STRUCT(GLX_egl_display);
if (!GLX_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
- GLX_dpy->dpy = (Display *) disp->NativeDisplay;
+ GLX_dpy->dpy = (Display *) disp->PlatformDisplay;
if (!GLX_dpy->dpy) {
GLX_dpy->dpy = XOpenDisplay(NULL);
if (!GLX_dpy->dpy) {
@@ -514,7 +517,7 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
if (!glXQueryVersion(GLX_dpy->dpy, &GLX_dpy->glx_maj, &GLX_dpy->glx_min)) {
_eglLog(_EGL_WARNING, "GLX: glXQueryVersion failed");
- if (!disp->NativeDisplay)
+ if (!disp->PlatformDisplay)
XCloseDisplay(GLX_dpy->dpy);
free(GLX_dpy);
return EGL_FALSE;
@@ -524,9 +527,9 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
check_quirks(GLX_dpy, DefaultScreen(GLX_dpy->dpy));
create_configs(disp, GLX_dpy, DefaultScreen(GLX_dpy->dpy));
- if (!disp->NumConfigs) {
+ if (!_eglGetArraySize(disp->Configs)) {
_eglLog(_EGL_WARNING, "GLX: failed to create any config");
- if (!disp->NativeDisplay)
+ if (!disp->PlatformDisplay)
XCloseDisplay(GLX_dpy->dpy);
free(GLX_dpy);
return EGL_FALSE;
@@ -558,7 +561,7 @@ GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp)
if (GLX_dpy->fbconfigs)
XFree(GLX_dpy->fbconfigs);
- if (!disp->NativeDisplay)
+ if (!disp->PlatformDisplay)
XCloseDisplay(GLX_dpy->dpy);
free(GLX_dpy);
@@ -617,10 +620,11 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
static void
destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
if (GLX_surf->destroy)
- GLX_surf->destroy(disp->NativeDisplay, GLX_surf->glx_drawable);
+ GLX_surf->destroy(GLX_dpy->dpy, GLX_surf->glx_drawable);
free(GLX_surf);
}