Sign in to follow this  
Gorrotz

Help, Texture.Dispose() results memory leaks

Recommended Posts

Hello, I'm working with Managed Direct3D Mobile on a Dell Axim x51v. I have some problems with textures in the video memory and I hope some of you might know how to fix this. Why are do these lines of code produce memory leaks? int membefore = device.GetAvailablePoolMem(Pool.VideoMemory); //Load a Texture Texture texture = TextureLoader.FromFile(device, "someTexture.dds"); //Delete it immediatly texture.Dispose(); int memafter = device.GetAvailablePoolMem(Pool.VideoMemory); int memlost = membefore - memafter; If I repeat this few times the video memory is full and creating a new texture fails. Question now is: How to *really* dispose a texture? Btw, the texture I get there is working, but i need to change textures several times which is difficult when 16MB video memory quickly run to zero...

Share this post


Link to post
Share on other sites
No. Dispose() frees unmanaged resources. You should call it when you are finished with the resource -- it should (if properly implemented) be done for you in the finalizer, but that is nondeterministic. Thus, if you need deterministic release of those unmanaged resources, calling Dispose() is the way to go (generally we have the using() pattern for this).

MDX did some funny things with respect to object lifetime. I don't have MDX assemblies around any more on this machine to Reflector, though. Those calls are not necessarily the most accurate either.

EDIT: You can also consider using SlimDX, since MDX is basically dead. I glossed over the 'mobile' bit. Fairly sure SlimDX will not run on a mobile platform. Nevermind.

[Edited by - jpetrie on April 24, 2008 11:35:17 AM]

Share this post


Link to post
Share on other sites
One thing worth noting here is that creating textures outside of the managed pool should be avoided in most cases. D3D will handle swapping managed textures in and out of video memory as needed.

If you need some textures in the default pool, say for render targets, then create those once on startup (and recreate them after you recover from a lost device).

That should minimize the chances of you from running out of video memory.

Share this post


Link to post
Share on other sites
Hello,

ManagedPool is a great thing, but unfortunatly my device caps tell me:
SupportsManagedPool: False
SupportsSysTexture: False

Funny thing is: I can try to create it with Pool.Managed or Pool.SystemMemory, but it seems to be ignored

texture = TextureLoader.FromFile(device, "someTexture.dds", 0, 0, 0, Usage.Texture, Format.R5G6B5, Pool.SystemMemory, Filter.None, Filter.None, 0);

and after it's created SurfaceDescription.Pool says VideoMemory


I already tryed
texture.Dispose();
texture = null;
GC.Collect();
Thread.Sleep(1000);
And still the lack of memory.... :(

Share this post


Link to post
Share on other sites
Interesting. I found the solution. It's all about the Pixelformat.

There is the dds file:
dummyAtlas512.dds 512x512, 10 Mipmaps, Format: R5G6B5 (683KB)


Case 1:

PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
Device device = new Device(0, DeviceType.Default, this, CreateFlags.None, presentParams);

int membefore = device.GetAvailablePoolMem(Pool.VideoMemory);

Texture texture = TextureLoader.FromFile(device, "dummy.dds");

texture.Dispose();

int memafter = device.GetAvailablePoolMem(Pool.VideoMemory);
int memlost = membefore - memafter;


When I look at the textures format before it is disposed, it says: R5G6B5 (correct)
Anyway, after disposing it, there is a memory leak of: 524.288 Bytes



Case 2:

PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
Device device = new Device(0, DeviceType.Default, this, CreateFlags.None, presentParams);

int membefore = device.GetAvailablePoolMem(Pool.VideoMemory);
Texture texture = TextureLoader.FromFile(device, "dummy.dds", 0, 0, 0, Usage.Texture, Format.Unknown, Pool.VideoMemory, Filter.None, Filter.None, Color.White.ToArgb());
texture.Dispose();

int memafter = device.GetAvailablePoolMem(Pool.VideoMemory);
int memlost = membefore - memafter;


When I explicit say to get all information from the file (which I think Case 1 should also do!), the texture format it says: A1R5G5B5
But after disposing there is no leak.

Share this post


Link to post
Share on other sites
Just to complete this topic, perhaps somebody will find this useful if he googles it...

It is NOT the Format Flag which causes the lack.
If you do not specify a transparent Color and set it 0 like this:
Texture texture = TextureLoader.FromFile(device, "dummy.dds", 0, 0, 0, Usage.Texture, Format.Unknown, Pool.VideoMemory, Filter.None, Filter.None, 0);
it takes double amount of memory and the texture can't be disposed correct (at least on my device)

Set a color like Color.White.ToArgb() and everything will be fine.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this