I've had a discussion with someone through this list about wine and libGL.so. It was about wine using dlopen("libGL.so") instead of linking directly with libGL.so.
I still don't understand why the wine developers have made this decision. I'm again at the point where I need to hook OpenGL (glX) functions ahd I have to patch wine again to make it work. There is absolutely no reason not to link with libGL.so directly: Even if you make OpenGL a hard dependency, nothing will break. Just announce it well so that everybody understands the change and make --disable-opengl the default option. Now everyone can get wine and it will work out-of-the-box and those who want opengl can enable it (and the distribution packagers should make sure wine depends on opengl when building the package).
tom
There is absolutely no reason not to link with libGL.so directly: Even if you make OpenGL a hard dependency, nothing will break. Just announce it well so that everybody understands the change and make --disable-opengl the default option. Now everyone can get wine and it will work out-of-the-box and those who want opengl can enable it (and the distribution packagers should make sure wine depends on opengl when building the package).
I do not agree with this suggestion. How many users want(or have to) override glx funtions, and how many users just build Wine from source and want OpenGL and Direct3D support?
It WILL lead to much confusion among users if OpenGL is disabled by default, no matter how well you annouce it. And those who know how to hook library functions will know about dynamic loading vs. linking at build time.
As a consent, I could think of a configure option --link-opengl, but I am not the one to decide this, and I think that too many options aren't really good too.
Why do you want to hook GL functions? I consider this a hacky workaround for bugs which should be fixed otherwise, but I might be wrong with this. The only thing I know is a workaround for the fglrx driver, but for Wine, this was fixed elsewhere.
Cheers, Stefan
Stefan Dösinger wrote:
Why do you want to hook GL functions? I consider this a hacky workaround for bugs which should be fixed otherwise, but I might be wrong with this. The only thing I know is a workaround for the fglrx driver, but for Wine, this was fixed elsewhere.
I want to create fraps for linux. Using XShmGetImage() and friends is too slow. So my first approach was to create a fullscreen opengl app and do glReadPixels(). But this performs very badly when there are two opengl applications running at the same time (fps drops from
100 down to ~10).
So my last approach was to call glReadPixels() from the same opengl context (the same opengl application). This is why I need to hook glXSwapBuffers(). Of course I could write a whole libGL.so with all the required functions, rename the real libGL.so to libRealGL.so, dlopen libRealGL.so from my libGL.so and propagate the function calls to the real opengl implementation, then wine would dlopen libGL.so (my library) and I could make whatever I need in glXSwapBuffers(). But this is overkill!
Now what are my options besides modifying the wine source?
tom
I want to create fraps for linux. Using XShmGetImage() and friends is too slow. So my first approach was to create a fullscreen opengl app and do glReadPixels(). But this performs very badly when there are two opengl applications running at the same time (fps drops from
Now what are my options besides modifying the wine source?
Do you mean the thing described at www.fraps.com?
It's certainly interesting, and hooking calls makes sense. There's for sure a point in it. However there may still be problems:
* There are some closed source games for Linux which load the library at run time. Your approach will fail here, just as it does with Wine. I don't know which games are affected, but I have read about this when searching for a workaround for the slow mouse pointer problem with fglrx.
* The fglrx driver: glReadPixels, glWritePixels, glTexImage2D and friends are _terribly_ slow with this driver( 1 fps when accessing the back buffer). Just follow the Direct3D discussions or search the archives, this problem has been discussed before, and it will come up again(At least when my DX7 patches are ready). Your glReadPixels approach won't work for radeon cards. I don't know a fix / workaround. If you have one, I'd really be glad!
Stefan
Stefan Dösinger wrote:
I want to create fraps for linux. Using XShmGetImage() and friends is too slow. So my first approach was to create a fullscreen opengl app and do glReadPixels(). But this performs very badly when there are two opengl applications running at the same time (fps drops from
Now what are my options besides modifying the wine source?
Do you mean the thing described at www.fraps.com?
exactly that thing :)
AnandTech has created a similar program (http://www.anandtech.com/linux/showdoc.aspx?i=2218). They've used the same approach as me, and for run-time linking, they modify the binary (which I don't want to do right now, too complicated ATM).
It's certainly interesting, and hooking calls makes sense. There's for sure a point in it. However there may still be problems:
- There are some closed source games for Linux which load the library at run
time. Your approach will fail here, just as it does with Wine. I don't know which games are affected, but I have read about this when searching for a workaround for the slow mouse pointer problem with fglrx.
- The fglrx driver: glReadPixels, glWritePixels, glTexImage2D and friends are
_terribly_ slow with this driver( 1 fps when accessing the back buffer). Just follow the Direct3D discussions or search the archives, this problem has been discussed before, and it will come up again(At least when my DX7 patches are ready). Your glReadPixels approach won't work for radeon cards. I don't know a fix / workaround. If you have one, I'd really be glad!
I have a nVidia 7800 GTX on a PCI-Express bus, and with a simple glReadPixels(), I can get ~700MB/s (makes ~140 fps at 5MB/frame, 1280x1024 RGBA). Is there another function which can be used for readback? I don't know any other OpenGL function that could be used for this. Is there any other?
What about asynchronous glReadPixels using PBOs, does this perform better on ATI cards? The nvidia SDK (for windows only) has a performance test application that can be used to measure the different readback techniques.
tom
Stefan Dösinger wrote:
- The fglrx driver: glReadPixels, glWritePixels, glTexImage2D and friends are
_terribly_ slow with this driver( 1 fps when accessing the back buffer). Just follow the Direct3D discussions or search the archives, this problem has been discussed before, and it will come up again(At least when my DX7 patches are ready). Your glReadPixels approach won't work for radeon cards. I don't know a fix / workaround. If you have one, I'd really be glad!
My approach wont work on older cards anyway. I'm using FBOs (which have been introduced recently) and maybe other features that require the latest drivers. My approach will also require a dual core or HT-enabled CPU.
My approach is: create a set (4 or 8) of objects, each holding a reference to a FBO and a PBO. This set is used for asynchronous readback. When the application calls glXSwapBuffers(), copy the frontbuffer to the FBO and issue an asynchronous glReadPixels() to the PBO. Then pass the object to the second thread and return so the app can continue. This is to reduce the time spent in glXSwapBuffers(), the FBO is used to create a consisten snapshot of the frontbuffer. The second thread maps the PBO (making the glReadPixels() transfer finish), uses the lzo compression algorithm to compress the pixels and writes the pixels (along with a timestamp, Window XID, dimensions (width,height) and probably other infos) to a file. For best performance, the destination file would be mapped to memory (mmap) and the lzo compression function would write the compressed data directly to the file. I see that there are still some unresolved issues (thread synchronization when accessing PBOs) but that is only a minor issue ;)
One note though, just one week ago I've had a nVidia 6800 on a 8x AGP bus. And I still could get ~500MB/s readback using glReadPixels(), that makes ~100 fps. This 1fps glReadPixels() is clearly an ATI issue. That's also why I would never buy an ATI card, because, honestly, they suck (I've had one, and it sucked badly, their drivers crashed the whole computer hardly when I've tried to play World of Warcraft).
tom
My approach is: ...
I can't comment on the technical details, because I am not an OpenGL expert at all. But I'd like to test it when you're finished. There may be a workaround for the glReadPixels slowlyness. I've seen that both mplayer and xine can draw a 2D movie fast onto an OpenGL texture, as long as the player window isn't overlapped too much. At least they pretend to use OpenGL to render the video. Once the window is overlapped, it becomes slow as hell( 1 fps, if not less).
One note though, just one week ago I've had a nVidia 6800 on a 8x AGP bus. And I still could get ~500MB/s readback using glReadPixels(), that makes ~100 fps. This 1fps glReadPixels() is clearly an ATI issue. That's also why I would never buy an ATI card, because, honestly, they suck (I've had one, and it sucked badly, their drivers crashed the whole computer hardly when I've tried to play World of Warcraft).
Sure it's an ATI driver bug. But I can't change my notebooks graphics chip ;) To be fair: The ATI driver is constantly improving, and it's really useable now. The only thing that bothers me right now, is the recent regression on old cards introduced with fglrx 8.19.10. I really hope they fix it.
How is the nvidia driver doing recently? Does it have acpi suspend support? How is the speed compared to the Windows drivers?
Stefan
Stefan Dösinger wrote:
How is the nvidia driver doing recently? Does it have acpi suspend support?
Can't comment, because my computer is a desktop computer, not a laptop and I havent tried suspend or sleep (I don't even know how to configure it).
How is the speed compared to the Windows drivers?
Can't comment either, I haven't windows installed here. Besides, do you know a relibale opengl test application for both windows and linux? glxgears isn't really a test application.
tom
Stefan Dösinger wrote:
How is the nvidia driver doing recently? Does it have acpi suspend support?
Seems like ACPI suspend isn't supported under amd64 :(
$ cat /sys/power/state standby mem
On Thu, 01 Dec 2005 16:12:47 +0000, Tomas Carnecky wrote:
I've had a discussion with someone through this list about wine and libGL.so. It was about wine using dlopen("libGL.so") instead of linking directly with libGL.so.
IIRC this was done so CodeWeavers can ship a GL enabled build. I don't see any reason to change it. Weak linking is usually a good thing.
Mike Hearn wrote:
On Thu, 01 Dec 2005 16:12:47 +0000, Tomas Carnecky wrote:
I've had a discussion with someone through this list about wine and libGL.so. It was about wine using dlopen("libGL.so") instead of linking directly with libGL.so.
IIRC this was done so CodeWeavers can ship a GL enabled build. I don't see any reason to change it. Weak linking is usually a good thing.
ddraw.dll uses dlopen on libGL, because there's code in ddraw that can work without libGL being present, and that is needed for some programs (eg. IE6) to run. dlopen'ing means Wine compiled on a machine with libGL can be run on a machine without libGL.
opengl32.dll is directly linked with libGL, since it's not useful without it.
If you're implementing your own shared library, you can probably try dlopen'ing the functions you need from that first, then falling back to dlopening from libGL.
Mike
Mike McCormack wrote:
Mike Hearn wrote:
On Thu, 01 Dec 2005 16:12:47 +0000, Tomas Carnecky wrote:
I've had a discussion with someone through this list about wine and libGL.so. It was about wine using dlopen("libGL.so") instead of linking directly with libGL.so.
IIRC this was done so CodeWeavers can ship a GL enabled build. I don't see any reason to change it. Weak linking is usually a good thing.
ddraw.dll uses dlopen on libGL, because there's code in ddraw that can work without libGL being present, and that is needed for some programs (eg. IE6) to run. dlopen'ing means Wine compiled on a machine with libGL can be run on a machine without libGL.
opengl32.dll is directly linked with libGL, since it's not useful without it.
If you're implementing your own shared library, you can probably try dlopen'ing the functions you need from that first, then falling back to dlopening from libGL.
At least you could do:
glHandle = dlopen("libGL.so", ...)
but later:
glXSwapBuffers_Ptr = dlsym(RTLD_NEXT, "glXSwapBuffers");
eg. use RTLD_NEXT instead of the real libGL handle. This would make it possible to preload my own library but wouldn't change the weak linking. In fact, that's how I've modified my local wine copy, and it worked.
tom
eg. use RTLD_NEXT instead of the real libGL handle. This would make it possible to preload my own library but wouldn't change the weak linking. In fact, that's how I've modified my local wine copy, and it worked.
Well, you have the patch now, so all you need to do is submit it ;)
Mike
Mike McCormack wrote:
eg. use RTLD_NEXT instead of the real libGL handle. This would make it possible to preload my own library but wouldn't change the weak linking. In fact, that's how I've modified my local wine copy, and it worked.
Well, you have the patch now, so all you need to do is submit it ;)
boils down to a one-line patch. RTLD_NEXT doesn't work, I have to use RTLD_DEFAULT to make wine (or the dynamic loader) use my functions.
tom
Hi,
boils down to a one-line patch. RTLD_NEXT doesn't work, I have to use RTLD_DEFAULT to make wine (or the dynamic loader) use my functions.
You should send patches to wine-patches@winehq.com to get them included.
Stefan
Stefan Dösinger wrote:
Hi,
boils down to a one-line patch. RTLD_NEXT doesn't work, I have to use RTLD_DEFAULT to make wine (or the dynamic loader) use my functions.
You should send patches to wine-patches@winehq.com to get them included.
Thanks. Once I have my local git copy I'll try to create the patch.
One question though: I've changed dlls/x11drv/opengl.c, but is it the only place I have to change? what about dlls/opengl32/* or dlls/wined3d/* ? Do both those modules use x11drv or do they use libGL.so directly?
tom