Over the past several days, I've been working with some people in #winehackers on a way to help solve the problems Wine faces with OpenGL.. namely the lack of useable onscreen pixel formats and broken child windown rendering. Here's a patch for your perusal in hopes to generate feedback.
What this does is, it renders GL to an offscreen buffer the size of the window it's rendering to, first trying a redirected window (if you have the Xcomposite extension), then falling back to GLXPixmaps (which may be slower, especially if you don't have AIGLX). The offscreen buffer is then copied to the window it should be displaying on using X, acting in a manner nearly identical to how Vista composites OpenGL (as described here: http://www.opengl.org/pipeline/article/vol003_7/ ).
Given that it uses X to do the final composite, it obeys all clipping regions, which means it works even on obscured child windows. And since it's offscreen, it won't interfere with, or be bothered by, Wine's window. It also allows it to use other visuals/pixel formats than Wine's window (not done in this patch yet).
There is a speed hit, however. The DX9 swap chains demo, which gets about 280 FPS for me normally, gets about 80 to 90 FPS with the compositing method. It seems to be a ceiling though, as other more GPU intense apps have no extra noticeable slow down. Still, as an optimization, it can render directly to the window when it's being used on the whole window and the selected pixel format matches the current visual (this bit is disabled in the patch since it's for testing offscreen rendering, but it's simple to re-enable).
Further, a registry setting (HKCU\Software\Wine\X11 Driver\CompositeGL) can be used to force GL compositing off to give you the current behavior (single onscreen pixel format, broken child window rendering).
This obviously isn't the final patch, however it's likely what the final result will be like, forgoing unforeseen issues. Questions and comments are welcome.
On Wednesday 22 August 2007 03:36, Chris Robinson wrote:
Over the past several days, I've been working with some people in #winehackers on a way to help solve the problems Wine faces with OpenGL.. namely the lack of useable onscreen pixel formats and broken child windown rendering. Here's a patch for your perusal in hopes to generate feedback.
What this does is, it renders GL to an offscreen buffer the size of the window it's rendering to, first trying a redirected window (if you have the Xcomposite extension), then falling back to GLXPixmaps (which may be slower, especially if you don't have AIGLX). The offscreen buffer is then copied to the window it should be displaying on using X, acting in a manner nearly identical to how Vista composites OpenGL (as described here: http://www.opengl.org/pipeline/article/vol003_7/ ).
I'll add some more info here as for sure people will ask about it. In short during the Winex11.drv window management rewrite Wine lost dedicated X11 windows for Direct3D/OpenGL (before everything had an X11 child window). This has broken windowed OpenGL for years.
Suggested solutions at the time were to use glxpixmap rendering. At the time that was only accelerated on Nvidia hardware. More about this below.
The other solution was the use of glScissor/glViewport to limit GL rendering to the place on the gui were GL was needed. This worked a bit on some drivers but there were SwapBuffers related issues, second it would also have clipping issues and the scissors/viewport override caused issues for pbuffers/fbos.
At the beginning of this year we looked at several methods of 'X11 child window injection' for GL. A few methods were tried. They had the same clipping issues as the scissors path but for the rest it worked. While it fixed most drawing issues, it got X event issues back. The win32 parent window would receive X expose events and in the end those would confuse programs.
The Xorg guys suggested that those events would get away when we would use automatic redirection using Composite. Even then the events are there though they are harmless but they still cause the same troubles.
The current solution takes advantage of (upcoming) changes in Xorg drivers. Thanks to Compiz and friends, developers are adding AIGLX, hw accelerated glxpixmap rendering and redirected gl rendering support to their display drivers. Right now all this stuff is still limited to Nvidia but other drivers are getting support. At least the intel driver and r300 will support it in Xorg 7.4 (you can get a preview of it in the TTM branches of both drivers, in case of Intel that's i915tex).
This solution is the best way to go. Luckily Microsoft made similar changes in Vista.
There is a speed hit, however. The DX9 swap chains demo, which gets about 280 FPS for me normally, gets about 80 to 90 FPS with the compositing method. It seems to be a ceiling though, as other more GPU intense apps have no extra noticeable slow down. Still, as an optimization, it can render directly to the window when it's being used on the whole window and the selected pixel format matches the current visual (this bit is disabled in the patch since it's for testing offscreen rendering, but it's simple to re-enable).
Demos like DX9 swap chains / 3DMark are heavily GPU limited e.g. they push the card to its limits. Normal programs are most of the time cpu limited. They are GPU limited ofcourse if you run the program on a system which the program considers lowend.
Regards Roderick Colenbrander
This solution is the best way to go. Luckily Microsoft made similar changes in Vista.
Conceptually its probably correct, but I think the speed hit is pretty large, and it's not like we've got a lot of performance to spare. As for the Vista comparison... Vista isn't exactly well known for it's OpenGL performance either. What is the performance hit for something like the CSS stress test? That should be a bit more representative than dx9 swapchains.
I'm certainly not saying it's not a good idea, but I do think the performance hit shouldn't be quite as noticeable.
On Wednesday 22 August 2007 20:57, H. Verbeet wrote:
This solution is the best way to go. Luckily Microsoft made similar changes in Vista.
Conceptually its probably correct, but I think the speed hit is pretty large, and it's not like we've got a lot of performance to spare. As for the Vista comparison... Vista isn't exactly well known for it's OpenGL performance either. What is the performance hit for something like the CSS stress test? That should be a bit more representative than dx9 swapchains.
I'm certainly not saying it's not a good idea, but I do think the performance hit shouldn't be quite as noticeable.
There are two distinct cases. You have programs that use a toplevel for GL/D3D rendering (in general this is the case for games). Further you have 'windowed' programs e.g. programs that mix GL/D3D with a GDI gui. The use of GL Composition is limited to these 'windowed' programs. So the performance hit is also only limited to those programs. In my case the hit in the dx9 swap chains and the dx8 dolphin demo is about 1/3th but still there's a hit. As I said before in cpu limited cases I don't expect problems.
Roderick
On 22/08/07, Roderick Colenbrander thunderbird2k@gmx.net wrote:
There are two distinct cases. You have programs that use a toplevel for GL/D3D rendering (in general this is the case for games). Further you have 'windowed' programs e.g. programs that mix GL/D3D with a GDI gui. The use of GL Composition is limited to these 'windowed' programs. So the performance hit is also only limited to those programs. In my case the hit in the dx9 swap chains and the dx8 dolphin demo is about 1/3th but still there's a hit. As I said before in cpu limited cases I don't expect problems.
I thought it was required in both cases to get additional pixel formats?
On Wednesday 22 August 2007 21:10, H. Verbeet wrote:
On 22/08/07, Roderick Colenbrander thunderbird2k@gmx.net wrote:
There are two distinct cases. You have programs that use a toplevel for GL/D3D rendering (in general this is the case for games). Further you have 'windowed' programs e.g. programs that mix GL/D3D with a GDI gui. The use of GL Composition is limited to these 'windowed' programs. So the performance hit is also only limited to those programs. In my case the hit in the dx9 swap chains and the dx8 dolphin demo is about 1/3th but still there's a hit. As I said before in cpu limited cases I don't expect problems.
I thought it was required in both cases to get additional pixel formats?
Right now there's still only a single pixelformat. We would like to add more pixelformats but toplevel windows are the problem right now. The proper way to support more pixelformats on it is to recreate windows. Though doing this is not trivial but it must be done.
Roderick
Am Mittwoch, 22. August 2007 20:57 schrieb H. Verbeet:
This solution is the best way to go. Luckily Microsoft made similar changes in Vista.
Conceptually its probably correct, but I think the speed hit is pretty large, and it's not like we've got a lot of performance to spare. As for the Vista comparison... Vista isn't exactly well known for it's OpenGL performance either. What is the performance hit for something like the CSS stress test? That should be a bit more representative than dx9 swapchains.
I'm certainly not saying it's not a good idea, but I do think the performance hit shouldn't be quite as noticeable.
I think for applications like css, we shouldn't activate that code at all. css renders to a top level window, so it doesn't have any clipping problems. The pixel format problem should be fixed in other ways, like making it safe to recreate X11 windows, as it seems to be needed for other things too.
I have tested this with a few apps. Simple d3d8 and d3d7 demos work nicely, but the mfctex and mfcfog samples crash with a GLXBadDrawable in X_GLXMakeCurrent. Wine also complains about missing GLX_MESA_copy_sub_buffer, but it does that in both working and broken demos. I also tried the warcraft 3 map editor, it fails with the bad drawable error too, and windows media player 10. The alchemy visualization doesn't crash, but it doesn't update the screen either.
But it looks very promising. The apps that work look nice now :-)
On Wednesday 22 August 2007 12:58:18 pm Stefan Dösinger wrote:
I think for applications like css, we shouldn't activate that code at all. css renders to a top level window, so it doesn't have any clipping problems. The pixel format problem should be fixed in other ways, like making it safe to recreate X11 windows, as it seems to be needed for other things too.
It would be simple to do this on WGL's end and let it render directly to a window after recreating it with the proper visual, although the actual recreation may be tricky. As it is though, it can already use the window directly if the requested format matches the visual, and it wouldn't be hard to add a Wine-specific GL extension for WineD3D to use, if present, to get the current format.
I have tested this with a few apps. Simple d3d8 and d3d7 demos work nicely, but the mfctex and mfcfog samples crash with a GLXBadDrawable in X_GLXMakeCurrent.
A whole bunch of GLX errors will need to be ignored, especially in the case of GLXPixmaps (where the current method to resize is very crude, given the lack of a method to resize pixmaps like you can windows). I didn't get those in my testing though, so I didn't know if which needed to be ignored yet.
Wine also complains about missing GLX_MESA_copy_sub_buffer, but it does that in both working and broken demos.
That extension is generally required for the GLXPixmap method to work, since the GLX specs say that glXSwapBuffers has no effect on them. However, both MESA and nVidia's binary drivers seem to have an effect anyway (others may also as well). Obviously we can't rely on that, but it should work as-is for (future) single-buffered modes, and I plan on attempting to use other methods and extensions to get a more reliable swap effect.