prevent system memory copy of textures

Hello,

I’m developing for an embedded system (no swap space) with 256MB System Ram and 256MB video ram (GeForce FX5200). The OpenGL implementation keeps a backup copy of all textures in system ram. As I need the system ram for other things I’m looking for a way to prevent the system ram copy of the textures.

I tried to upload texture data as pixel buffer object first and create the texture from video memory but this didn’t help.

I know that this copy is usually a good thing but in my case I really need this ram for other things.

Thanks

Markus

Originally posted by muhkuh:
I tried to upload texture data as pixel buffer object first and create the texture from video memory but this didn’t help.
actually it should work that way. did you delete the pixel data from memory (after calling glBufferData)?

Originally posted by RigidBody:
actually it should work that way. did you delete the pixel data from memory (after calling glBufferData)?
Yes. I compared the two cases:
A:

  1. load a texture image into system ram
  2. glTexImage2D with the system buffer
  3. delete the system buffer

B:

  1. load a texture image into ram
  2. create/bind a PBO (GL_PIXEL_UNPACK_BUFFER_ARB)
  3. glBufferData with system buffer and GL_STATIC_DRAW)
  4. glTexImage2D with the PBO
  5. unbind/destroy the PBO

A and B both consume the same amount of system memory. So it seems like there is always system memory allocated to backup all textures in case they need to be swapped from VRAM.

i’m not so sure if it is allowed to delete the image from memory in case A, but in case B it is for sure, because the image is transferred to gpu memory and therefore no longer needed in main memory.

again: in case B, delete the pixel data from system memory. do not destroy the PBO.

i’m not so sure if it is allowed to delete the image from memory in case A
Buffer passed to glTexImage2D needs only to be valid during that call, after that you can delete it, because driver has copied your image.
What the driver does with the image is another thing. It looks like it’s stored in the system memory after all - when I load 4MB texture I get 8MB more memory usage in my app (I don’t delete buffer after I call glTexImage, so I consume 4MB myself, the other 4MB is consumed by driver).
I didn’t notice that before but muhkuh’s post motivated me to check this in my game.
My GPU is RIVA TNT2.

Ok, but perhaps instead of comparing observations I should propose a solution :slight_smile:
Not sure if it will work, but you could try something like this:

  1. Create texture A and pass contents with glTexImage2D
  2. Create texture B and initialize with glTexImage2D (pass NULL as buffer)
  3. Render texture A to B
  4. Delete texture A
    This way, texture B is never passed by your application, so the driver would have to copy it from VRAM to system memory in order to create it’s ‘backup’ version. If you get lucky, driver will wait with that until it really has to swap this texture out of GPU memory.

This seems to be worth a try. I’ll check that out.

Mmmm, there is a problem with the render to texture stuff. Compressed textures cannot be render targets IIRC. As automatic mipmap generation does rely on that this wouldn’t work too I guess. Damn.

You don’t have to render directly to texture. Render to framebuffer and use glCopyTexSubImage2D or glCopyTexImage2D (in this case you wouldn’t need to call glTexImage2D for texture B at all).

Ok, forget it - it doesn’t work anyway - I just tested it.
When I do this:

glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 1024, 1024, 0);

System memory consumption goes up by 4MB and when I do this:

glDeleteTextures(1, &texId);

I get that 4MB back.
So even if you create texture this way it’s copy is stored in system memory from the the beginning.

I wonder how does it affect render to texture operations. Are such textures copied to system memory every time I finish rendering to them? Perhaps drivers recognize such case (when texture is bound to FBO).

I’m developing for an embedded system (no swap space) with 256MB System Ram and 256MB video ram (GeForce FX5200).
Would this system be a PS3? If so, you have my sympathies.

a ps3 with a geforce fx5200 would have my deepest compassion, too…

a ps3 with a geforce fx5200 would have my deepest compassion, too…
Fair enough :wink: But the memory configuration is very much like PS3, so I kinda figured…

Back to the issue at hand.

Since this is a GeForce FX, and since GeForces are nVidia cards (who are notoriously tight-lipped about their drivers, hardware, even to the detriment of being able to use them in embedded systems. Microsoft had all kinds of trouble with nVidia on X-Box, and I don’t think Sony’s getting much better on PS3), this is probably untenable.

The standard nVidia PC drivers are designed to do exactly what you suggest: keep a system memory copy. This is usually because Windows doesn’t guarantee that anything in video memory will be there the next time the hardware looks for it. If you’re on an OS that doesn’t have these problems, it’s probably a waste.

So, basically, I think you’re out of luck. Not unless you can get nVidia to give you a new driver (I’d bet their OpenGL PS3 drivers don’t have this problem, for example). But that would only be at the request of the actual hardware makers of said embedded system. And even then, it’s probably not likely unless the system itself is popular.

How about you first create the texture using glTexImage with NULL source data and then split your image data into 2+ PBOs and upload each one separately using glTexSubImage?

How about you first create the texture using glTexImage with NULL source data and then split your image data into 2+ PBOs and upload each one separately using glTexSubImage?
My solution with glCopyTexImage2D didn’t work so I believe this one wouldn’t too. Drivers just make a copy of texture whenever you change it’s contents in any way. So this is where I would to repeat my question from previous post:
Does it mean I pay with GPU->system memory transfer every time I render to texture? If I use HDR and render to 1280x1024 RGBA_FLOAT16 texture, do I waste my time on transfering 10MB of data every frame?

Unfortunately none of this worked. Either there was system ram allocation or it didn’t work. At the point where the driver gets to know the size of the texture it allocated system ram for it. May be the texture isn’t transfered to system ram immediately in case of dynamically created textures but I guess the ram is allocated to prevent an out of memory condition when the texture has to be swapped out later.

Well I guess you really need a customized driver, have a look here :
http://nouveau.freedesktop.org/

Some work in progress, still not a “done” thing :
http://nouveau.freedesktop.org/wiki/RequiredFunctionality

uhm… Try this (but it is unefficient)…
Create one big PBO and store all your textures in it. Keep offsets for all textures. Then create (for example) 4 GL textures (depends on shading complexity).
Every time you want to use some texture do glTexImage2D (with proper offset value) on one of 4 textures ID’s that you have.
Pros… only 4 textures will be in sys mem. !?
Cons… Frequent glTexImage2D is huge performance hit.

Just make test before you do anything with this approach. Im not sure but it might happens that PBO memory is also backed-up in sys mem, so you are on beginning.

PBOs are backed up by system memory too. Furthermore I couldn’t take the performance hit of calling glTexImage2D for every texture. This is like not using texture objects. So I have to downsize textures.