Terminating (Managed) Direct3D

Started by
3 comments, last by CodeImp 18 years, 1 month ago
I'm making a game (C#, MDX) in which the launcher is integrated. From the launcher, you can start playing (initializes Direct3D) and when leaving the game (terminates Direct3D) you will see the launcher window again. Problem is, Direct3D does not seem to terminate and/or initialize correctly when running fullscreen (no problem whatsoever in windowed mode though). Sometimes when terminating, the last frame just sticks on the screen and while the launcher is actually there (i can see it by observing my mouse cursor) you can click it and everything, you don't see it at all because its behind this last frame that is stuck on the screen. When the above problem does not occur, there is another (most likely relevant) problem; When trying to launch for the 2nd time fullscreen, it will not work, saying that exclusive access cannot be obtained because the device is already in use (but it isnt, im watching my launcher window!). 3rd time trying, no problems, 4th time, no problems... I unload all my resources when terminating Direct3D, I use d3dd.EvictManagedResources() to force Direct3D to dispose all its resources and a d3dd.Dispose() followed by a d3dd = null; should kill it... should it not? Im puzzled. Please give me some tips I could try (i already tried GC.Collect() and Application.DoEvents() in several locations, but that doesnt seem to help).
Kind regards,
Pascal van der Heiden

CodeImp - My trademark and website
Advertisement
afaik you should just make sure you dispose of all d3d objects, ie. textures, meshes, vertexbuffers, sprites, fonts etc.

you could try running pix (in the sdk/tools) to find out if everything is being disposed of. (although i've tried using this to find a similar problem and it didn't help much, probably because i don't know how to use pix properly.)
Ok I tried using PIX but it can't give me any usefull information. It only counts # of resources per frame and it doesn't continue counting after the last frame (which is where everything is disposed).
Kind regards,
Pascal van der Heiden

CodeImp - My trademark and website
The easiest way to do this is probably to run the launcher in another process, so you start the launcher app which in turn starts the game/3D app. When you close the Window's Form onto which you're doing your rendering, the games's main loop should be terminated and the game child process should be killed, which will release the device whatever happens. That may not be the cleanest approach, but it always worked for me :)

If you're manually keeping the render loop alive (with the AppStillIdle approach or with the Application.DoEvents() call), you should surround this with an if(!yourMainForm.Disposed) block, to make sure the loop gets terminated neatly when the program exists.

Another approach would probably be to manually call Dispose() on your device object. If you're using the device with event handlers enabled (which is the default setting), the resources should be disposed automatically (afaik, please correct me if I'm wrong). Otherwise, you'll have to dispose of your device bound resources manually as well.

Instead of using PIX to find any unreleased resources, you can switch to the DirectX debug runtime and Enable Unmanaged Debugging in Visual Studio to get a memory dump of the unreleased objects when the application closes/the device is released. Don't worry if you can't make much of it, if it only reads "Mem fini!", you're home free. If it displays some memory addresses though, you still have some unreleased resources floating in video memory.

Hope this helps, somewhat at least :)
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
I have been viewing the DirectX debug output and it does say Mem Fini! at the end, so that would mean all my resources are disposed correctly?! Then something else may be wrong.

I dont like the idea of seperating the launcher from the game really, like you said, its not a very clean solution. But if there is no other option I will have to do that and send an angry letter to the microsoft directx department :P

What my game does is this; In the launcher is a big Join or Host button. When clicked, it will load the game window, initializes DX and it will run the main loop. In the main loop is one Application.DoEvents() to keep the application alive. This also allows events to occur on the game window. When the pressing ESC, a variable "gamerunning" is set to false to indicate the game should terminate. The main loop will then exit, terminate DX and dispose the game window.

I hope someone can give me more tips with the additional information in this post. If you need any more information about how it works, please ask! I really would like to make this work smoothly and it would be a shame if DX was unable to work that smoothly.
Kind regards,
Pascal van der Heiden

CodeImp - My trademark and website

This topic is closed to new replies.

Advertisement