[Mesa-dev] [PATCH 03/10] egl: add EGL_MESA_device_software support

Eric Engestrom eric.engestrom at intel.com
Wed Aug 29 11:47:37 UTC 2018


On Friday, 2018-08-03 13:44:19 +0100, Emil Velikov wrote:
> From: Emil Velikov <emil.velikov at collabora.com>
> 
> Add LookupDevices/FindDevice helpers, alongside their first user -
> software device ;-)
> 
> This adds support to both dri2 and haiku backends.
> 
> Signed-off-by: Emil Velikov <emil.velikov at collabora.com>
> ---
> How can we split this up for platforms that support SW and HW devices?
> FindDevice on a HW device will fail, bringing the whole eglInitialize
> with it.
> ---
>  src/egl/drivers/dri2/egl_dri2.h             |  1 +
>  src/egl/drivers/dri2/platform_android.c     |  9 +++
>  src/egl/drivers/dri2/platform_drm.c         |  9 +++
>  src/egl/drivers/dri2/platform_surfaceless.c | 10 ++-
>  src/egl/drivers/dri2/platform_wayland.c     | 18 +++++
>  src/egl/drivers/dri2/platform_x11.c         | 27 +++++++
>  src/egl/drivers/haiku/egl_haiku.cpp         |  8 +++
>  src/egl/main/egldevice.c                    | 78 ++++++++++++++++++++-
>  src/egl/main/egldevice.h                    | 14 +++-
>  9 files changed, 171 insertions(+), 3 deletions(-)
> 
> diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
> index f8001ec4b66..d57b91cf3b9 100644
> --- a/src/egl/drivers/dri2/egl_dri2.h
> +++ b/src/egl/drivers/dri2/egl_dri2.h
> @@ -71,6 +71,7 @@ struct zwp_linux_dmabuf_v1;
>  
>  #include "eglconfig.h"
>  #include "eglcontext.h"
> +#include "egldevice.h"
>  #include "egldisplay.h"
>  #include "egldriver.h"
>  #include "eglcurrent.h"
> diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
> index cc16fd8118f..cb3b8c1a93a 100644
> --- a/src/egl/drivers/dri2/platform_android.c
> +++ b/src/egl/drivers/dri2/platform_android.c
> @@ -1360,6 +1360,7 @@ success:
>  EGLBoolean
>  dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
>  {
> +   _EGLDevice *dev;
>     struct dri2_egl_display *dri2_dpy;
>     const char *err;
>     int ret;
> @@ -1390,6 +1391,14 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
>        goto cleanup;
>     }
>  
> +   dev = _eglFindDevice(dri2_dpy->fd, false);
> +   if (!dev) {
> +      err = "DRI2: failed to find EGLDevice";
> +      goto cleanup;
> +   }
> +
> +   disp->Device = dev;
> +
>     if (!droid_load_driver(disp)) {
>        err = "DRI2: failed to load driver";
>        goto cleanup;
> diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
> index 35bc4b5b1ac..5fc42668974 100644
> --- a/src/egl/drivers/dri2/platform_drm.c
> +++ b/src/egl/drivers/dri2/platform_drm.c
> @@ -696,6 +696,7 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
>  EGLBoolean
>  dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
>  {
> +   _EGLDevice *dev;
>     struct dri2_egl_display *dri2_dpy;
>     struct gbm_device *gbm;
>     const char *err;
> @@ -738,6 +739,14 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
>        goto cleanup;
>     }
>  
> +   dev = _eglFindDevice(dri2_dpy->fd, false);
> +   if (!dev) {
> +      err = "DRI2: failed to find EGLDevice";
> +      goto cleanup;
> +   }
> +
> +   disp->Device = dev;
> +
>     dri2_dpy->gbm_dri = gbm_dri_device(gbm);
>     dri2_dpy->driver_name = strdup(dri2_dpy->gbm_dri->driver_name);
>  
> diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c
> index bfc8fb99eab..a5e6f976ad2 100644
> --- a/src/egl/drivers/dri2/platform_surfaceless.c
> +++ b/src/egl/drivers/dri2/platform_surfaceless.c
> @@ -317,8 +317,16 @@ surfaceless_probe_device(_EGLDisplay *dpy, bool swrast)
>        }
>  
>        dri2_dpy->fd = fd;
> -      if (dri2_load_driver_dri3(dpy))
> +      if (dri2_load_driver_dri3(dpy)) {
> +         _EGLDevice *dev = _eglFindDevice(dri2_dpy->fd, swrast);
> +         if (!dev) {
> +            dlclose(dri2_dpy->driver);
> +            _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
> +            continue;
> +         }
> +         dpy->Device = dev;
>           return true;
> +      }
>  
>        close(fd);
>        dri2_dpy->fd = -1;
> diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
> index dca099500a8..b4a0790dda3 100644
> --- a/src/egl/drivers/dri2/platform_wayland.c
> +++ b/src/egl/drivers/dri2/platform_wayland.c
> @@ -1300,6 +1300,7 @@ dri2_wl_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
>  static EGLBoolean
>  dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
>  {
> +   _EGLDevice *dev;
>     struct dri2_egl_display *dri2_dpy;
>  
>     loader_set_logger(_eglLog);
> @@ -1319,6 +1320,14 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
>        dri2_dpy->wl_dpy = disp->PlatformDisplay;
>     }
>  
> +   dev = _eglFindDevice(dri2_dpy->fd, false);
> +   if (!dev) {
> +      _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
> +      goto cleanup;
> +   }
> +
> +   disp->Device = dev;
> +
>     dri2_dpy->wl_modifiers =
>        calloc(ARRAY_SIZE(dri2_wl_visuals), sizeof(*dri2_dpy->wl_modifiers));
>     if (!dri2_dpy->wl_modifiers)
> @@ -1954,6 +1963,7 @@ static const __DRIextension *swrast_loader_extensions[] = {
>  static EGLBoolean
>  dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
>  {
> +   _EGLDevice *dev;
>     struct dri2_egl_display *dri2_dpy;
>  
>     loader_set_logger(_eglLog);
> @@ -1973,6 +1983,14 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
>        dri2_dpy->wl_dpy = disp->PlatformDisplay;
>     }
>  
> +   dev = _eglFindDevice(dri2_dpy->fd, true);
> +   if (!dev) {
> +      _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
> +      goto cleanup;
> +   }
> +
> +   disp->Device = dev;
> +
>     dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy);
>  
>     dri2_dpy->wl_dpy_wrapper = wl_proxy_create_wrapper(dri2_dpy->wl_dpy);
> diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
> index 118ce717b99..0e844962d7d 100644
> --- a/src/egl/drivers/dri2/platform_x11.c
> +++ b/src/egl/drivers/dri2/platform_x11.c
> @@ -1274,6 +1274,7 @@ disconnect:
>  static EGLBoolean
>  dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
>  {
> +   _EGLDevice *dev;
>     struct dri2_egl_display *dri2_dpy;
>  
>     dri2_dpy = calloc(1, sizeof *dri2_dpy);
> @@ -1284,6 +1285,14 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
>     if (!dri2_get_xcb_connection(drv, disp, dri2_dpy))
>        goto cleanup;
>  
> +   dev = _eglFindDevice(dri2_dpy->fd, true);
> +   if (!dev) {
> +      _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
> +      goto cleanup;
> +   }
> +
> +   disp->Device = dev;
> +
>     /*
>      * Every hardware driver_name is set using strdup. Doing the same in
>      * here will allow is to simply free the memory at dri2_terminate().
> @@ -1352,6 +1361,7 @@ static const __DRIextension *dri3_image_loader_extensions[] = {
>  static EGLBoolean
>  dri2_initialize_x11_dri3(_EGLDriver *drv, _EGLDisplay *disp)
>  {
> +   _EGLDevice *dev;
>     struct dri2_egl_display *dri2_dpy;
>  
>     dri2_dpy = calloc(1, sizeof *dri2_dpy);
> @@ -1365,6 +1375,14 @@ dri2_initialize_x11_dri3(_EGLDriver *drv, _EGLDisplay *disp)
>     if (!dri3_x11_connect(dri2_dpy))
>        goto cleanup;
>  
> +   dev = _eglFindDevice(dri2_dpy->fd, false);
> +   if (!dev) {
> +      _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
> +      goto cleanup;
> +   }
> +
> +   disp->Device = dev;
> +
>     if (!dri2_load_driver_dri3(disp))
>        goto cleanup;
>  
> @@ -1450,6 +1468,7 @@ static const __DRIextension *dri2_loader_extensions[] = {
>  static EGLBoolean
>  dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
>  {
> +   _EGLDevice *dev;
>     struct dri2_egl_display *dri2_dpy;
>  
>     dri2_dpy = calloc(1, sizeof *dri2_dpy);
> @@ -1463,6 +1482,14 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
>     if (!dri2_x11_connect(dri2_dpy))
>        goto cleanup;
>  
> +   dev = _eglFindDevice(dri2_dpy->fd, false);
> +   if (!dev) {
> +      _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
> +      goto cleanup;
> +   }
> +
> +   disp->Device = dev;
> +
>     if (!dri2_load_driver(disp))
>        goto cleanup;
>  
> diff --git a/src/egl/drivers/haiku/egl_haiku.cpp b/src/egl/drivers/haiku/egl_haiku.cpp
> index 287760661e5..dfdb90185c5 100644
> --- a/src/egl/drivers/haiku/egl_haiku.cpp
> +++ b/src/egl/drivers/haiku/egl_haiku.cpp
> @@ -207,8 +207,16 @@ extern "C"
>  EGLBoolean
>  init_haiku(_EGLDriver *drv, _EGLDisplay *dpy)
>  {
> +	_EGLDevice *dev;
>  	CALLED();
>  
> +	dev = _eglFindDevice(-1, true);
> +	if (!dev) {
> +		_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
> +		return EGL_FALSE;
> +	}
> +	disp->Device = dev;
> +
>  	TRACE("Add configs\n");
>  	if (!haiku_add_configs_for_visuals(dpy))
>  		return EGL_FALSE;
> diff --git a/src/egl/main/egldevice.c b/src/egl/main/egldevice.c
> index 26ecc50b5e0..8e7116c90f4 100644
> --- a/src/egl/main/egldevice.c
> +++ b/src/egl/main/egldevice.c
> @@ -30,6 +30,7 @@
>  #include "eglcurrent.h"
>  #include "egldevice.h"
>  #include "eglglobals.h"
> +#include "egllog.h"
>  #include "egltypedefs.h"
>  
>  
> @@ -37,6 +38,8 @@ struct _egl_device {
>     _EGLDevice *Next;
>  
>     const char *extensions;
> +
> +   EGLBoolean MESA_device_software;
>  };
>  
>  void
> @@ -47,6 +50,12 @@ _eglFiniDevice(void)
>     /* atexit function is called with global mutex locked */
>  
>     dev_list = _eglGlobal.DeviceList;
> +
> +   if (!dev_list)
> +      return;
> +
> +   /* The first device is on-stack allocated SW device */
> +   dev_list = dev_list->Next;
>     while (dev_list) {
>        /* pop list head */
>        dev = dev_list;
> @@ -74,6 +83,49 @@ _eglCheckDeviceHandle(EGLDeviceEXT device)
>     return (cur != NULL);
>  }
>  
> +static _EGLDevice software_device = {
> +   .extensions = "EGL_MESA_device_software",
> +   .MESA_device_software = EGL_TRUE,
> +};
> +
> +/* Looks up for device in DeviceList adding if there isn't one already.
> + *
> + * For software device lookup, the fd is ignored.
> + */
> +_EGLDevice *
> +_eglFindDevice(int fd, bool software)

"find()" doesn't really sounds like the function that builds the list
one device at a time.
How about _eglAddDevice() ?

> +{
> +   _EGLDevice *dev;
> +
> +   mtx_lock(_eglGlobal.Mutex);
> +   dev = _eglGlobal.DeviceList;
> +   /* The first device is always software */
> +   if (!dev) {
> +      _eglGlobal.DeviceList = &software_device;
> +      dev = _eglGlobal.DeviceList;
> +   }

You could avoid that (duplicated) runtime logic by just putting that
line in the initialisation of `_eglGlobal`

> +
> +   if (software)
> +      goto out;
> +
> +   dev = NULL;
> +
> +out:
> +   mtx_unlock(_eglGlobal.Mutex);
> +   return dev;
> +}
> +
> +EGLBoolean
> +_eglDeviceSupports(_EGLDevice *dev, _EGLDeviceExtension ext)
> +{
> +   switch (ext) {
> +   case _EGL_DEVICE_SOFTWARE:
> +      return dev->MESA_device_software;
> +   };
> +   assert(0);
> +   return EGL_FALSE;
> +}
> +
>  EGLBoolean
>  _eglQueryDeviceAttribEXT(_EGLDevice *dev, EGLint attribute,
>                           EGLAttrib *value)
> @@ -97,6 +149,30 @@ _eglQueryDeviceStringEXT(_EGLDevice *dev, EGLint name)
>     };
>  }
>  
> +/* Do a fresh lookup for devices.
> + *
> + * Walks through the DeviceList, discarding no longer available ones
> + * and adding new ones as applicable.
> + *
> + * Must be called with the global lock held.
> + */
> +static int
> +_eglLookupAllDevices(void)

