Sample for releasing DirectX resources


  • In the Windows 8 app samples, there are several samples showing DirectX and SwapChainBackgroundPanel.

    I found the code in DirectXBase.cpp very useful and everything works fine. The only problem is that in the samples, the DirectX stuff is never released. For those samples, it is OK. But in my app I would like to have more than one page with SwapChainBackgroundPanel (of course, never more than one at one time).

    But I don't know how to release the things at the end. It seems it is not enough to have everything in ComPtr.

    Probably, there are some additional DirectX calls that have to be done to release all things. But which?

    Is it possible for the DirectX sample team to provide a sample where there is navigation between different pages (all having SwapChainBackgroundPanel) and which show how to release things properly? This would be cool!

    [If you are asking why I use DirectX and don't know much about it: We started everything in XAML but after buying a Surface RT it showed that ARM devices are too slow to handle 10,000 XAML objects... So we had to switch to DirectX. Now, everything works fine except the memory issue]

    Friday, April 26, 2013 5:18 PM

All replies

  • I don't know much about the XAML interop, but for Direct3D 11 generally the 'cleanup' guidelines are:

    • You should release the device last. The Direct3D API doesn't fully implement the COM ref count rules. All the 'Device Children' are referenced counted, but all pointers to them become invalid when their parent Device is fully released (i.e. hits a refcount of 0). I believe you can control this by having the ComPtr<ID3D11Device> listed first in your class.
    • In your cleanup, you should call ClearState on all your ID3D11DeviceContext instances to ensure all resources are unbound
    Saturday, April 27, 2013 1:20 AM
  • In addition to what Chuck said, with SwapChainBackgroundPanel, you must do a QueryInterface to get its native ISwapChainBackgroundPanelNative COM interface and must then call ISwapChainBackgroundPanelNative::SetSwapChain(IDXGISwapChain* pSwapChain) to associate the swap chain with the SwapChainBackgroundPanel. This call increases the reference count of the IDXGISwapChain.

    Using your repro from a different thread - http://sdrv.ms/11dS2CB - its seems as though the reference count is not decreased when the SwapChainBackgroundPanel is destroyed; as such you'd be leaking a swap chain each time you created and destroyed and SwapChainBackgroundPanel which would steadily leak memory. This isn't a problem in any of the samples since they only ever use one instance of SwapChainBackgroundPanel.

    I tried to find a robust way to modify that repro so as to decrement the added reference count (thus causing memory usage to remain within a stable range) but invariably after enough switches back and forth between the two pages I would get any one of several exceptions in the C++ code which would be thrown from inside the XAML framework or within DComp. The sense I got from it was that there was some sort of race condition which eventually triggered; I couldn't determine the exact source of the problem though.

    Ultimately I think you would be best served by either using a single XAML page and swapping out the UI overlay or else creating and retaining a single SwapChainBackgroundPanel (complete with a single DirectXBase-derived class instance for it) which you would then set and unset on each page whenever the app navigates to or away from the page. Either of these would avoid the issue of using multiple SwapChainBackgroundPanel instances within your app, which is inefficient and error prone.

    Visual C++ MVP | Website | Blog | @mikebmcl | Windows Store DirectX Game Template

    Sunday, April 28, 2013 5:40 AM
  • @ Chuck Walbourn:

    Thank you for your sharing your knowledge! Unfortunately, I don't know enough DirectX to be able to code a cleanup method on my own. I really would need a complete example from Microsoft (which shows switching between different SwapChainBackgroundPanel pages). As I said: I have zero knowledge of DirectX and just use it for 2D drawing of lines, rectangles and text since Xaml is too slow for thousands of graphics objects.

    @ MikeBMcL:

    Thank you for trying out to find a way of cleaning up a SwapChainBackgroundPanel! And thank you for sharing that it is difficult / impossible! Also in my previous thread, you helped a lot. Thank you very much!

    Yes, at the moment, I have only two options (which I don't like either):

    • Have one single page (SwapChainBackgroundPanel) and showing a full screen Xaml Grid over it when I need the menu. The only problem is: If this full screen Xaml Grid is really full screen, then in Windows RT (not Windows 8), the screen sometimes freezes after making the full screen Grid visible. My workaround is to give this Grid a margin of 0.001 pixels, so the SwapChainBackgroundPanel is still "visible" a tiny bit. It seems there is some optimization in Windows RT that does something when a Xaml Grid covers the whole SwapChainBackgroundPanel (and which is buggy)
    • Have one SwapChainBackgroundPanel page and one menu page and switch between them via Window.Current.Content = ...  Unfortunately, I discovered some strange behaviour and exceptions in 1 of 100 switches. So I stay with option 1...

    Tuesday, April 30, 2013 11:08 AM