Skip to main content
gamedev.net
🔒 Locked

Resource management

Started by Shinpou Dec 31, 2008 at 1:41 PM 11 replies 3.5k views
Original Post
Shinpou
Shinpou
Hi everyone and a happy new year. So, I'm designing a game engine for a project that we're doing in a small group, and here are some questions regarding OpenGL. I've googled the hell out of it, and have understood that OpenGL handles the texture management when it comes to moving textures from RAM to VRAM, but what I don't understand is the process: - Does OpenGL copy the texture to VRAM, or move it? - When OGL is done with it, does it put it back to RAM. (If it was moved) - When the pixel data is in RAM, can I somehow take the pixel-data out and leave the openGL handle hanging or remove the handle entirely, and then load the texture up to RAM when it's needed again. If I do that, should I try to pre-emptively buffer data to memory before it's actually used. (I guess loading data exactly when it is needed would slow up things considerably) My plan is to implement something similar to Scott Bilas' handle based resource manager, and be able to swap resources in and out of memory based on usage patterns to achieve a system where no loading is needed. Any ideas, experiences and whatnot would be greatly appreciated. - Lari
"Give a man a match, and he'll be warm for a minute, but set him on fire, and he'll be warm for the rest of his life."
CableGuy
CableGuy
The way OpenGL handles texture management is implementation specific. The texture may reside on RAM/VRAM/Both. I didn't get exactly your third question but if I understand you correctly you want to change a texture's pixel data which is done using glSubTexImage.

HTH.
Shinpou
Shinpou
Thanks for your reply,

I actually started trying to explain it better when it hit me, that that question is somehow foolish.

So let's try another way:
How would you go about managing the unloading and loading of textures for OpenGL safely?

Also, I'd like to keep the inner workings of the openGL as separate from the resource manager as possible.

I'm sorry for the crappy explanation.
"Give a man a match, and he'll be warm for a minute, but set him on fire, and he'll be warm for the rest of his life."
swiftcoder
swiftcoder
Quote:
Original post by Shinpou
How would you go about managing the unloading and loading of textures for OpenGL safely?
glGenTextures when you want to create one, glDeleteTexture when you are done with it. OpenGL will move textures around as needed if it runs low on VRAM, and will overwrite deleted textures when it needs to.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
CableGuy
CableGuy
Quote:

How would you go about managing the unloading and loading of textures for OpenGL safely?


In my small game framework I use the naive and straightforward approach that says that if there are no models loaded that currently use a specific texture, that texture can be safely unloaded. Of course that's not what you want because it can cause redundant loading/unloading, but it's something you can expand. You would need to come up with a way to know which textures are going to be used in the near future. AFAIK there is no general solution to that. I guess some space partitioning is required and then maybe loading only texture that are adjacent to the "cell" the camera is in but I'm no expert.

Good luck.
Shinpou
Shinpou
Ok, thanks a lot guys.
"Give a man a match, and he'll be warm for a minute, but set him on fire, and he'll be warm for the rest of his life."
ruysch
ruysch
Quote:
Original post by swiftcoder
glGenTextures when you want to create one, glDeleteTexture when you are done with it. OpenGL will move textures around as needed if it runs low on VRAM, and will overwrite deleted textures when it needs to.


Texture download on a freshly create texture (glGenTextures) is inherently slow, so creating and deleting contioniously is a bad idea in my opinion. Better to cache handles and/or pack more data into a single texture(s). New data is fastly transfered since handle is alreay valid and memory has been reserved.

swiftcoder
swiftcoder
Quote:
Original post by ruysch
Quote:
Original post by swiftcoder
glGenTextures when you want to create one, glDeleteTexture when you are done with it. OpenGL will move textures around as needed if it runs low on VRAM, and will overwrite deleted textures when it needs to.
Texture download on a freshly create texture (glGenTextures) is inherently slow, so creating and deleting contioniously is a bad idea in my opinion. Better to cache handles and/or pack more data into a single texture(s). New data is fastly transfered since handle is alreay valid and memory has been reserved.
We aren't talking malloc and free here - texture memory management is far lighter weight, and shouldn't cause a problem. glTexture* should perform no differently on a newly gen'd handle than on an existing handle, particularly because they are merely allocate a new texture (possibly over the old one, possibly not) and change the handle to point there - otherwise glTexture* couldn't resize textures or change their format.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
V-man
V-man
Quote:
We aren't talking malloc and free here - texture memory management is far lighter weight, and shouldn't cause a problem. glTexture* should perform no differently on a newly gen'd handle than on an existing handle, particularly because they are merely allocate a new texture (possibly over the old one, possibly not) and change the handle to point there - otherwise glTexture* couldn't resize textures or change their format.


Actually, it is not a good idea to delete and recreate. It is like malloc or new.
It's better to have a bunch of blank textures, 64x64, 512x64, ...
and upload whatever pixels you want with glTexSubImage2D

glGenTextures is not the issue but the actual call to glTexImage2D. That's where drivers check if the paramteres have changed and they might do a delete and realloc.
Shinpou
Shinpou
Quote:
Original post by ruysch

Texture download on a freshly create texture (glGenTextures) is inherently slow, so creating and deleting contioniously is a bad idea in my opinion. Better to cache handles and/or pack more data into a single texture(s). New data is fastly transfered since handle is alreay valid and memory has been reserved.


I don't really know what OpenGL texture handles incorporate, so what is it that you mean by cacheing the handles? I understand it's just a number, or is it a pointer?

glGenTextures() just creates the handle, but it doesn't reserve memory, does it?

glTexImage2D() passes the image data to OpenGL to be handled. I've read that the data passed is copied, so you can remove any data that the texture was created from?

glDeleteTextures() removes the image from openGL never to be seen again?

Are you suggesting that when glTexImage2D is used again on a handle that was used before, it will change the image data in a more efficient manner?
"Give a man a match, and he'll be warm for a minute, but set him on fire, and he'll be warm for the rest of his life."
swiftcoder
swiftcoder
Quote:
Original post by V-manglGenTextures is not the issue but the actual call to glTexImage2D. That's where drivers check if the paramteres have changed and they might do a delete and realloc.
This was the point of my post - though I submit you worded it more succinctly [wink]

However, since textures are typically only created and deleted at level load time, the performance issue is only with streaming textures, so implementing some fancy caching system (particularly in these days of non-power-of-two textures), is probably a waste of your time for negligible benefit.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
ruysch
ruysch
To quote my own post :-)

New data is fastly transfered since handle is alreay valid and memory has been reserved.

Dont trust me - do the timing yourself. Anyways heres what I can recommend you to do (NB: this advice is valid for both ATI/NVIDIA, and under both Linux and Windows). Come to think of it the advice even goes with DirectX, reuse textures is the only way to obtain near teoretical transfer rates. + async PBO streaming only goes with cached textures.

Try and time a glTexSubImage2D with both accounting for CPU time (Win32 has a high resolution timer which is suitable) + GPU time with GPU timer extension.

Do the timing on a freshly created handle. I think you will notice that transfer rate on a fresh texture is 1/4 of what you can achieve with an already allocted texture.

If ~550 MB/s is sufficient for your usage then glGenTextures/glDeleteTextures is easiest way to go, however if performance is of importance for you then you are forced to code a bit more optimal texture usage, still its quite simple for most applications to reuse handles (and the allocated texture memory)

Shinpou
Shinpou
Ok, thanks a lot guys, I think that will get me started.
"Give a man a match, and he'll be warm for a minute, but set him on fire, and he'll be warm for the rest of his life."

Topic Locked

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

Sign in to reply to this topic.