Summary: | Check OpenGL and OpenGL ES2.0 renderer info in one process | ||
---|---|---|---|
Product: | Mesa | Reporter: | Jammy Zhou <jammy.zhou> |
Component: | Mesa core | Assignee: | mesa-dev |
Status: | RESOLVED FIXED | QA Contact: | |
Severity: | normal | ||
Priority: | medium | ||
Version: | git | ||
Hardware: | Other | ||
OS: | All | ||
Whiteboard: | |||
i915 platform: | i915 features: | ||
Attachments: |
test case for get GL and GLES2 renderer in one process
hack to work patch to renderer_info |
Created attachment 40980 [details] [review] hack to work It may depend on your setup and the dynamic linker, but this patch to renderer_info.c may "fix" the issue, even with the "failed to remap ..." messages. Or alternatively, you can try linking to libGL.so directly when compiling and call glGetString directly. The bug here is that there are two copies of glapi: one in libGL.so and the other in libGLESv2.so. One of the things that glapi does is to manage the dispatch table of the current context. When the OpenGL ES context is first made current, the dispatch table in libGLESv2.so is updated. Calling glGetString from libGLESv2.so gives the correct result. But when the OpenGL context is made current, the dynamic linker decides to update the dispatch table in libGLESv2.so again. If you call glGetString from libGL.so, it will be no-op since the dispatch table in libGL.so is never updated. For the same reason, when the OpenGL context is created, the remap table in libGLESv2.so is updated. Since OpenGL has much more entry points than libGLESv2.so can handle, you will see the "failed to remap ..." messages after the entry points in libGLESv2.so run out. 16ee7a55ae26 only fixed core mesa (src/mesa/). It will only work when an app links to either one of libGL.so or libGLESv2.so, and use eglGetProcAddress to get the addresses of the entry points that are not statically available. But when both libGL.so and libGLESv2.so are used, the app will be affected by this bug. A fix to glapi (src/mapi/glapi/) is required. (In reply to comment #1) Thanks for the quick response and detailed explanation. > Created an attachment (id=40980) [details] > hack to work > > It may depend on your setup and the dynamic linker, but this patch to > renderer_info.c may "fix" the issue, even with the "failed to remap ..." > messages. Or alternatively, you can try linking to libGL.so directly when > compiling and call glGetString directly. With this patch, both GL and GLESv2 renderer info can be got successfully now. But this seems a little tricky, and in this case the dispatch table of GLESv2 is also used for OpenGL/GLX context. I am curious why "dlclose(gles2_handle);" didn't clean libGLESv2.so out of the address space? By the way, because I want to make my application independent of both libGL and libGLESv2, I cannot link it directly to libGL.so or libGLESv2.so. > > The bug here is that there are two copies of glapi: one in libGL.so and the > other in libGLESv2.so. One of the things that glapi does is to manage the > dispatch table of the current context. When the OpenGL ES context is first > made current, the dispatch table in libGLESv2.so is updated. Calling > glGetString from libGLESv2.so gives the correct result. > > But when the OpenGL context is made current, the dynamic linker decides to > update the dispatch table in libGLESv2.so again. If you call glGetString from > libGL.so, it will be no-op since the dispatch table in libGL.so is never > updated. > > For the same reason, when the OpenGL context is created, the remap table in > libGLESv2.so is updated. Since OpenGL has much more entry points than > libGLESv2.so can handle, you will see the "failed to remap ..." messages after > the entry points in libGLESv2.so run out. Hmm... resonable > > 16ee7a55ae26 only fixed core mesa (src/mesa/). It will only work when an app > links to either one of libGL.so or libGLESv2.so, and use eglGetProcAddress to > get the addresses of the entry points that are not statically available. > > But when both libGL.so and libGLESv2.so are used, the app will be affected by > this bug. A fix to glapi (src/mapi/glapi/) is required. (In reply to comment #2) > (In reply to comment #1) > Thanks for the quick response and detailed explanation. > > > Created an attachment (id=40980) [details] [details] > > hack to work > > > > It may depend on your setup and the dynamic linker, but this patch to > > renderer_info.c may "fix" the issue, even with the "failed to remap ..." > > messages. Or alternatively, you can try linking to libGL.so directly when > > compiling and call glGetString directly. > > With this patch, both GL and GLESv2 renderer info can be got successfully now. > But this seems a little tricky, and in this case the dispatch table of GLESv2 > is also used for OpenGL/GLX context. I am curious why "dlclose(gles2_handle);" > didn't clean libGLESv2.so out of the address space? Because it is linked to by st_GLESv2.so, which is not unloaded until the app exits. > By the way, because I want to make my application independent of both libGL and > libGLESv2, I cannot link it directly to libGL.so or libGLESv2.so. It should also work if you dlopen with RTLD_GLOBAL. But these are all (very bad) workarounds. It is still the best to fix the bug. > > > > The bug here is that there are two copies of glapi: one in libGL.so and the > > other in libGLESv2.so. One of the things that glapi does is to manage the > > dispatch table of the current context. When the OpenGL ES context is first > > made current, the dispatch table in libGLESv2.so is updated. Calling > > glGetString from libGLESv2.so gives the correct result. > > > > But when the OpenGL context is made current, the dynamic linker decides to > > update the dispatch table in libGLESv2.so again. If you call glGetString from > > libGL.so, it will be no-op since the dispatch table in libGL.so is never > > updated. > > > > For the same reason, when the OpenGL context is created, the remap table in > > libGLESv2.so is updated. Since OpenGL has much more entry points than > > libGLESv2.so can handle, you will see the "failed to remap ..." messages after > > the entry points in libGLESv2.so run out. > > Hmm... resonable > > > > > 16ee7a55ae26 only fixed core mesa (src/mesa/). It will only work when an app > > links to either one of libGL.so or libGLESv2.so, and use eglGetProcAddress to > > get the addresses of the entry points that are not statically available. > > > > But when both libGL.so and libGLESv2.so are used, the app will be affected by > > this bug. A fix to glapi (src/mapi/glapi/) is required. (In reply to comment #3) > (In reply to comment #2) > > (In reply to comment #1) > > Thanks for the quick response and detailed explanation. > > > > > Created an attachment (id=40980) [details] [details] [details] > > > hack to work > > > > > > It may depend on your setup and the dynamic linker, but this patch to > > > renderer_info.c may "fix" the issue, even with the "failed to remap ..." > > > messages. Or alternatively, you can try linking to libGL.so directly when > > > compiling and call glGetString directly. > > > > With this patch, both GL and GLESv2 renderer info can be got successfully now. > > But this seems a little tricky, and in this case the dispatch table of GLESv2 > > is also used for OpenGL/GLX context. I am curious why "dlclose(gles2_handle);" > > didn't clean libGLESv2.so out of the address space? > Because it is linked to by st_GLESv2.so, which is not unloaded until the app > exits. > > By the way, because I want to make my application independent of both libGL and > > libGLESv2, I cannot link it directly to libGL.so or libGLESv2.so. > It should also work if you dlopen with RTLD_GLOBAL. But these are all (very > bad) workarounds. It is still the best to fix the bug. I tried RTLD_GLOBAL before, but it doesn't work either. Yes, we need to fix the bug itself in mesa. ;) > > > > > > The bug here is that there are two copies of glapi: one in libGL.so and the > > > other in libGLESv2.so. One of the things that glapi does is to manage the > > > dispatch table of the current context. When the OpenGL ES context is first > > > made current, the dispatch table in libGLESv2.so is updated. Calling > > > glGetString from libGLESv2.so gives the correct result. > > > > > > But when the OpenGL context is made current, the dynamic linker decides to > > > update the dispatch table in libGLESv2.so again. If you call glGetString from > > > libGL.so, it will be no-op since the dispatch table in libGL.so is never > > > updated. > > > > > > For the same reason, when the OpenGL context is created, the remap table in > > > libGLESv2.so is updated. Since OpenGL has much more entry points than > > > libGLESv2.so can handle, you will see the "failed to remap ..." messages after > > > the entry points in libGLESv2.so run out. > > > > Hmm... resonable > > > > > > > > 16ee7a55ae26 only fixed core mesa (src/mesa/). It will only work when an app > > > links to either one of libGL.so or libGLESv2.so, and use eglGetProcAddress to > > > get the addresses of the entry points that are not statically available. > > > > > > But when both libGL.so and libGLESv2.so are used, the app will be affected by > > > this bug. A fix to glapi (src/mapi/glapi/) is required. I just tried latest mesa driver with the patch series of GL and GLES interop, but the problem is still there with the original test application attached. The GLES2.0 renderer info was NULL, and when call glGetString for GL, segmentation fault happened. If I add --enable-shared-glapi configure option, the GLES2.0 renderer info was still NULL, but the GL renderer info can be got successfully. Created attachment 42698 [details] [review] patch to renderer_info I am able to get GLES2 and GL renderer infos after applying this patch to renderer_info.c. It should use eglChooseConfig instead of eglGetConfigs to make sure the returned config can be used to create a window surface. I did my test with --enable-shared-glapi and egl_gallium. egl_dri2 would fail because of the missing _glapi_get_proc_address. I will see what can be done about that. (In reply to comment #6) > Created an attachment (id=42698) [details] > patch to renderer_info > > I am able to get GLES2 and GL renderer infos after applying this patch to > renderer_info.c. It should use eglChooseConfig instead of eglGetConfigs to > make sure the returned config can be used to create a window surface. > > I did my test with --enable-shared-glapi and egl_gallium. egl_dri2 would fail > because of the missing _glapi_get_proc_address. I will see what can be done > about that. After applying the patch for renderer_info, I still cannot get the renderer info for GLES2. Following messages were printed out. jammy@thinkpad-t400:~/tests$ EGL_DRIVER=egl_gallium ./renderer_info OpenGL ES2.0 Renderer: Not Available OpenGL Renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX/SSE2 (In reply to comment #7) > (In reply to comment #6) > > Created an attachment (id=42698) [details] [details] > > patch to renderer_info > > > > I am able to get GLES2 and GL renderer infos after applying this patch to > > renderer_info.c. It should use eglChooseConfig instead of eglGetConfigs to > > make sure the returned config can be used to create a window surface. > > > > I did my test with --enable-shared-glapi and egl_gallium. egl_dri2 would fail > > because of the missing _glapi_get_proc_address. I will see what can be done > > about that. > > After applying the patch for renderer_info, I still cannot get the renderer > info for GLES2. Following messages were printed out. > > jammy@thinkpad-t400:~/tests$ EGL_DRIVER=egl_gallium ./renderer_info > OpenGL ES2.0 Renderer: Not Available > OpenGL Renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 > DEVELOPMENT x86/MMX/SSE2 And after update to latest mesa master (commit a7293cbe5c5e2db29fb36842747da7dd62d9de06), I got segfault when run renderer_info. jammy@thinkpad-t400:~/tests$ EGL_DRIVER=egl_gallium ./renderer_info OpenGL ES2.0 Renderer: Gallium 0.4 on softpipe Segmentation fault Can you show me the result with EGL_LOG_LEVEL=debug set? Maybe also the backtrace? This is what I get when mesa is configured with --enable-shared-glapi: olvaffe@m500:~$ EGL_LOG_LEVEL=debug EGL_SOFTWARE=1 ./renderer_info libEGL debug: EGL search path is /usr/local/lib/egl libEGL debug: added /usr/local/lib/egl/egl_gallium.so to module array libEGL debug: added egl_dri2 to module array libEGL debug: added egl_glx to module array libEGL debug: dlopen(/usr/local/lib/egl/egl_gallium.so) libEGL info: use X11 for display 0x9791838 libEGL info: use software fallback libEGL debug: searching for pipe module swrast libEGL debug: loaded /usr/local/lib/egl/pipe_swrast.so couldn't open libtxc_dxtn.so, software DXTn compression/decompression unavailable libEGL debug: the best driver is Gallium libEGL debug: searching for st module GL libEGL debug: loaded /usr/local/lib/egl/st_GL.so Mesa warning: couldn't open libtxc_dxtn.so, software DXTn compression/decompression unavailable OpenGL ES2.0 Renderer: Gallium 0.4 on llvmpipe Mesa warning: couldn't open libtxc_dxtn.so, software DXTn compression/decompression unavailable OpenGL Renderer: Gallium 0.4 on i915 (chipset: 945GM) (In reply to comment #9) > Can you show me the result with EGL_LOG_LEVEL=debug set? Maybe also the > backtrace? > > This is what I get when mesa is configured with --enable-shared-glapi: > > olvaffe@m500:~$ EGL_LOG_LEVEL=debug EGL_SOFTWARE=1 ./renderer_info > libEGL debug: EGL search path is /usr/local/lib/egl > libEGL debug: added /usr/local/lib/egl/egl_gallium.so to module array > libEGL debug: added egl_dri2 to module array > libEGL debug: added egl_glx to module array > libEGL debug: dlopen(/usr/local/lib/egl/egl_gallium.so) > libEGL info: use X11 for display 0x9791838 > libEGL info: use software fallback > libEGL debug: searching for pipe module swrast > libEGL debug: loaded /usr/local/lib/egl/pipe_swrast.so > couldn't open libtxc_dxtn.so, software DXTn compression/decompression > unavailable > libEGL debug: the best driver is Gallium > libEGL debug: searching for st module GL > libEGL debug: loaded /usr/local/lib/egl/st_GL.so > Mesa warning: couldn't open libtxc_dxtn.so, software DXTn > compression/decompression unavailable > OpenGL ES2.0 Renderer: Gallium 0.4 on llvmpipe > Mesa warning: couldn't open libtxc_dxtn.so, software DXTn > compression/decompression unavailable > OpenGL Renderer: Gallium 0.4 on i915 (chipset: 945GM) I re-checked this problem, for egl_gallium driver, this problem is fixed no matter using eglGetConfigs or eglChooseConfig. jammy@jammy-ThinkPad-T400:~/tests$ EGL_LOG_LEVEL=debug EGL_SOFTWARE=1 ./renderer_info libEGL debug: EGL search path is /usr/lib/egl libEGL debug: added /usr/lib/egl/egl_gallium.so to module array libEGL debug: dlopen(/usr/lib/egl/egl_gallium.so) libEGL info: use X11 for display 0x13bba90 libEGL info: use software fallback libEGL debug: searching for pipe module swrast libEGL debug: loaded /usr/lib/egl/pipe_swrast.so libEGL debug: the best driver is Gallium libEGL debug: searching for st module GL libEGL debug: loaded /usr/lib/egl/st_GL.so OpenGL ES2.0 Renderer: Gallium 0.4 on softpipe OpenGL Renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT But with egl_dri2 driver, there is segmentation fault. jammy@jammy-ThinkPad-T400:~/tests$ EGL_LOG_LEVEL=debug EGL_DRIVER=egl_dri2 ./renderer_info libEGL debug: EGL search path is /usr/lib/egl libEGL debug: added /usr/lib/egl/egl_dri2.so to module array libEGL debug: dlopen(/usr/lib/egl/egl_dri2.so) Segmentation fault Because I am using an x86_64 system with a possible buggy gdb, it seems hard to debug the application and get the backtrace currently. But I can confirm that the segfault happens in eglInitialize. For the egl_gallium case, although I can get renderer info for both GL and GLES2, it seems that there are still some problem for later GL calling when run the triangle test application in my glproxy project. I got following error message, it seems that the dispatch table went wrong. Mesa: User error: GL_INVALID_ENUM in glGetHandleARB Mesa: User error: GL_INVALID_ENUM in glBeginQueryARB(target) Error: fragment shader did not compile! The details are given in: https://bugs.launchpad.net/glproxy/+bug/722430 The source code can be got in: https://code.launchpad.net/~jammy-zhou/glproxy/glproxy I built a clean mesa driver with latest master branch, and this problem has been fixed. Thanks, Chia-I. |
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.
Created attachment 40977 [details] test case for get GL and GLES2 renderer in one process Currently I am doing some experiments with mesa to check the renderer info of underlying OpenGL and OpenGL ES2.0 drivers to decide which driver to use at runtime. With my code attached, the renderer info for GLES2 can be got successfully, and although the EGL and GLES2 libraries are unloaded before creating the GLX context, glGetString(GL_RENDERER) for OpenGL still returns NULL. After enable MESA_DEBUG, I found the error message "GL User Error: calling GL function without a rendering context", and many warnings as "Mesa warning: failed to remap ....". I also changed the sequence for GL and GLES2, but got similar results. If do separately, both renderer info can be got successfully. And with the commit 16ee7a55ae269612263468195f2af998cb9ef695, the problem is still there.