I thought I would share my findings regarding recent research into the feasibility of replacing Pbuffers with FBOs in VirtualGL. I welcome feedback from the community regarding this. In summary, the aspects of FBOs that make them easier for applications to use make them much more difficult for VirtualGL to use.
The basic issue is that FBOs/RBOs have no concept of visual properties, but VirtualGL heavily relies on that feature of Pbuffers. For instance, if the application wants an OpenGL window with multisampling, double buffering, an accumulation buffer, etc., then it will call glXChooseVisual() with those desired attributes, and VirtualGL needs only translate those attributes into FB config attributes, acquire an appropriate FB config on the 3D X server, then create a Pbuffer using that FB config. The Pbuffer is a GLX drawable, so it is straightforward to remap the various GLX functions and use the Pbuffer handle instead of the window handle. This allows us to redirect all of the rendering into the Pbuffer at the GLX level without messing with OpenGL. Once the Pbuffer is made current, then all of the OpenGL rendering that occurs beyond that point will behave as if it was happening in a window, except that it will be off-screen. FBOs are a fundamentally different beast, since they are implemented at the OpenGL level. In order to use them in VirtualGL, it would be necessarily to emulate all of the basic visual properties that we get automatically whenever we use Pbuffers. To enumerate these: -- Double buffering: Would require setting up two RBOs, one to act as the front buffer and one to act as the back buffer, attaching both to the FBO, and intercepting various OpenGL calls (glReadBufer(), glDrawBuffer(), glDrawBuffers(), etc.) that deal with changing or reading the current buffer. glXSwapBuffers() would also have to be emulated by changing the RBO attachment order. -- Stereo: Similar to the above. Two additional RBOs (front right and back right) would need to be attached to the FBO in order to support quad buffering, and buffer constants (GL_FRONT_RIGHT, GL_BACK_RIGHT) would need to be intercepted and modified wherever those constants are used. -- Aux buffers: Similar to the above. An additional RBO would need to be created for each aux buffer, and the functions dealing with setting or getting the current buffer would need to be similarly modified. All of the above are doable, but there are a lot of potential pain points, as well as a high potential for hidden bugs and compatibility issues. For instance, OpenGL will automatically change the read or draw buffer at certain points without an explicit call to glReadBuffer()/glDrawBuffer(), so I would need to figure out what those points are and activate the appropriate RBO instead. Another issue is how to handle cases in which the application itself is rendering to an FBO. I would need to detect this and not remap the buffer constants in that case. Doable, but a lot of testing would be required, and I anticipate that some applications would break in the near term until the various issues were ironed out. -- Multisampling: It is necessary to use a different function (glRenderbufferStorageMultisample()) when creating the RBO in order to enable multisampling. -- Alpha channel: Similarly, an alpha channel is a property of the RBO, not a property of the FBO or its parent drawable. -- Stencil and depth buffers: Are also attached as separate RBOs. It is unclear exactly how stenciling works in concert with FBOs. I'm hoping that simply binding an FBO with a stencil buffer attachment will make stenciling work automatically, but this needs to be tested. Oddly, I couldn't find any clear documentation on this. -- Accumulation buffers: There doesn't appear to be any way of supporting these with RBOs. Although accum. buffers are an obsolete feature, VirtualGL is still used by a lot of applications that were written for OpenGL 1.1 and 2.0. One of the selling points of VirtualGL has always been that we don't get in the way of OpenGL-- we intercept mainly just GLX calls, so whatever version of OpenGL the application wants to use, it should "just work" as long as the underlying OpenGL library supports it. I'm less excited about the prospect of FBOs if I have to "apologize" for them, i.e. to state that they only work in certain cases. Also, it's a good bit more difficult to implement them if we have to retain support for Pbuffers as well, in order to support legacy apps. In addition to the concerns above, FBOs also create quite a lot of awkwardness with respect to how VirtualGL handles visuals. Currently, VirtualGL will obtain an FB config on the 3D X Server with a set of appropriate visual properties for a "virtual 3D window." VirtualGL relies on the GLXFBConfig structure as a storage mechanism for these visual properties. With FBOs, the GLXFBConfig attributes become irrelevant, because the visual properties are emulated by virtue of how the FBO is constructed and managed. However, VirtualGL still needs a way to store the visual properties. For instance, if an application requests a stereo visual, VirtualGL will currently find a stereo FB config on the 3D X server and use it to create a stereo Pbuffer. Thus, the stereo property is passed down from the FB config to the GLX context and then to the drawable. If the application wants to query the value of GLX_STEREO for a particular visual, it's easy to do, because we can just figure out which FB config is mapped to that visual and query GLX_STEREO for the FB config. With FBOs, it becomes either awkward or complicated. The awkward approach: we could just continue selecting an FB config with the application's desired visual attributes, use that FB config to create a hidden window on the 3D X server, and bind the FBO to that window. This is really unnecessary, though. In the above example, it isn't necessary to use a stereo FB config to support stereo, because stereo is now emulated using RBOs -- and it would certainly be advantageous to be able to support stereo on the server end without actually requiring a stereo-capable card. The complicated approach: The "right" thing to do, IMHO, is to set up our own table of "fake" GLXFBConfigs and expose these to the application instead of the real GLXFBConfigs provided by the 3D X server. That's potentially painful, though, for several reasons: for starters, it would require overriding the GLXFBConfig type with our own structure, which is a potential compatibility minefield. We'd have to be 100% certain that all touch points for this type are interposed. The main source of pain, however, is the fact that we'd still need to pass through the 3D X server's GLXFBConfig table to the application, because those "real" FB configs would still be necessary if the application wanted to create Pbuffers and 3D Pixmaps on its own. Our "fake" GLXFBConfig table would be used only for creating 3D windows. None of these are impossible problems, but they're definitely not easy problems either. FBOs would require fairly deep architectural changes to VirtualGL and quite a lot of testing, including probably running the OpenGL conformance suite, etc. Further, it doesn't appear that it would be possible to implement all of the legacy OpenGL features using FBOs, so it might be necessary to retain Pbuffer support for legacy apps. I was looking at this technology as a potential way to improve compatibility, but at the moment, it doesn't make much sense. It would perhaps improve hardware compatibility, but at the expense of introducing a lot of application compatibility issues and other bugs. As long as nVidia and AMD continue to provide good Pbuffer support, I'm inclined to maintain the status quo. ------------------------------------------------------------------------------ Open source business process management suite built on Java and Eclipse Turn processes into business applications with Bonita BPM Community Edition Quickly connect people, data, and systems into organized workflows Winner of BOSSIE, CODIE, OW2 and Gartner awards http://p.sf.net/sfu/Bonitasoft _______________________________________________ VirtualGL-Devel mailing list VirtualGL-Devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/virtualgl-devel