[mdx] dx9 and texture memory behavior

Started by
2 comments, last by circlesoft 18 years, 4 months ago
I have a lottery game I wrote in dx9, mostly vb.net, some c#. For the most part it went really well once I got ahold of Tom Millers MDX Kickstart, but recently I ran into some memory problems. Apparently if I leave the game running long enough it will run out of memory. Not entirely surprising, but the behavior of Device.AvailableTextureMemory that I ran into trying to track down my memory leak is. The first step I took trying to figure this out was of course to keep an eye on the texture memory. I counted all the textures that get loaded and unloaded when entering / exiting a state, so far so good. However I noticed that just playing the game the availabletexturememory does go down during playing despite the fact that no textures are loaded during play. Now I know texture memory on the video card and ram are linked, but heres the strange part: The drops in available memory seem to coincide with the first time an individual texture is drawn for the first time. As mentioned this is a lottery game, so for instance when you pick your numbers initially the memory drops, the first time any of them are "hit", goes down a little bit more. As you may imagine at first it drops quite rapidly and then slows down as you come closer to all of them having been drawn. Presumably it would eventually stop. Is this what its supposed to do? I'm really lost because that makes it rather hard to figure my actual memory requirements, and also I cant seem to find a way to release the memory (when they switch back to the "cashier" screen for example) Perhaps I'm just doing something stupid, so I'll post a bit of code at the bottom, but if anyone can shed any light on this I'd be very appreciative. Sorry for the long post but want to be as clear as possible.

Protected Shared HitTexture(74) as direct3d.texture
Protected Shared PickedTexture(74) as direct3d.texture
Protected Shared CalledTexture(74) as direct3d.texture

Select Case Me.State
    Case LotterNumberState.Hit
        MyBase.Draw(HitTexture(Me.Value - 1))
    Case LotteryNumberState.Called
        MyBase.Draw(CalledTexture(Me.Value - 1))
    Case LotteryNumberState.Picked
        MyBase.Draw(PickedTexture(Me.Value - 1))
End Select

Overridable Sub Draw(ByRef spriteTexture As Direct3D.Texture)
    If Visible Then Sprite.Draw(spriteTexture, Me.Size, BlankVector3, 
Position, Color.White)
End Sub
llloyd
Advertisement
This behavior isn't abnormal; it is how video memory paging works. More specifically, its how the managed pool works.

Recall that the managed pool stores two copies of a resource - one in video memory and one in system. In the event that the device is lost and all resources in video memory are lost, it can simply be copied back over. The default pool doesn't have this luxury, but uses far less memory.

However, resources aren't *always* in video memory - they are only there when needed. When a texture is loaded (in the managed pool), it is not necessarily transfered into video memory right away. This only occurs when your application actually needs it - ie the first time its used.

Also, it is worth mentioning that resources can actually be evicted from video memory if not used for a long period of time. This would only occur if you want to put a new object into video memory, but don't have the space.

So, for a final word on your question: it is normal for the memory counters and such to not register until you actually use the resource in question, as it is only loaded into video memory upon its first use.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Thanks!

Does this mean that when I switch major game states (lobby -> cashier -> game) there is something I should be doing to tell it that those textures arent going to be used any time soon, or as long as I'm disposing of them correctly it will take care of itself?

Also whats the best way of calculating the maximum possible memory usage at any given time? Just add up the size of all loaded textures and double it and compare that to video + system memory?
llloyd
Quote:Original post by llloyd
Does this mean that when I switch major game states (lobby -> cashier -> game) there is something I should be doing to tell it that those textures arent going to be used any time soon, or as long as I'm disposing of them correctly it will take care of itself?

Generally, D3D will take care of this itself. It automatically detects when a resource hasn't been used and needs to be evicted. Check out this KBase article on the topic.

Quote:
Also whats the best way of calculating the maximum possible memory usage at any given time? Just add up the size of all loaded textures and double it and compare that to video + system memory?

This is a tough one. The provided APIs are notoriously inaccurate (as you have found out), and shouldn't really be used in a production build (ie to determine optimizations at runtime based on the hardware). You can try a few things:

(a) IDirect3DQuery9 has some GPU performance functionality that you could look into. It covers things like memory usage, number of evictions, thrashing, ect...

(b) Definetly look into PIX. This should give you an accurate profile of your application.

(c) If you have an Nvidia card, check out NVidiaPerfHud. They are tailored specifically (in the drivers) for Nvidia cards, and provide some valuable information. It seems that Nvidia is finally playing ball with Microsoft for PIX support - for a while there they wouldn't provide a plugin.

[Edited by - circlesoft on November 24, 2005 5:11:57 PM]
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )

This topic is closed to new replies.

Advertisement