From: Emil Velikov <emil.veli...@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.veli...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev