Bug 100627

Summary: EGL fails to fall back to DRI2 when DRI3 is enabled but not available
Product: Mesa Reporter: rezny
Component: EGLAssignee: mesa-dev
Status: RESOLVED MOVED QA Contact: mesa-dev
Severity: normal    
Priority: medium    
Version: 17.0   
Hardware: All   
OS: FreeBSD   
Whiteboard:
i915 platform: i915 features:

Description rezny 2017-04-09 11:55:02 UTC
DRI2 will be available but DRI3 may or may not depending which kernel and drivers are running. When Mesa is compiled with DRI3 support enabled and run on a kernel with only DRI2 support, applications using GLX work fine (modulo scary messages), but applications that use EGL fail. The cause appears to be insufficient checking during init in libEGL.

The GLX init code has separate dri3_create_screen and dri2_create_screen functions which are called from the respective init function. When the former bails with "libGL error: Version 7 or imageFromFds image extension not found\nlibGL error: failed to load driver: r600", libGL then tries the DRI2 path and succeeds. As an aside, it would be nice if the first message was only shown if LIBGL_DEBUG is set, and the second should indicate that DRI3 init has failed but DRI2 will be attempted instead of saying the driver failed to load (which is a source of spurious bug reports).

The EGL path on the other hand only has a dri2_create_screen function which is called from both dri2_initialize_x11_dri2 and dri2_initialize_x11_dri3. Thus the init path succeeds for DRI3 even though it cannot work, so the application ultimately fails because the first detectable error is after we are out of the init routines and it's too late to attempt a fallback to DRI2. Setting LIBGL_DRI3_DISABLE allows applications using EGL to function correctly, so there is a work-around until the initialization can be fixed to check availability of DRI3 support as is done in libGL.

Example of failure running mesa EGL demos:

% LIBGL_DEBUG=verbose EGL_LOG_LEVEL=debug MESA_DEBUG=1 eglgears_x11                     
libEGL debug: Native platform type: x11 (autodetected)
libEGL debug: added egl_dri2 to module array
libGL: Can't open configuration file /home/user/.drirc: No such file or directory.
libEGL debug: DRI2: dlopen(/usr/local/lib/dri/r600_dri.so)
libEGL debug: found extension `DRI_Core'
libEGL info: found extension DRI_Core version 1
libEGL debug: found extension `DRI_IMAGE_DRIVER'
libEGL info: found extension DRI_IMAGE_DRIVER version 1
libEGL debug: found extension `DRI_DRI2'
libEGL debug: found extension `DRI_ConfigOptions'
libEGL debug: found extension `DRI2_Fence'
libGL: Can't open configuration file /home/user/.drirc: No such file or directory.
libGL: Can't open configuration file /home/user/.drirc: No such file or directory.
libEGL debug: found extension `DRI_TexBuffer'
libEGL info: found extension DRI_TexBuffer version 2
libEGL debug: found extension `DRI2_Flush'
libEGL info: found extension DRI2_Flush version 4
libEGL debug: found extension `DRI_IMAGE'
libEGL info: found extension DRI_IMAGE version 12
libEGL debug: found extension `DRI_RENDERER_QUERY'
libEGL debug: found extension `DRI_CONFIG_QUERY'
libEGL debug: found extension `DRI2_Throttle'
libEGL debug: found extension `DRI2_Fence'
libEGL debug: found extension `DRI2_Interop'
libEGL debug: found extension `DRI_TexBuffer'
libEGL debug: found extension `DRI2_Flush'
libEGL debug: found extension `DRI_IMAGE'
libEGL debug: found extension `DRI_RENDERER_QUERY'
libEGL info: found extension DRI_RENDERER_QUERY version 1
libEGL debug: found extension `DRI_CONFIG_QUERY'
libEGL info: found extension DRI_CONFIG_QUERY version 1
libEGL debug: found extension `DRI2_Throttle'
libEGL debug: found extension `DRI2_Fence'
libEGL info: found extension DRI2_Fence version 2
libEGL debug: found extension `DRI2_Interop'
libEGL info: found extension DRI2_Interop version 1
libEGL debug: did not find optional extension DRI_Robustness version 1
libEGL info: Using DRI3
libEGL debug: the best driver is DRI2
EGL_VERSION = 1.4 (DRI2)
zsh: segmentation fault (core dumped)

As can be seen, libEGL runs right through the DRI3 init and then crashes when it tries to draw without having a surface. The backtrace differs according to the driver in use. This is just an example from my machine:

(lldb) bt
* thread #1
  * frame #0: r600_dri.so`_debug_assert_fail(expr="surface", file="state_tracker/st_atom_framebuffer.c", line=61, function="update_framebuffer_size") at u_debug.c:321
    frame #1: r600_dri.so`update_framebuffer_size(framebuffer=0x000000080a845028, surface=0x0000000000000000) at st_atom_framebuffer.c:61
    frame #2: r600_dri.so`update_framebuffer_state(st=0x000000080a843000) at st_atom_framebuffer.c:181
    frame #3: r600_dri.so`st_validate_state(st=0x000000080a843000, pipeline=ST_PIPELINE_RENDER) at st_atom.c:219
    frame #4: r600_dri.so`st_Clear(ctx=0x000000080a85ff00, mask=18) at st_cb_clear.c:409
    frame #5: r600_dri.so`_mesa_Clear(mask=16640) at clear.c:224
    frame #6: 0x0000000000401fde eglgears_x11`___lldb_unnamed_symbol6$$eglgears_x11 + 14
    frame #7: 0x0000000000403a37 eglgears_x11`___lldb_unnamed_symbol30$$eglgears_x11 + 295
    frame #8: 0x0000000000401e97 eglgears_x11`___lldb_unnamed_symbol3$$eglgears_x11 + 423
    frame #9: 0x0000000000401bef eglgears_x11`___lldb_unnamed_symbol1$$eglgears_x11 + 383
Comment 1 Emil Velikov 2017-07-04 11:01:45 UTC
Rezny, nicely spotted. The EGL codebase is missing a few checks analogous to the GLX one. At the same time the i915/i965 are missing a drmGetCap(sPriv->fd, DRM_CAP_PRIME) call analogous to st/dri.

Can you spin some patches and send them to the list [1]?

I've seen you added some patches to FreeBSD - please send patches upstream alongside the FreeBSD ones. it should make the whole process a bit quicker/easier.

[1] https://www.mesa3d.org/submittingpatches.html
Comment 2 GitLab Migration User 2019-09-18 18:07:24 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/mesa/mesa/issues/158.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.