Direct3D on Linux via Gallium State Tracker
In my previous post I talked a little bit about a state tracker that I discovered that claims big gains in performance for Direct3D 9 games running under Wine. I was planning on waiting for Wayland but I wanted to test this thing out. I converted my guest PC into a Peppermint Linux machine. The open source AMD graphics driver has direct rendering support for it's graphics card so it makes a good test machine. Unfortunately neither the nine state tracker nor the wine patches made it into their respective upstream projects. What this means is compiling code from source and installing the libraries & headers yourself. It's a shame because this seems like a good enhancement but it only applies to Linux (Wine is cross-platform) and only to open source drivers so this hasn't received the interest I think it deserves. Below are the steps I've taken so far to get this up and running.
- Download and extract the modified Mesa-3D and wine source. https://github.com/chrisbmr/Mesa-3D/tree/gallium-nine https://github.com/chrisbmr/wine/tree/d3dadapter9-wip
- cd Mesa-3D-gallium-nine
- CFLAGS="-m32" CXXFLAGS="-m32" ./autogen.sh --prefix=/usr --with-gallium-drivers=nouveau,r600,swrast --enable-nine --with-gallium-driver-dir="`pwd`/src/gallium/targets/pipe-loader/.libs" --enable-debug --enable-texture-float --with-dri-drivers= --disable-dri --disable-opengl --disable-egl --disable-vdpau --disable-xvmc --disable-gbm --disable-gallium-llvm --enable-32bit --disable-64bit
- ln -s "`pwd`/lib/gallium/libd3dadapter9.so.0.0.0" /usr/lib32/
- ln -s "`pwd`/lib/gallium/libd3dadapter9.so.0" /usr/lib32/
- ln -s "`pwd`/lib/gallium/libd3dadapter9.so" /usr/lib32/
- ln -s "`pwd`/include/d3dadapter" /usr/include/i386-linux-gnu/
- cd ../wine-d3dadapter9-wip
- LDFLAGS=-lpthread CFLAGS="-pthread" CXXFLAGS="-pthread" ./configure
- for f in d3d9.dll gdi32.dll user32.dll wineps.drv winex11.drv; do mv /usr/lib/x86_64-linux-gnu/wine/$f.so /usr/lib/x86_64-linux-gnu/wine/$f.so.old ln -s "`pwd`/dlls/`basename -s .dll $f`/$f.so" /usr/lib/x86_64-linux-gnu/wine/ done
There are a couple if things I should mention regarding these steps. If nine isn't built as 32bit (-m32) then 32bit wine won't load it. Also the pthread related flags on the configure are there because without them I was getting an error indicating that the 32bit libraries for d3dadapter could not be found. After digging through the configure.log I found that there was a linker error because -pthread hadn't been used. That fixed that issue and then I went to build and I got an error about missing pthread references. Naturally if I'm including pthread I need to tell the linker about it hence the -lpthread in the LDFLAGS. Another thing to note is that if the nine libraries don't build as 32bit for some reason wine won't find them. So you can do "ldconfig --print-cache | grep d3d" so see if they are 32bit or 64bit. If they say x86_64 then something went wrong and you should try building Mesa-3d again. Also to complete the build steps you will need to install the build dependencies for wine and mesa. In theory you could use something like "apt-get build-dep wine:i386" but when I tried it apt-get would switch to the 64bit package. I ended up installing a bunch of :i386 packages directly in apt-get. Basically trying to build and then installing packages for each of the build errors. I have to believe there is a better way to do this but multilib seems to have complicated matters. All of these instructions are based on README in the nine branch but I had to modify them to make them work.
What was the result of all of this? Well currently nothing I tried to run EverQuest2 and I got the same FPS as before so I can't tell if it is even running or if the silent fall-back to the default D3D implementation kicked in. Also it appears there haven't been any commits to that branch for four months.