[Mesa-dev] [PATCH 04/10] egl: add EGL_EXT_device_drm support
Emil Velikov
emil.l.velikov at gmail.com
Fri Aug 3 12:44:20 UTC 2018
From: Emil Velikov <emil.velikov at collabora.com>
Add implementation based around the drmDevice API. As such it's only
available only when building with libdrm. With the latter already a
requirement when using !SW code paths in the platform code.
Note: the current code will work if a device is hot-plugged. Yet
hot-unplugged is not implemented, since I have no ways of testing it.
Signed-off-by: Emil Velikov <emil.velikov at collabora.com>
---
src/egl/main/egldevice.c | 97 ++++++++++++++++++++++++++++++++++++++++
src/egl/main/egldevice.h | 1 +
2 files changed, 98 insertions(+)
diff --git a/src/egl/main/egldevice.c b/src/egl/main/egldevice.c
index 8e7116c90f4..36f913adcac 100644
--- a/src/egl/main/egldevice.c
+++ b/src/egl/main/egldevice.c
@@ -25,6 +25,9 @@
*
**************************************************************************/
+#ifdef HAVE_LIBDRM
+#include <xf86drm.h>
+#endif
#include "util/macros.h"
#include "eglcurrent.h"
@@ -40,6 +43,11 @@ struct _egl_device {
const char *extensions;
EGLBoolean MESA_device_software;
+ EGLBoolean EXT_device_drm;
+
+#ifdef HAVE_LIBDRM
+ drmDevicePtr device;
+#endif
};
void
@@ -61,6 +69,9 @@ _eglFiniDevice(void)
dev = dev_list;
dev_list = dev_list->Next;
+#ifdef HAVE_LIBDRM
+ drmFreeDevice(&dev->device);
+#endif
free(dev);
}
@@ -88,6 +99,53 @@ static _EGLDevice software_device = {
.MESA_device_software = EGL_TRUE,
};
+#ifdef HAVE_LIBDRM
+/*
+ * Negative value on error, zero if newly added, one if already in list.
+ */
+static int
+_eglAddDRMDevice(drmDevicePtr device, _EGLDevice **out_dev)
+{
+ _EGLDevice *dev;
+
+ if ((device->available_nodes & 1 << DRM_NODE_PRIMARY) == 0)
+ return -1;
+
+ dev = _eglGlobal.DeviceList;
+
+ /* Compare against the second device onward.
+ * As said elsewhere - first one is always software.
+ */
+
+ while (dev->Next) {
+ dev = dev->Next;
+
+ if (drmDevicesEqual(device, dev->device) != 0) {
+ if (out_dev)
+ *out_dev = dev;
+ return 1;
+ }
+ }
+
+ dev->Next = calloc(1, sizeof(_EGLDevice));
+ if (!dev->Next) {
+ if (out_dev)
+ *out_dev = NULL;
+ return -1;
+ }
+
+ dev = dev->Next;
+ dev->extensions = "EGL_EXT_device_drm";
+ dev->EXT_device_drm = EGL_TRUE;
+ dev->device = device;
+
+ if (out_dev)
+ *out_dev = dev;
+
+ return 0;
+}
+#endif
+
/* Looks up for device in DeviceList adding if there isn't one already.
*
* For software device lookup, the fd is ignored.
@@ -108,7 +166,21 @@ _eglFindDevice(int fd, bool software)
if (software)
goto out;
+#ifdef HAVE_LIBDRM
+ drmDevicePtr device;
+
+ if (drmGetDevice2(fd, 0, &device) != 0) {
+ dev = NULL;
+ goto out;
+ }
+
+ /* Device is not added - error or already present */
+ if (_eglAddDRMDevice(device, &dev) != 0)
+ drmFreeDevice(&device);
+#else
+ _eglLog(_EGL_FATAL, "Driver bug: Built without libdrm, yet looking for HW device");
dev = NULL;
+#endif
out:
mtx_unlock(_eglGlobal.Mutex);
@@ -121,6 +193,8 @@ _eglDeviceSupports(_EGLDevice *dev, _EGLDeviceExtension ext)
switch (ext) {
case _EGL_DEVICE_SOFTWARE:
return dev->MESA_device_software;
+ case _EGL_DEVICE_DRM:
+ return dev->EXT_device_drm;
};
assert(0);
return EGL_FALSE;
@@ -143,6 +217,12 @@ _eglQueryDeviceStringEXT(_EGLDevice *dev, EGLint name)
switch (name) {
case EGL_EXTENSIONS:
return dev->extensions;
+#ifdef HAVE_LIBDRM
+ case EGL_DRM_DEVICE_FILE_EXT:
+ if (_eglDeviceSupports(dev, _EGL_DEVICE_DRM))
+ return dev->device->nodes[DRM_NODE_PRIMARY];
+ /* fall through */
+#endif
default:
_eglError(EGL_BAD_PARAMETER, "eglQueryDeviceStringEXT");
return NULL;
@@ -170,6 +250,23 @@ _eglLookupAllDevices(void)
}
count++;
+#ifdef HAVE_LIBDRM
+ drmDevicePtr devices[64];
+ int num_devs, ret;
+
+ num_devs = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
+ for (int i = 0; i < num_devs; i++) {
+ ret = _eglAddDRMDevice(devices[i], NULL);
+
+ /* Device is not added - error or already present */
+ if (ret != 0)
+ drmFreeDevice(&devices[i]);
+
+ if (ret >= 0)
+ count++;
+ }
+#endif
+
return count;
}
diff --git a/src/egl/main/egldevice.h b/src/egl/main/egldevice.h
index 945c25268e1..61f88df6b24 100644
--- a/src/egl/main/egldevice.h
+++ b/src/egl/main/egldevice.h
@@ -57,6 +57,7 @@ _eglFindDevice(int fd, bool software);
enum _egl_device_extension {
_EGL_DEVICE_SOFTWARE,
+ _EGL_DEVICE_DRM,
};
typedef enum _egl_device_extension _EGLDeviceExtension;
--
2.18.0
More information about the mesa-dev
mailing list