VirtualGL / virtualgl

Main VirtualGL repository
https://VirtualGL.org
Other
682 stars 103 forks source link

EGL back end: additional GLX extensions #134

Open dcommander opened 4 years ago

dcommander commented 4 years ago

The EGL back end does not currently support certain GLX extensions that are supported by the GLX back end:

It should be possible, but probably not straightforward in all cases (hence the "funding needed" tag), to support some or all of these.

dcommander commented 4 years ago

Challenges:

GLX_EXT_create_context_es2_profile: The main challenge here is the fact that, in EGL, the choice between an OpenGL and an OpenGL ES context is made by calling eglBindAPI() prior to calling eglCreateContext(). Because we're emulating Pbuffers using RBOs and maintaining a dedicated RBO context for that purpose, we potentially have to make the API choice before the 3D application calls glXCreate*Context*(). I don't know how to solve that dilemma without introducing some kind of hack, such as a global VGL environment variable that forces the use of the OpenGL ES API.

GLX_ext_texture_from_pixmap: The main challenge here is the fact that the EGL equivalent to glBindTexImageEXT()-- eglBindTexImage()-- operates on the default framebuffer, whereas the EGL back end stores the actual pixel data in RBOs. Thus, the emulation of glBindTexImageEXT() will not be straightforward.

GLX_ARB_create_context_robustness: nVidia's implementation of eglCreateContext() returns EGL_FALSE but does not set the EGL error if it is passed EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY. That's the only thing keeping the EGL back end from exposing GLX_ARB_create_context_robustness.

nwnk commented 1 year ago

Because we're emulating Pbuffers using RBOs and maintaining a dedicated RBO context for that purpose, we potentially have to make the API choice before the 3D application calls glXCreateContext().

Is there a reason to not use EGLImages instead? They're already scoped to be shared among APIs and contexts.

dcommander commented 1 year ago

Is there a reason to not use EGLImages instead? They're already scoped to be shared among APIs and contexts.

Believe me, I spent at least 500 hours over several years researching and developing the EGL back end. I consulted extensively with nVidia and explored all available avenues, including EGLImages. You can read more about the issues here: https://forums.developer.nvidia.com/t/sharing-render-buffers-or-render-textures-among-multiple-opengl-contexts/77168/1 and here: https://github.com/VirtualGL/virtualgl/issues/10

tl;dr: The fundamental problem with using an EGLImage to emulate a Pbuffer is that EGLImages do not support multisampling. Thus, it wouldn't be possible to preserve multisampled data across OpenGL contexts unless we used private renderbuffers, and that means using a shared RBO context as we are currently doing. The best we could do would be to use EGLImages only for single-sampled rendering, but that would greatly increase the complexity of the EGL back end. I simply didn't (and still don't) have the funding to pursue that kind of multi-pronged solution, and such a solution would be hard to maintain and support anyhow.

dcommander commented 6 months ago

Unfortunately, further research has revealed that it will be impossible to emulate GLX_EXT_create_context_es2_profile in the EGL back end. Because EGL doesn't support multi-buffered Pbuffer surfaces, VirtualGL has to emulate multi-buffered OpenGL windows using OpenGL renderbuffer objects (RBOs.) RBOs are bound to a specific OpenGL context, whereas GLXPbuffers are independent of context. Thus, in order to properly emulate a GLXPbuffer using an RBO, it is necessary to maintain a persistent OpenGL context (the "RBO context") and share it with every context that the 3D application explicitly requests (when the application calls one of the glXCreate*Context*() functions.) Since the shared RBO context must use the same API as the explicitly requested context, we would have to maintain a separate RBO context for OpenGL and OpenGL ES. That already breaks one of the assumptions of GLX_EXT_create_context_es2_profile, which is that the API is tied to the context rather than the drawable. (It should be possible to render to the same drawable using both OpenGL and OpenGL ES, as long as separate contexts are used for each API.) Furthermore, we don't know which API to use until the 3D application calls glXCreate*Context*(), but we might need to create an RBO context in the body of glXCreatePbuffer(), which could be called before glXCreate*Context*(). Thus, as far as I can tell, there is no way to properly implement GLX_EXT_create_context_es2_profile.