SchaeferGL - The New Plan
I managed to create all of the interfaces I needed and had started work in the Gallium3D state tracker when I ran into some problems. The first thing that I ran into is huge inconsistencies in driver performance. Because of this issue only a limited number of AMD graphics cards would actually benefit from the design I proposed. In addition Direct3D is designed to work with Windows windows when running in a window. I could hack around that but I suspect that would be a brittle integration. The other issue I've run into is the lack of documentation for Gallium3D. I've found a couple places to look but one is incomplete and the other is basically just a listing of methods and structures with almost no comments let alone usage examples. All of these issues have led me to take another look at the purpose of this project. The end goal of SchaeferGL is to allow D3D9 games such as EQ2 to run on Linux with good performance. My original assumption was that the approach that Wine took to handling Direct3D was the issue. However Valve's release of ToGL brings that into question as well. Valve was able to release a big name title using D3D9 over OpenGL.
With all of that in mind I started to look at the Nine state tracker, Wine's D3D9, and ToGL side by side. Right off the bat I noticed that the Wine implementation was doing more. In the first place they are calling lock and unlock methods but the other two implementations are not. Also when looking at the method for rendering indexed primitives there were allot more function calls in Wine's implementation. In fact they appeared to be using some kind of constant state object implementation. When I started I assumed ToGL and Wine's D3D9 would have similarities at least in the Direct3D method implementations. Another thing that I noticed in the ToGL code was comments in the indexed primitive method for example there was a note to be careful in that method because the implementation was "hot" which I take to mean that it has high impact on performance. I ran sysprof while running EverQuest 2 in Wine and sure enough that method was about 5-7% of the cpu time. To me this means the Valve spent the time to profile and tweak there implementation to achieve the performance they needed for their title.
Even though there is a possibility for increased performance the Wine team does not appear to have any intention of trying to integrate the ToGL changes. And to be honest I can't blame them because the code is structured completely different. In addition ToGL is D3D9 only and the current Wine D3D implementation has some support for 10 and 11. On top of all of that the wine implementation is actually more complete. So what is the solution? After digging into this issue the conclusion I've come to is that the best solution would be to allow the existing Wine3D to continue to grow and mature and instead create a new Direct3D library based on ToGL. Wine allows native libraries to be used per executable so if a PE format library that called OpenGL existed it should work inside of Wine. If that library were a drop in replacement for the Direct3D9 dll (including ABI compatibility) then it should allow users to leverage the performance of this implementation without loosing the features present in the Wine implementation for the applications that need them.
So, with all of this in mind here is the new plan for SchaeferGL. I will create a Direct3D9 library compiled with MSVC that calls OpenGL using modified ToGL code and the interfaces from the state-tracker implementation. Then I will test and profile this library on Windows to take other potential bottle-necks out of the equation. After I've completed the unit tests and have ensured the ABI is compatible I'll test it with EQ2 on Windows to make sure the implementation functions. If all of this works the next step will be to copy that library into a Wine installation and do final testing. I've already restructured the github repo and am ready to start moving the ToGL logic into the required structure.