summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2015-07-22 15:26:42 +0200
committerJonny Lamb <jonny.lamb@collabora.co.uk>2015-07-22 17:09:00 +0200
commitdfade75f321293425582441142741b1d20493ba5 (patch)
tree47c69f604e7414a8d45e869af8b2abb0a6c8abe7 /src
parent7e7f9d25c2cac6b6e1dd980f263eb34165462299 (diff)
egldevice: implement EGL_MESA_device_hashdevice-hash
Use the hash table string hashing function as it's probably fine. The hash is taken of the string of the vendor and device IDs from the PCI bus. Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/egl/main/Makefile.am2
-rw-r--r--src/egl/main/egldevice.c69
-rw-r--r--src/egl/main/egldevice.h1
3 files changed, 71 insertions, 1 deletions
diff --git a/src/egl/main/Makefile.am b/src/egl/main/Makefile.am
index 9030d272b5..e2811371de 100644
--- a/src/egl/main/Makefile.am
+++ b/src/egl/main/Makefile.am
@@ -23,6 +23,7 @@ include Makefile.sources
AM_CFLAGS = \
-I$(top_srcdir)/include \
+ -I$(top_srcdir)/src \
-I$(top_srcdir)/src/gbm/main \
$(DEFINES) \
$(VISIBILITY_CFLAGS) \
@@ -37,6 +38,7 @@ libEGL_la_SOURCES = \
${LIBEGL_C_FILES}
libEGL_la_LIBADD = \
+ $(top_builddir)/src/util/libmesautil.la
$(EGL_LIB_DEPS)
libEGL_la_LDFLAGS = \
-no-undefined \
diff --git a/src/egl/main/egldevice.c b/src/egl/main/egldevice.c
index 8a717a6c6a..69121e6812 100644
--- a/src/egl/main/egldevice.c
+++ b/src/egl/main/egldevice.c
@@ -34,6 +34,8 @@
#include <assert.h>
#include <string.h>
+#include "util/hash_table.h"
+
#include "eglcurrent.h"
#include "egldevice.h"
#include "egldriver.h"
@@ -79,7 +81,7 @@ _eglEnsureDeviceInfo(EGLBoolean get_devices)
/* update this string like in eglglobals.c to add support for a device
* extension */
- info->extensions = "";
+ info->extensions = "EGL_MESA_device_hash";
#ifdef HAVE_LIBUDEV
info->udev = NULL;
@@ -216,6 +218,64 @@ _eglFiniDeviceInfo(void)
_eglGlobal.DeviceInfo = NULL;
}
+static EGLBoolean
+_eglQueryDeviceHash(_EGLDevice *device,
+ EGLAttrib *value)
+{
+#ifdef HAVE_LIBUDEV
+ struct udev_device *parent;
+ EGLBoolean ret = EGL_TRUE;
+ const char *subsystem_vendor, *subsystem_device;
+ char *str;
+ int len;
+ UDEV_SYMBOL(struct udev_device *, udev_device_get_parent_with_subsystem_devtype,
+ (struct udev_device *, const char *, const char *));
+ UDEV_SYMBOL(const char *, udev_device_get_sysattr_value,
+ (struct udev_device *, const char *));
+
+ if (dlsym_failed)
+ return EGL_FALSE;
+
+ assert(device->Hash == 0);
+
+ mtx_lock(_eglGlobal.Mutex);
+
+ parent = udev_device_get_parent_with_subsystem_devtype(
+ device->Info, "pci", NULL);
+
+ if (!parent) {
+ ret = EGL_FALSE;
+ goto out;
+ }
+
+ subsystem_vendor = udev_device_get_sysattr_value(parent, "subsystem_vendor");
+ subsystem_device = udev_device_get_sysattr_value(parent, "subsystem_device");
+
+ if (!subsystem_vendor || !subsystem_device) {
+ ret = EGL_FALSE;
+ goto out;
+ }
+
+ len = strlen(subsystem_vendor) + strlen(subsystem_device);
+ str = calloc(len + 1, sizeof(char));
+
+ str = strdup(subsystem_vendor);
+ strcat(str, subsystem_device);
+
+ *value = _mesa_hash_string(str);
+
+ device->Hash = *value;
+
+ free(str);
+
+out:
+ mtx_unlock(_eglGlobal.Mutex);
+ return ret;
+#else
+ return EGL_FALSE;
+#endif
+}
+
/**
* Get attribute about specific device
*/
@@ -228,6 +288,13 @@ _eglQueryDeviceAttribEXT(_EGLDevice *device,
return _eglError(EGL_BAD_PARAMETER, "eglQueryDeviceAttribEXT");
switch (attribute) {
+ case EGL_DEVICE_HASH_MESA:
+ if (device->Hash > 0) {
+ return device->Hash;
+ } else {
+ return _eglQueryDeviceHash(device, value);
+ }
+ break;
default:
return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryDeviceAttribEXT");
break;
diff --git a/src/egl/main/egldevice.h b/src/egl/main/egldevice.h
index 2c7986acb7..fb30bd2050 100644
--- a/src/egl/main/egldevice.h
+++ b/src/egl/main/egldevice.h
@@ -37,6 +37,7 @@ struct _egl_device {
_EGLDevice *Next;
void *Info;
+ EGLint Hash;
};