## Using Hardware OpenGL acceleration from Nvidia on your TNT card ## Jordan K. Hubbard If you're like me, you probably picked up one of the cheap Nvidia TNT AGP cards when they first came out, perhaps just so you could have 16MB of video memory to play with and not have to suffer reduced pixel depths at (practical) higher resolutions ever again. You probably also got the XFree86 project's SVGA server working on it, just as I did, and were impressed at how well it worked just as a basic X display card. But still, something felt vaguely missing and that, of course, was the 3D performance that these cards are so well known for. Sadly, the XFree86 documentation was quite explicit on this point: This was a 2D server, using only 2D features of the card, and that was that. No 3D acceleration for us TNT users! Happily, all of this changed a short time ago thanks to a new spirit of cooperation at Nvidia along with some timely hacking by the folks at Precision Insight, the XFree86 project and the Mesa team. The end result is that we can now develop FreeBSD-native OpenGL applications which take advantage of a number of the TNT card's features, accelerating 3D drawing performance to the point where it's actually what I would consider "usable" for basic animation and visualization work. Just to give one example, the archetypal OpenGL "gears" demo, run at the same resolution and depth each time, goes from 55fps with software rendering to 240fps with glx hardware rendering. More practically, a number of OpenGL demos which were formerly in the "huh?" category actually make sense now that I can see them running at their intended speed. This is a speed-up which is well-worth the effort if you're into OpenGL at all. :-) With that in mind, what follows is a step-by-step guide for modifying XFree86 3.3.3.1 and Mesa 3.0 on your system to use hardware 3D support on any Riva TNT or Riva TNT2 based card - this includes cards made by Hercules, STB, Diamond and other manufacturers. If it has a TNT chip on it, it should work. I also assume FreeBSD 3.1 or greater and a fairly recent ports collection. If your ports collection is significantly out of date with respect to your distribution, you may wish to consider updating it (see http://www.freebsd.org/ports) before proceeding with this checklist. I also assume that you have good net connectivity for fetching patches and such. 1) First, execute the following commands to fetch the files you'll need from Nvidia: fetch ftp://ftp1.detonator.nvidia.com/pub/drivers/english/riva-tnt-tnt2-vanta/linux/XFree86-3_3_3_1.diff fetch ftp://ftp1.detonator.nvidia.com/pub/drivers/english/riva-tnt-tnt2-vanta/linux/riva_glx-0.99.tar.gz fetch ftp://ftp1.detonator.nvidia.com/pub/drivers/english/riva-tnt-tnt2-vanta/linux/Mesa-3_0.diff If you have trouble getting to these URLS, or you wish to view the top-level site information, please go to: http://www.nvidia.com/Products.nsf/htmlmedia/software_drivers.html which will also display license information (basically: "it kills you, it's your fault"). One way or another, you want to get the XFree86 diffs, the riva_glx package and the Mesa 3.0 diffs into a local directory somewhere. Once you've done this, go on to the next steps where we'll install the XFree86 and Mesa 3.0 ports, assuming for the purpose of these examples that $STUFF points to the directory where you stored the files fetched during this step. 2) Build and install the XFree86 port with the following commands: cd /usr/ports/x11/XFree86 && make patch cd work && patch < $STUFF/XFree86-3_3_3_1.diff cd ..; make all install # NOTE: Do NOT do a clean! That comes later. In the last step, XFree86 will ask you a bunch of questions about which servers to build. If you don't want to be picky and have CPU time to burn, you can just whack the ENTER key through all these questions unless you feel like typing "NO" for all the extraneous servers. You're only interested in XF86_SVGA anyway. Once XFree86 has built and installed, you next need to edit your /etc/XF86Config file (if you're installing X for the very first time then you can run XF86Setup at this point and create your initial XF86Config file, which you should then come back and edit). You're basically looking to do two principal things here: o Change the default depth to 16. These accelerations won't work at 8, 24 or 32 bit depths and you'll see it fall-back to software rendering at those depths, which buys you nothing. You're basically looking for the DefaultColorDepth keyword, which you can change to 16. o Add to the file (outside of any other section) the following 3 lines: Section "Module" Load "glx.so" EndSection In my case, this is at the very end of the file. Don't worry about what this means yet, we've still to build and install the glx module. We're doing this now since we might just as well get the config file edits out of the way while we're thinking about it. Save the config file and go on to step 2b (don't clean the XFree86 port, don't restart your X server, just moooove along! :-). 3) Build and install the Mesa 3.0 port with the following commands: cd /usr/ports/graphics/Mesa3 && make patch cd work/Mesa-3.0 && patch < $STUFF/Mesa-3_0.diff # See NOTE 1 cd ../..; make all install # NOTE: Do NOT make clean afterwards. NOTE 1: This patch will actually apply with some rejects. Don't worry about them - if you go examine each .rej file, you'll see that they're actually all in the comments and don't affect the functionality of the code. This step should end with Mesa informing you that it's all installed and registered. Go on to step 4. 4) Now that we've installed the patched XFree86 and Mesa bits, we can build Nvidia's GLX module for the XFree86 server along with their GL library for OpenGL clients to link with. This is done with the following commands: cd /usr/ports/tcl80 # For tclsh. Can also use tcl81 make all install && make clean # This one we can clean now. :) cd /some/tmp/directory # we need some temporary build room tar xvzf $STUFF/riva_glx-0.99.tar.gz # unpack the bits we got earlier cd glx-0.99 # adjust paths with sed sed -e 's;XSERVTOP = .*;XSERVTOP=/usr/ports/x11/XFree86/work/xc;' \ -e 's;MESATOP = .*;MESATOP=/usr/ports/graphics/Mesa-3.0/work/Mesa-3.0;' \ < Config > Config.new && mv Config.new Config vi libGL/Imakefile servGL/serverglx/Imakefile # Hand edit coming up! >>> change all instances of tclsh to tclsh8.0 (or tclsh8.1) <<< xmkmf # now we can make our makefile make Makefile # more Makefile bootstrapping make Makefiles # make the rest of the makefiles. make all install # build and install it all This last step will run for awhile, building the complete OpenGL (GLX) rendering module which will later be dynamically loaded into the server, along with the client libraries you'll need for talking to this GLX server extention. That last bit will involve going into /usr/X11R6/lib and changing some things around with symlinks in order to get our OpenGL apps to talk to the GLX renderer rather than the "classic" Mesa software renderer. The following commands should do the trick: cd /usr/X11R6/lib mv libMesaGL.a libMesaGL.a.old # deal with future static apps mv libMesaGL.so.14 libMesaGL.so.14.old ln -s libGL.a libMesaGL.a ln -s libGL.so.1 libMesaGL.so.14 The resulting symlink forest may seem a little confusing at first glance but it works and, what's more, will work for any OpenGL applications you've already compiled. If you've got xlockmore installed, for example, then you're in for a bit of a surprise the next time it brings up one of its OpenGL-based screensavers. :) 5) Now that we've installed the new X server, installed the new Mesa, written over parts of Mesa with the Nvidia GLX port and edited the X config file to load the glx.so module on startup, it's time to restart your X server (or start it for the first time, perhaps) so that we can see if all this junk has worked. The very first thing you want to do once the new server comes up (and if it doesn't, check your permissions and where the /usr/X11R6/bin/X symlink is pointing) is this: xdpyinfo | egrep 'depth of|GLX' You should see the following output if everything is operating according to plan so far: GLX depth of root window: 16 planes If you don't see a GLX string in there, your module has not been loaded for some reason. Perhaps the glx install step fell over and you didn't notice - is there a /usr/X11R6/lib/modules/glx.so file and is it readable to the server? If the answer to that question is yes, next check your /etc/XF86Setup file again and make sure there's a Module section and Load line, as specified in step 2. Similarly, if the depth of the root window is not 16 bits then you must have missed an important DefaultColorDepth keyword somewhere - go look through /etc/XF86Config again as directed in step 2. 6) Assuming that xdpyinfo is reporting good things, you're now ready to test your first OpenGL application. Assuming that you've followed instructions to the letter so far, you should be able to simply do this: cd /usr/ports/graphics/Mesa3/work/Mesa-3.0/demos ./gears You should now see a set of gears spinning at a rather impressive 200-250fps on a stock Riva TNT card. The best a PII/450 generally gets with the software renderer is 60fps, just by way of comparison, and slower machines will naturally see an even more impressive difference. :) If that didn't work, you may wish to go check your symlinks again, depending on the failure of the gears program to execute. If it's whining about missing libraries, you most certainly want to check your symlinks; perhaps you got one backwards? :) 7) You're now done with all the temporary bits, you can get rid of your unpacked glx-0.99 bits (wherever you put them) and you can also do: cd /usr/ports/graphics/Mesa3 && make clean cd /usr/ports/x11/XFree86 && make clean To get rid of all the temporary cruft we've accumulated during this exercise. Of course, like anyone with a new toy you're now keen to see it do a lot more than spin a bunch of gears around, and there's happily quite a bit more out there for the budding OpenGL addict. First on the list is the previously mentioned xlockmore program; if you don't have it already installed, you can install and test it like this: cd /usr/ports/x11/xlockmore && make all install && make clean xlock -nolock -mode moebius # ants *crawl* without hardware support! xlock -nolock -mode sproingies # an all-time favorite xlock -nolock -mode bubble3d # wow, so that's what that looks like! :) Some other good screensavers to try are atlantis, cage and morph3d. Of course, no OpenGL discussion would be complete without mentioning the Quake2 for Linux port, something which will also work with your new GLX module but I'm not a quake player so that's something which I'll leave as an exercise for the reader. :) Some of the existing FAQs such as: http://www.nvidia.com/Marketing/Products/Pages.nsf/pages/linuxfaq provide more information on using GLX with quake. IMPORTANT NOTE: Most, if not all, of this 3D hardware rendering support will be in the upcoming 4.0 release of XFree86 (no predictions on the release date). What you're getting with this stuff is simply a preview of coming attractions! Also see the OpenGL resource page at http://www.opengl.org for more demo programs and other useful OpenGL information. Books like the OpenGL Programming Guide (Addison-Wesley, ISBN 0-201-63274-8) are also useful guides if you'd like to take advantage of this new speed in creating your own OpenGL game or demo masterpieces. Happy rendering! - Jordan $Id: tnt.txt,v 1.1 2000/02/16 08:07:53 jim Exp $