summaryrefslogtreecommitdiff
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
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>
-rw-r--r--docs/specs/EGL_MESA_device_hash.txt95
-rw-r--r--include/EGL/eglmesaext.h5
-rw-r--r--src/egl/main/Makefile.am2
-rw-r--r--src/egl/main/egldevice.c69
-rw-r--r--src/egl/main/egldevice.h1
5 files changed, 171 insertions, 1 deletions
diff --git a/docs/specs/EGL_MESA_device_hash.txt b/docs/specs/EGL_MESA_device_hash.txt
new file mode 100644
index 0000000000..910a33e66e
--- /dev/null
+++ b/docs/specs/EGL_MESA_device_hash.txt
@@ -0,0 +1,95 @@
+Name
+
+ EGL_MESA_device_hash
+
+Name Strings
+
+ EGL_MESA_device_hash
+
+Contributors
+
+ Jonny Lamb <jonny.lamb@collabora.co.uk>
+
+Contact
+
+ Jonny Lamb <jonny.lamb@collabora.co.uk>
+
+Status
+
+ Draft
+
+Version
+
+ Version 1, 2015-07-22
+
+Number
+
+ EGL Extension #XXX
+
+Extension Type
+
+ EGL device extension
+
+Dependencies
+
+ This extension is written against the wording of EGL 1.5 as
+ modified by EGL_EXT_device_query.
+
+ EGL_EXT_device_query is required.
+
+Overview
+
+ The EGLDeviceEXT object is useful for referring to a particular
+ device on the system. However, this handle is only valid for the
+ current process. For referring to devices across different
+ processes on the same system an integer value is required.
+
+ Additionally, when using functions with EGLint argument types, it
+ is currently not possible to refer to EGLDeviceEXT objects. An
+ integer value for said objects is necessary to enable this
+ functionality. The <attrib_list> argument of eglGetPlatformDisplay
+ is an example of a function with an argument of type EGLint.
+
+New Types
+
+ None
+
+New Procedures and Functions
+
+ None
+
+New Tokens
+
+ Accepted as a queried <attribute> in eglQueryDeviceAttribEXT:
+
+ EGL_DEVICE_HASH_MESA 0x31E0
+
+Additions to the EGL 1.5 Specification
+
+ In section 3.2 "Devices", replace the paragraph immediately
+ following the prototype for eglQueryDeviceAttribEXT with the
+ following:
+
+ "On success, EGL_TRUE is returned and the requested attribute
+ value is returned in <value>. Currently the only valid value for
+ <attribute> is EGL_DEVICE_HASH_MESA which returns in <value> an
+ EGLint hash value for the EGLDeviceEXT object given in <device>.
+ This hash value can be used for comparing EGLDeviceEXT objects
+ across different processes on the same system and for when an EGL
+ function argument type is EGLint instead of EGLattrib. With a
+ successful call using EGL_DEVICE_HASH_MESA as <attribute> the
+ returned EGLint is always non-zero.
+
+ The method used to calculate the hash for a EGLDeviceEXT is left
+ up to the implementation. Compatibility between hash values can
+ only be assumed with the same version of the same implementation
+ running on the same system."
+
+Issues
+
+ None
+
+Revision History
+
+ Version 1, 2015-7-22 (Jonny Lamb)
+ - Initial draft
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index 917a2043c7..ea96e97737 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -95,6 +95,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
#define EGL_NO_CONFIG_MESA ((EGLConfig)0)
#endif
+#ifndef EGL_MESA_device_hash
+#define EGL_MESA_device_hash 1
+#define EGL_DEVICE_HASH_MESA 0x31E0
+#endif
+
#ifdef __cplusplus
}
#endif
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;
};