Same issue, "lookup()" doesn't sound like what builds the list.
How about _eglRefreshDeviceList() ?

> +{
> +   _EGLDevice *dev;
> +   int count = 0;
> +
> +   dev = _eglGlobal.DeviceList;
> +   /* The first device is always software */
> +   if (!dev) {
> +      _eglGlobal.DeviceList = &software_device;
> +      dev = _eglGlobal.DeviceList;
> +   }
> +   count++;
> +
> +   return count;
> +}
> +
>  EGLBoolean
>  _eglQueryDevicesEXT(EGLint max_devices,
>                      _EGLDevice **devices,
> @@ -110,7 +186,7 @@ _eglQueryDevicesEXT(EGLint max_devices,
>  
>     mtx_lock(_eglGlobal.Mutex);
>  
> -   num_devs = 0;
> +   num_devs = _eglLookupAllDevices();
>     devs = _eglGlobal.DeviceList;
>  
>     /* bail early if we only care about the count */
> diff --git a/src/egl/main/egldevice.h b/src/egl/main/egldevice.h
> index 69bcc1572cc..945c25268e1 100644
> --- a/src/egl/main/egldevice.h
> +++ b/src/egl/main/egldevice.h
> @@ -29,7 +29,7 @@
>  #ifndef EGLDEVICE_INCLUDED
>  #define EGLDEVICE_INCLUDED
>  
> -
> +#include <stdbool.h>
>  #include "egltypedefs.h"
>  
>  
> @@ -52,6 +52,18 @@ _eglLookupDevice(EGLDeviceEXT device)
>     return dev;
>  }
>  
> +_EGLDevice *
> +_eglFindDevice(int fd, bool software);
> +
> +enum _egl_device_extension {
> +   _EGL_DEVICE_SOFTWARE,
> +};
> +
> +typedef enum _egl_device_extension _EGLDeviceExtension;
> +
> +EGLBoolean
> +_eglDeviceSupports(_EGLDevice *dev, _EGLDeviceExtension ext);
> +
>  EGLBoolean
>  _eglQueryDeviceAttribEXT(_EGLDevice *dev, EGLint attribute,
>                           EGLAttrib *value);
> -- 
> 2.18.0
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list