NVIDIA software fallback

Hi,

this is an old problem but still should be solved. On all Geforce 6x and 5x NVIDIA hardware I get a complete non-recovering software fallback under linux. It occurs when I upload lots of textures and then resize the window. The driver then falls back to the software renderer and does not return to hw acceleration until I restart the application.

Is there an upper limit in GL for the amount of textures one can upload and how can I query that if it exists? Or is that simply a bug in NVIDIA’s texture memory management? Or is there a workaround, e.g. by following a specific ordering when creating a GL context, the textures, shaders etc.

Any help is highly appreciated…

A window resize does this? I’ve done some graphics development in Linux with large textures and window resizes using NVIDIA cards and never had that problem.

It sounds like a memory management bug, although a larger window requires more graphics memory and that could potentially start lots of memory paging that would grind performance to a halt.

Some nasty things can happen with graphics memory management, it’s not just a case of requiring space, sometimes contiguous space is required and this can have complex paging repercussions with different sized images, their MIP maps and the need to use specific memory for best performance.

It’s never a good idea to oversubscribe graphics memory and even worse to use up your GART mapped memory but the drivers should handle this or report an error.

Software fallback is a perfectly legitimate recourse but still probably a bug in your case. Slow performance can be caused by things other than software rendering.

You might want to increase your AGP GART mapped memory in the BIOS and see if that helps.

> A window resize does this? I’ve done some graphics development in Linux with large textures and window resizes using NVIDIA cards and never had that problem.

I’m pretty sure that I’m doing nothing special, a simple (Qt based) app and really lots of 3D textures that cannot be held completely in the graphics RAM, and there you have it. I don’t consider it a good solution to do the texture memory management manually by using lots of glTexSubImage calls since that would certainly be a performace problem.

> It sounds like a memory management bug, although a larger window requires more graphics memory and that could potentially start lots of memory paging that would grind performance to a halt.

The system doesn’t halt, but the renderer gets really sloooow. Nevertheless the renderer continues to work, a clear sign for a kind of software fallback.

> Some nasty things can happen with graphics memory management

I see, but the driver always knows how much graphics mem is available, doesn’t it. So, when a window resize requests a certain amount of mem the textures could be easily rearranged.

> It’s never a good idea to oversubscribe graphics memory and even worse to use up your GART mapped memory but the drivers should handle this or report an error.

There is no error report. I always check for errors after each gl call.

> Software fallback is a perfectly legitimate recourse but still probably a bug in your case. Slow performance can be caused by things other than software rendering.

How can I find out if I have a sw fallback? There’s no way in GL to find out, right?

> You might want to increase your AGP GART mapped memory in the BIOS and see if that helps.

I’ll try. But the “aperture” is usually limited, too. Btw. is it legal in GL to create more textures than the graphics mem plus AGP aperture? I think I’ll have situations where this will be the case. The driver could then simple swap data between agp and “normal” memory, in AFAIR it does.

Michael

It is perfectly legal to try but at some point the teximage call after a new bind will fail and give you an error. It just won’t let you oversubscribe.

What’s different about your situation is you resize the window after creating your texture objects… if you’re on the border of oversubscription and a framebuffer resize suddenly uses more memory you could be in a world of hurt. An excellent implementation would slow down instead of crashing, but you’d hope there would be some paging (the point of fast memory IS fast contiguous paging, but that may not mean migration and says nothing about unmapped system memory) so unless your draw calls used all of that memory at some point everything you use you’d hope would migrate to fast memory (in theory but not in practice on a lot of PC implementations). Some graphics implementations deliberately don’t use LRU paging schemes on assets like textures because this can be pathologically bad for round robin rendering (a reasonably common case), so you can’t really blame bad behavior in this case on paging strategy.

Now what memory is useable for graphics resources is entirely up to the driver. A driver could in theory use unmapped system memory, I don’t think they do though (for driver allocated fast stuff like textures, not user allocated space/client stuff)(maybe in your emergency buffer resize case).

The AGP aperture is the the ammount of GART mapped memory available for DMAs. It’s the same thing and there is an upper limit (256MB I think) but you should at least try increasing this as a first step.

One possible strategy to fix this may be to begin with a large framebuffer allocation to begin with even if the window is small, you can always free that before a resize. Some approach like that would could avoid your problem. Just starting with a large window and making it smaller may also work, it may not free (?).

Remember this is somewhat speculative, we don’t get to see what the driver actually does.

dorbie,

> Now what memory is useable for graphics resources is entirely up to the driver. A driver could in theory use unmapped system memory, I don’t think they do though

In fact they do (at least it looks like that), you can upload really large amounts of textures and everything works well. I think the software fallback is triggered in a situation like that (more textures than video ram plus agp aperture can hold).

> One possible strategy to fix this may be to begin with a large framebuffer allocation to begin with even if the window is small, you can always free that before a resize. Some approach like that would could avoid your problem.

That could work. But unfortunately I don’t like such workarounds. In my opinion, either the GL implementation should simply work in such a case (which is not so easy, I know) or there should be a way to query the limits of the implementation - if there are any :wink: In practice there are lots of limits and often we cannot query them even though it is clear that they have to exist.

Grrrr.

> Just starting with a large window and making it smaller may also work, it may not free (?).

I’ll try …

perhaps do what i do and with screenresize delete all textures shaders etc and then reload them again once youve created the new resolution sized window

zed,

Hoooo. So I have to hold another copy of all my textures in main memory, in addition to the copy the GL does itself. That’s double the memory footprint. I don’t like that, you understand.

u dont store the texture data for textures that come from files etc, just thier filenames like so.
obviously if the window has dynamic resize u only wanna reload/build textures after the user has finished altering the window size

struct Texture
{
GLuint textureID;
char texture_name[ MAX_FILENAME_LENGTH ];
GLubyte *pixels;
bool texture_came_from_file; // some are constructed from data in the program eg shadowmaps, usually though theyre loaded from the HD

};

zed,

reloading all textures from hard disk would surely work. But it would mean to reload about 200 MB of data. That should take some seconds…not very friendly