Texture manager extension

What i’m proposing is an extension that gives some control onto the OpenGL’s texture manager… for a simple reason.

Correct me if i’m wrong. When you create a texture ( glTexImage2d for example ), it is uploaded to video memory, as needed, but a copy is also made in system or AGP memory, in case the texture is destroyed in video memory ( ie alt-tab, changing the resolution, etc… ). This can be seen as an advantage ( simplicity: the user doesn’t have to bother about this issue ), or a disadvantage, since it takes some more memory to store it. Quite frankly i’d prefer to have the possibility to check myself if a texture is still in video memory, and update it myself if not, as with surfaces in DirectX.

Here’s how i see it implemented:

  • glIsLost ( GLint tex ) : to tell if a texture was lost… if so it is the user’s responsability to bind the texture and glTexImage it again.
  • glEnable/Disable ( GL_LOST_TEXTURE_EXT ) to enable/disable the extension… could be done on a per-texture basis ( ie you could keep the OpenGL mechanism for some textures, and not for others ? ).

What do you think of that ?

Y.

In the case of Alt-Tabbing I’m pretty sure drivers could pull data back from vidmem if they wanted to; I think the sysmem copy is to handle pathological cases (think BSOD) where Windows can trash the contents of vidmem without giving the driver any warning. Several people have argued persuasively that by that point you’re pretty much screwed anyway. In any case, though, in the normal course of things the sysmem copy will get paged out to virtual mem pretty soon and stay there, so it shouldn’t have all that much impact on your app.

Not convinced by glIsLost() - it looks like a glGet by any other name (i.e. you’re pulling data from GL back to the app) and could have a similar performance hit in a pipelined implementation.

uhm. yer…

for a start, not every system that opengl touches is affected by BSOD, alt tab, pathological mindless operaitng systems, etc etc etc.

secondly, what you’re proposing isn’t an advantage ANYWAY. it just means more work on the programmer. Instead of alloc’ing a texture, binding it, and then FREEING the texture (because it’s copied by the driver) and thus still only have two copies of the texture around (one possibly in vid mem and the other in system mem), your solution has two copies (one possibly in vid mem, and the other in system mem), but you have to constantly poll the texture… well, noto hust ONE texture, but ALL textures to see if they need rebinding, or something. WTF do you do that efficiently, eh? suppose you have 1000 textures floating around the place… then thazt’ s a freak of a lot of effort. at least with the previous system the vid card has the oppurtunity to talk to its driver to TELL it what textures are being evicted and thus flag them for rebinding if they’re used again.

you can ask if a texture IS resident (glIsResident()), but… hmm

cheers,
John

I don’t really see the problem ? What i’m proposing is not fundamentally different than how D3D manages it ( as far as i know… i’m not a DX expert ).

MikeC:

As for glIsLost, it sure shouldn’t require a stall, or it would be useless. But there’s probably an efficient way to program it, no ?

John:

If not any system is affected by loosing video textures, don’t you think the redundant copy is even more useless ?

I 100% agree that it is more work for the programmer. But dividing by 2 the texture memory usage worths it 10 times in my opinion. You don’t have to check all the textures each time you use them, probably once per frame is enough ?

> your solution has two copies (one possibly in vid mem, and the other in system
mem)

No, i was proposing to keep only one copy: the one in video memory. Then if it no longer exists in video memory, you could know it with glIsLost, and upload it again youtself…

Y.

#ifdef _WINDOWS_
  /* need to check to see if the texture has been lost */
  if(glOurTextureHasGone()) { }
#else
  /* our sgi machine; do nothing, because it'll always be there */
#endif

so, the redundant copy is useless but only for a given implementation; but opengl is meant to abstract OVER the implementation.

In summary: as far as the programmer should be concerned WRT the opengl specs, once a texture is bound, then the system side of the mem can be safely deallocated. Wheter or not the opengl impl needs to copy that memory is up to the driver writers, and shouldn’t be part of the programmers job.

(As an analogy: some harddisks like parking their drive heads, or powering down. should we add some code to the C library so we can detect if the harddisk head has moved, and should MANUALLY realign it? no… of course not…)

I 100% agree that it is more work for the programmer. But dividing by 2 the texture memory usage worths it 10 times in my opinion. You don’t have to check all the textures each time you use them, probably once per frame is enough ?

well, checking them all the time IS what i mean by once per frame (since that’s when you’re going to use them).

No, i was proposing to keep only one copy: the one in video memory. Then if it no longer exists in video memory, you could know it with glIsLost, and upload it again youtself…

but where IS this magic copy that you pull out to repack video memory? if it’s not IN memory, then it must be on disk… so, you’re seriously advocating polling your plethroa of textures and reloading from disk any that are missing?
for a start, disk access is slow. Secondly, disk caches will probably store the texture in memory anyway (because you keep thrashing the texture file), and so you’ve automagically got your second copy; thirdly, you need to allocate memory to load the botmap from disk, THEN bind the texture and then free the texture memory (so, you spend a lot of your time with yet another copy of the texture) and thirdly, you’re doign a LOT of redundant checks to load in a LOT of textures from a slow resource.

