Jump to content
  • Advertisement
Sign in to follow this  
DwarvesH

Best XNA resource load etiquette

This topic is 1906 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know that XNA is dead and I should ditch it, but it would be an enormous task to port everything over to SharpDX, so for now I'm sticking with it.

 

In DirectX managing resource lifetime is very easy once you understand the Create/Destroy Reset/Lost cycle. XNA tries to simplify this with the LoadContent/UnloadContent pair, but I couldn't get his to behave as expected. For starters, I can't seem to get the load or unload method to trigger more than one time per execution of the engine, at the start and end. I can change resolution or other device settings without extra triggers. Second, my engine uses heavy streaming, so in the load/unload methods all I can do is load a shader or two. The rest is loaded when needed on separate threads.

 

I mostly care about shaders and render targets. I wrote code similar to the DirectX to be called when I know that I am changing device settings. In this code I recreate the render targets and I noticed that I also need to re-extract parameters from shaders. Not always, but some shaders do need their parameters re-extracted.

 

Now this solution works well and I've been using it for months, but is not exactly elegant, nor is it very clear when and which resource is recreated. I was wondering what are the best practices related to XNA and resource management that don't rely on loading everything in the LoadContent method once. I was thinking of even recreating the whole Create/Destroy Reset/Lost paradigm.

 

 

 

Share this post


Link to post
Share on other sites
Advertisement

WIth XNA (since v2.0), there is no concept of Reset/Restore anymore. The graphics device has been virtualized such that you can keep references to device resources without worrying about what's happening to the underlying device. XNA takes care of ensuring that resources survive through any under-the-hood device resets. (Render targets are a special case. They survive, but their contents do not.) So don't go recreating the Create/Destroy/Reset/Lost paradigm. ;-)

 

Generally, you can load content at any time after Initialize, though you obviously don't want to be doing that during critical times like the middle of game play. The most common technique is to use multiple ContentManagers. Use one for loading content that needs to hang around for the life of the program, such as gui elements. Use additional content managers for things with shorter lifetimes, such as per-level resources. That allows you to unload a level and load another without having to reload everything else. You would perform these unload/load tasks during level transition.

Share this post


Link to post
Share on other sites

Off topic: if you want XNA to live on, you can eventually port your code to MonoGame, which is basically just an open-source version of XNA (that isn't "dead").

Share this post


Link to post
Share on other sites

WIth XNA (since v2.0), there is no concept of Reset/Restore anymore. The graphics device has been virtualized such that you can keep references to device resources without worrying about what's happening to the underlying device. XNA takes care of ensuring that resources survive through any under-the-hood device resets. (Render targets are a special case. They survive, but their contents do not.) So don't go recreating the Create/Destroy/Reset/Lost paradigm. ;-)

 

Generally, you can load content at any time after Initialize, though you obviously don't want to be doing that during critical times like the middle of game play. The most common technique is to use multiple ContentManagers. Use one for loading content that needs to hang around for the life of the program, such as gui elements. Use additional content managers for things with shorter lifetimes, such as per-level resources. That allows you to unload a level and load another without having to reload everything else. You would perform these unload/load tasks during level transition.

 

Thank for the info and link. I waited a while to test out my setup to see if it works before answering.

 

Things are a little bit more complicated, because there is no concept of level, level loading or level transition. The engine streams in content constantly. Or at least as long as you are walking around. If you stand still, after a few dozen/hundred frames the streaming should stop.

 

and I am not using the ContentManager. Actually, I do load my effects with it. But in rest I use my own custom content managers that don't inherit from XNA classes. At first this was because of the load time. I noticed that as the number of models piled up, XNA became very slow at loading meshes. I don't have 3 seconds to waste on loading meshes. I wrote my own importers that take 30 milliseconds for the same task. I am also loading the textures without the content manager.

 

And I'm planning to update the system to make it able to determine what mip-map levels are in use and when it has free time to remove some larger mips. I am running out of memory very quickly. A 2048x2048 mip-mapped image is 21.6 MiB. Add a normal and a specular map to it...

 

So anyway, this is the scheme I came up:

  • constructor: does normal constructor stuff
  • LoadContent: in 99% of cases, only loads shaders and extracts parameters. Get's only called once per instance per engine run.
  • BringUp: handles screen-size dependent resources, like render targets, pixel size, camera aspect ratio...
  • BringDown: almost always empty, but when a render target is involved, I dispose of it here

BringUp and BringDown are generally called only once, but they are called when a resolution change happens or when a device reset is needed. Somehow, I still need to handle a device reset, especially on Windows 8 which behaves strangely when Metro is involved. If I don't handle it, some of my post-processing effects fail to apply.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!