Archived

This topic is now archived and is closed to further replies.

Sweenie

Managed pool

Recommended Posts

Hi. I use the managed pool in DX9 to let it handle if my textures and vb''s should reside in graphicmemory or systemmemory. Now, is there any way for me to know if the texture/buffer is in the graphiccardmem or systemmem? I checked the pool property but it only tells me what kind of pool i put the object in(scratch,default,managed or systemmem). As i''m putting all objects into the managed pool, that''s the answer i get back. I''m trying to write a resourcemanager that will handle loading and flushing of textures and models. If want to keep track of my resources memory usage so that the manager knows when to flush "unused" objects. First i thought that i just flush out objects(textures/models) that aren''t within a certain zone, but on the other hand, if you got memory to spare it would be better to keep it as long as possible(to minimize diskactivity) Someone has any good articles or tutorials about this topic?

Share this post


Link to post
Share on other sites
There''s no easy way that I know of to tell whether a managed resource currently has video memory committed to it.

However you shouldn''t really try to "second guess" the D3D resource manager - things aren''t as simple as "it''s in video memory" or "it''s in system memory". Where the texture ends up is different on a machine with AGP memory, and different again on a UMA based system. Your code would need to handle each case differently. And it''d need to be aware of driver based management schemes such as virtual texturing.

D3D already provides almost all of the functionality you''re asking for and wanting to write yourself though!:

IDirect3DDevice9::EvictManagedResources() - to flush all resources out of non-system memory.

IDirect3DTexture9:reLoad() - to tell the resource manager you will be using a texture *soon*.

IDirect3DTexture9::SetPriority() - to tell the resource manager which textures should stay in memory for longer.


Its actually better to evict all resources from (conceptual) video memory rather than just a few in the middle of all the others - this helps avoid things like fragmentation etc. The resource manager will upload them all next time they''re used anyway (pre-loading can help here).

A note on render target textures: create them BEFORE you create any managed ones. If you do need to create a render target after some managed resources, always evict all the video mem resources.

--
Simon O''Connor
3D Game Programmer &
Microsoft DirectX MVP

Share this post


Link to post
Share on other sites
Hi Simon, you are absolutely right about the DX's resourcemanager. I should and will let DX handle this itself.
However, while DX handles resourcemanagement between videomemory and systemmemory, it won't handle resourcemanagement between systemmemory and disk.
I believe I need to keep track of how much memory my resources use(in sysmem) and set some kind of Maxsize there I start to flush(release) unused resources from sysmem.

Maybe I should mention that I will have a large world divided into zones, and I want to move smoothly between these zones without stalling the game too much while loading resources for the zone i'm entering.

So I guess what I really want to know is...
How would I implement a good paging system into my game.
I'm not sure but I think it's called paging

I read somewhere that I should anticipate which resources too load next and likewise anticipate which resources to release by determing which zone i'm moving towards and moving away from.

(Thanks for the tip about Preload and SetPriority by the way).


[edited by - Sweenie on October 6, 2003 2:52:55 PM]

Share this post


Link to post
Share on other sites
quote:
it won''t handle resourcemanagement between systemmemory and disk


Ah, but Windows will - if a system memory texture (such as the system memory copy of a managed texture) hasn''t been used for a long time, then the virtual memory manager will page that out back to disk automatically. If that texture is never used again, then it''ll stay on disk until your process exits.

You can influence how Windows treats memory using calls such as VirtualProtect().


As for a zone based streaming system - some random implementation/design thoughts:

- sort all your resources into cell/zone/area/whatever order so that every zone knows all of the resources it needs.

- make a reference counting system for your resource loader where if the same resource is already loaded its reference count is increased rather than that resource being loaded multiple times.

- use the reference counting for your resource destruction too - don''t release the memory until nothing else needs it.

- make sure your artists know using similar resources between zones is a "good" thing since it means less zone-to-zone data to be loaded.

- use asynchronous I/O

- when loading all the resources for a new zone have a "batch" loading system where you just pass a list of all the files used by that zone to an async I/O thread which loops through and loads ALL of the files. The idea is the rest of your code shouldn''t need to get involved until everything is loaded.

- your zone determination system knows all the neighbouring zones (i.e. what''s going to be loaded "soon") - you can use things like average movement velocities and dead reckoning to "guess" which zone will be required next.

- set yourself some limits: work out the maximum amount of data required to be loaded by a zone. Work out the minimum amount of time between entering one zone and needing to enter the next. Work out the maximum async I/O streaming rate for your target platform and media. If the numbers don''t work out, you''ll have to sacrifice somewhere.

- memory mapped files are good for turning files into addressable memory - and avoiding some intermediate VMM work.

- look at other games which are doing what you want to do. Keep a look out for level design which is hiding loading/prolonging the time you spend in a zone such as lifts, long stairways etc. It happens more than you''d think!

- compress files - if your data decompression doesn''t take much overhead.

- a nice trick to increase draw distance is to sort the data in each zone by LOD - store your lowest detail mip map levels first in the zone data, along with lowest LOD meshes (assuming discreet LOD) _or_ store a low detail "shell" of what''s going to be coming up soon. The idea is the shell or low LOD stuff loads very quickly so can be displayed while you load the true details.

- don''t flush any resources until AFTER the zone has loaded. The idea is you have enough in system memory for two zones at a time (because one is loading while one is being displayed), and you only remove the first when the player is inside the second. The reference counting then worries about not unloading duplicates etc.

- there''s no need to do anything more low level than the above. The D3D texture manager will worry about the low level sys<->vram stuff, and Windows VMM will worry about overcommit of physical system memory.

--
Simon O''Connor
3D Game Programmer &
Microsoft DirectX MVP

Share this post


Link to post
Share on other sites