the fact that your opengl driver feels it needs to copy texture memory isn’t opengl’s problem. it is an implementation detail because windows trashes vid mem.

cheers,
John

[This message has been edited by john (edited 04-01-2001).]

> as far as the programmer should be concerned WRT the opengl specs, once a texture is bound, then the system side of the mem can be safely deallocated.

What i’m proposing is an extension, not a modification of the OpenGL specification. I don’t see where the problem is. If you don’t want to use it, don’t use it, that’s all. The vertex array range extension also modifies the behavior of the driver ( by not making redundent copies of the vertex array ), and it gives a huge performance boost. My proposal is also a modification of the driver behavior, and it would greatly reduce the memory usage. Yet you surely don’t have a problem with VARs, do you ?

> but where IS this magic copy that you pull out to repack video memory? if it’s not IN memory, then it must be on disk… so, you’re seriously advocating polling your plethroa of textures and reloading from disk any that are missing?

Yes, that’s exactly what i’d be doing. Loading it from the disk. That’s surely a slow way to do it, but it’s a rare event. If you did an alt-tab, who cares if just after, you loose one or two seconds reloading the textures ? Don’t you think that, if you’ve got 32 Mb of textures, using a permanent 32 Mb of system memory to keep a copy in case textures are lost once an hour is just a waste of ressource ?

I’ll even go further. Think about procedural textures that you need to modify each frame, or about dynamic lightmaps. Since you can’t access the driver’s system texture, you must keep your own copy in system memory too. Damn, that’s already 3 copies: 1 in video, 1 in system for the driver, and 1 for yourself. I don’t want to sound like i’m ranting, but i don’t like to see memory wasted like that…

Y.

If it is true that every single texture is being backed up in AGP memory, then yes it is a huge waste in resources.

But why would anyone want to have to check whether a texture is present or not and load from hardisk? Do you know how long it will take to load 32 MB of data of a hard disk?

This isn’t solving the problem if you ask me.

V-man

Well, that’s just that 99,999% of the time, these 32 Mb of memory are not in use, they’re just “sleeping”. Using so much memory for something you don’t use, or hardly ever use, seems a incredible waste to me. Give the choice to the programmer !!

Y.

> What i’m proposing is an extension, not a modification of the OpenGL specification.

As a quick response to this - extensions are all proposed modifications of the core specification. Not all of them are accepted into the core language, but all are candidates. The purpose of the extension mechanism is so that features can be exposed rapidly, then gradually incorporated into the core as they prove themselves - not to add behaviour contrary to OpenGL standards (not saying you are).

So proposing an extension /is/ proposing a change to the specification.

– Jeff

That’s an interesting way to look at extensions. However, a number of extensions are designed around a specific hardware platform. I seriously doubt that any NV extension will be implemented by ATI, for instance, simply because the hardware will not match the interface provided in the extension.

Also, many extensions add behaviour contrary to OpenGL standards. NV_Vertex_Array_Range, for instance, rewrites the entire vertex array mechanism. It breaks many of the vertex array specifications, and it is allowed to do so because it is an extension.

The purpose of extensions is not to add features that one would like to have as part of the OpenGL core, but to add features that the OpenGL core does not have, yet a particular implementation would like to provide access to. I, for one, would not want to see Register Combiners become part of OpenGL (especially since the extension likely mirrors NVIDIA hardware), and I seriously doubt that was NVIDIA’s intent when they developed the extension. They simply wanted to provide an interface to a portion of their hardware that OpenGL didn’t allow access to.

Ysaneya has a good point - there can be a very good reason for wanting the driver to avoid making that extra texture copy . Making the copy consumes host memory and takes time. So if you are calling SubTexImage2d every frame, you end up with two copies of the texture in host memory, and some performance loss due to the time the CPU spends on the memcpy. And when you are streaming many MB of image data every frame, this IS an issue.

However, Ysaneya’s glIsLost() proposal can not work on a pre-emptive OS. This is because a context switch can be made after glIsLost() returns, but before the next statement is executed. This context switch can then swap out the texture which you just inquired about. So your program can easily end up in a state whereby it believes the texture is OK, but is in fact “lost”.

Kim

The way I understand Direct3D handles this (from reading the docs, as I don’t program Direct3D) is not by allowing to query for invalidated textures, but by invalidating the entire rendering context. Once the rendering context is invalidated, no actual rendering will take place (therefore Kim’s pre-emptivity problem doesn’t exist). The program then needs to deallocate and reallocate all resources (textures, display lists…). This is a lot of work, but it’s only after the program regains control, and not while it is running, and therefore adds no real cost to rendering, as it can be done in event handlers, or by using a check at the start of each frame.

About extensions - what are WGL extensions if not Windows specific extensions?