32-bit 2GB limitations has reared its ugly limitation head on me more often recently than I would like.
2GB limitations sounds all nice and dandy for a console, but on the PC you have double copies of all your data in both RAM and VRAM. It sucks. Granted VRAM is windowed, but that single extra copy can eat up a lot of space. High end video cards have 1.5GB of VRAM in it for example. If you had a double copy of all that data in RAM, then you should have less than 512mb for your game. That being said I'm using up nowhere near 1.5GB of VRAM, but the thought that in a couple years that I could is troubling.
So naturally, the first angle I attacked is don't let D3D manage the resources in video/main memory. IE, do it manually yourself and store the copies on disk, not in RAM. That worked out great, except in the cases where you actually can't do that cause you need the RAM copies around. Which unfortunately is more often than I would like. In that case you can sometimes compress the data while its not in immediate use. (Its also worth noting that if you go the route of manual resource management you may need to pay attention to LRU resources and flush them to disk if a VRAM allocation fails.)
One thing that did help though was that on Win7/Vista 64-bit you can enable /LARGEADDRESSAWARE and are then able to use the entire 4GB of address space. Which is awesome. Except that some parts of D3D9 are not really made to work with that very well. One of the problems arises with D3DXHANDLE. Negative numbers are handles, and positive numbers are pointers to strings. This just doesn't work with >2GB address space. You can hack around it by detecting when the D3DXHANDLE is actually a string and not a handle and then copying that string to a store of addresses which are under 2GB. So far this has worked out. However, the looming threat that external libraries might do these tricks in other places is a bit scary.
Its disturbing that they are selling Win 7/Vista 32-bit copies. Are they crazy? Get rid of 32-bit! don't keep it around! This was obviously not an engineering decision and had much more to do with business. Somewhere there is an engineer at Microsoft who told them it was a bad idea. I feel your pain. This is really going to cause problems in a couple years for everybody. Having to support a 2GB address space is hell if your memory constrained, and in a few years we will all be memory constrained when making PC games.
Something else to keep an eye on:
Its typical to use default parameters when using CreateThread, however this is bad when you have lots of threads. A game usually has a stack size of multiple megabytes these days. Each CreateThread called with default parameters will have an address space reservation of the same size as the executable's main thread. It adds up.