egl: ensure a render node is passed to _eglFindDevice()
authorSimon Ser <contact@emersion.fr>
Wed, 15 Nov 2023 11:59:40 +0000 (12:59 +0100)
committerEric Engestrom <eric@engestrom.ch>
Sat, 18 Nov 2023 21:20:39 +0000 (21:20 +0000)
_eglFindDevice() will fail if it's not provided a render node:
the EGLDevice list only contains one entry per render node, plus
the special software device. Passing a primary node for a
display-only device will not work.

Signed-off-by: Simon Ser <contact@emersion.fr>
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10142
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Tested-by: Iago Toral Quiroga <itoral@igalia.com>
Tested-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Fixes: 2be404f5571a ("egl: error out if we can't find an EGLDevice in _eglFindDevice()")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26205>
(cherry picked from commit 0f978c34410283558afe9de5dab007f63a763c5e)

.pick_status.json
src/egl/drivers/dri2/egl_dri2.c

index 9fc1af0..dc34d5f 100644 (file)
@@ -84,7 +84,7 @@
         "description": "egl: ensure a render node is passed to _eglFindDevice()",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": "2be404f5571ada32d3b2e9cfe9b769846f27d68f",
         "notes": null
index 3e3ac3c..1ad4e9a 100644 (file)
@@ -1080,8 +1080,31 @@ dri2_setup_device(_EGLDisplay *disp, EGLBoolean software)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    _EGLDevice *dev;
+   int render_fd;
+
+   /* Extensions must be loaded before calling this function */
+   assert(dri2_dpy->mesa);
+   /* If we're not software, we need a DRM node FD */
+   assert(software || dri2_dpy->fd_render_gpu >= 0);
+
+   /* fd_render_gpu is what we got from WSI, so might actually be a lie and
+    * not a render node... */
+   if (software) {
+      render_fd = -1;
+   } else if (loader_is_device_render_capable(dri2_dpy->fd_render_gpu)) {
+      render_fd = dri2_dpy->fd_render_gpu;
+   } else {
+      render_fd = dri2_dpy->mesa->queryCompatibleRenderOnlyDeviceFd(
+         dri2_dpy->fd_render_gpu);
+      if (render_fd < 0)
+         return EGL_FALSE;
+   }
+
+   dev = _eglFindDevice(render_fd, software);
+
+   if (render_fd >= 0 && render_fd != dri2_dpy->fd_render_gpu)
+      close(render_fd);
 
-   dev = _eglFindDevice(dri2_dpy->fd_render_gpu, software);
    if (!dev)
       return EGL_FALSE;