Skip to main content
GameDev.net gamedev.net
🔒 Locked

"throwing away" specific mip map levels?

Started by coderchris Jun 23, 2008 at 10:03 PM 4 replies 1.7k views
Original Post
coderchris
coderchris
So, i have a basic texture manager that loads from disk any textures that are needed by my render system. Now, lets say an object starts getting quite far from the camera such that only the mipmaps > 4 are visible (for example). What I would like to do is free from memory the top 3 mimaps as they are no longer needed at the moment. By free I mean that, to the gfx card, the 4th mipmap is actualy now the top most (level 0) mipmap. My rendersystem is cross API. As far as directx 9 goes, there is a convenient function for managed textures, "SetLOD()" which allows me to do just what I want. However, for directx 10 and opengl, I can find no equivelent. The only way I can think to do this management with the other API's is to completely free the entire texture, then recreate the whole texture with only the mipmaps I want. This would involve reading the original texture from disk again, unless i keep a local copy of the original data in system ram, as well as the obvious cost of freeing/allocating texture memory. My question: is there a smarter way to do this, or am i stuck with freeing/reallocating the texture each time i want to remove/add a mipmap? A side question: relatively how expensive is texture memory allocation ( with for example directx's CreateTexture() )?
Jbs
Jbs
One thing you might want to investigate is adding a mipmap bias to that texture to sort of modify the mipping calculations. In essence, when the texel-to-pixel ratio is calculated to determine the mip level, you can apply a certain adjustment to the value which will affect the final level which is used. You might be able to set the bias such that it always picks your nth level.

OpenGL Reference
DirectX References
OrangyTang
OrangyTang
In OpenGL, the texture lod extension can force it to only use a subset of the mipmaps. This is handy when loading as you can load the lower mipmaps and force it to use those while you're still loading in the (bigger) high level mipmaps. However if you use it for unloading I'm not sure how you'll actually reclaim the memory rather than it just sitting idle.
ebray99
ebray99
Forcing the driver to use only certain mipmaps probably won't help you much. The big issue that I ran into in a game I worked on was the sheer amount of memory being used, and using LODs didn't help by any real amount (we were actually blowing out our 2GB address space towards the end of the project).

While what I recommend requires more work, it's well worth the effort. I recommend using a streaming system to load high resolution textures on demand. If you simply keep low resolution textures in memory all of the time, then you can use them as a fallback for your high resolution textures in the event that a high resolution texture isn't in memory and needs to be streamed in. If a high resolution texture isn't used in a while, then simply free it.

Basically, what you end up with is a system where all textures loaded in memory are low resolution, and high resolution textures are only loaded when they're actually needed. Using this approach dropped over 1GB of memory usage on a project I worked on.

Kevin B
coderchris
coderchris
thanks for the replies!

texture lod looks interesting, but i was hoping to actually free the top mipmaps rather than simply not use them, but thanks

I kindof like the idea of streaming my textures. Im wondering though, how exactly does this streaming work?

The way I image it is like this: If i find that i need a certain high res texture, I allocate a new texture of that size then start loading the texture from disk (in a separate thread). then when thats done, lock the texture and load the data into it.

If thats how you did it, I assume the cost of allocating the texture memory for the high res texture does not take long?
ebray99
ebray99
Yeah, that pretty much describes it. However, I allocated a bunch of high res textures up front at application start up. When file loading on the other thread was done, I would simply lock the texture and fill it with the loaded data. The only problem with that is that you have to be prepared for what would happen if you run out of pre-allocated textures. In that case, I would simply allocated more and added them to the pool. I'd do a garbage collection pass every so often to shrink the pool. Try to keep texture allocation down to 1 per frame max. Ideally, you would allocate all of your textures up front and simply manage the textures yourself. Drivers tend to do a crappy job of managing lots of resources (though it's not really their fault per se... it's a very difficult task to manage memory optimally and efficiently without shuffling things around in memory a lot). That said, try to keep the texture allocation/deletion to a minimum if possible, otherwise you're setting yourself for BSODs in WinXP or random driver crashes under Vista (but at least they're not BSODs =)).

Kevin B

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.