Where is the texture data stored

I have just been blindly creating texture names and then using glBindTexture when I want the texture to be used. In my app there is potential for up to 500M of textures that can be used at one time or another, and so I have been managing these using a disk cache.

When a texture gets swapped out to the cache, its data is deleted and when its needed again its allocated a new chunk of memory.

So the question is, when I do the initial bind, and glTexture2D thing, I pass a pointer to the current image data. However during the program this image may be in a different location when I use the glBindTexture with the appropriatte texture name.

It just occured to me that this might be a problem, but the app works fine, even transversing the scene so that all 500M of textures will eventually get displayed. Why does my App still work even when I shift the textures’s data? I’m thinking this is going to bite me later.

Thanks

The driver keeps around a copy of the texture data. The pointer itself is not saved.

  • Matt

Thanks Matt,

So, the driver maintains textures outside of video memory as well?

If I have a world with around 250-300M of textures, and a target system of 64M system and 32M Video RAM, can I just load and initially bind the textures (probably on first use), release my copy of the data and then forget about it? (except for the glBindTexture when I want it to be used of course).

I had always thought I would have to manage the textures myself, using a pool of system memory, and maybe a disk cache.

No, you will get really slow performance if you do that. The driver has to put the textures somewhere, and if you have only 96MB of total memory on the system, you’ll get horrible paging. Every time you render with a new texture, it’ll probably get paged off disk and then downloaded to video memory, and your app will chug.

You can try this and make sure it works first, but don’t be surpised if it’s slow.

I’d suggest maintaining your own cache, as you suggest. Allocate a bunch of textures at startup time, but not so many as to overflow system memory. If the texture you need is in the cache, you can bind it. If it’s not, decide which texture to discard, and use glTexSubImage (not glTexImage) to load new data into it, which you would read off disk.

This is the basic strategy, and there are a number of possible enhancements, such as using the texture base level functionality of OpenGL 1.2, precaching textures before you need them, and so on.

It’s a tricky problem, and there are no easy, fast solutions except to buy more memory.

  • Matt

Thats great Matt, thanks alot, funny thing is that now I know more about whats going on, its even more of a mystery why my app works. Just dumb luck I guess

I think I understand your suggestion and will give it a go and see what happens.

Matt,

Perhaps BK could try to use texture compression as well, if supported…

Having 500Mb of textures on a 96Mb system seems quite unreal even if managing textures properly…

Regards.

Eric

Hi Eric,

I had planed to implement texture compression at some stage, but you gotta walk first right. Just a question on that, Matt mentioned using glTexSubImage2D to reload a texture in preference to glTexImage2D, using compressed textures I understand you use glCompressedTexImage2D to load an already compressed image (which is the desirable way I guess). Is there an equivilent glTexSubImage for compressed textures, or is glCompressedTexImage2D it already.

Taken from http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt :

New Procedures and Functions

void CompressedTexImage3DARB(enum target, int level,
                             int internalformat, sizei width,
                             sizei height, sizei depth,
                             int border, sizei imageSize,
                             const void *data);
void CompressedTexImage2DARB(enum target, int level,
                             int internalformat, sizei width,
                             sizei height, int border, 
                             sizei imageSize, const void *data);
void CompressedTexImage1DARB(enum target, int level,
                             int internalformat, sizei width,
                             int border, sizei imageSize,
                             const void *data);
void CompressedTexSubImage3DARB(enum target, int level, 
                                int xoffset, int yoffset,
                                int zoffset, sizei width,
                                sizei height, sizei depth,
                                enum format, sizei imageSize,
                                const void *data);
void CompressedTexSubImage2DARB(enum target, int level, 
                                int xoffset, int yoffset,
                                sizei width, sizei height,
                                enum format, sizei imageSize,
                                const void *data);
void CompressedTexSubImage1DARB(enum target, int level, 
                                int xoffset, sizei width,
                                enum format, sizei imageSize,
                                const void *data);
void GetCompressedTexImageARB(enum target, int lod,
                              const void *img);

As you can see there is a glCompressedTexSubImage(1,2,3)D ! I was not sure about this myself, so thanks !

Eric