Search code examples
c++comdirect3d

Does the order in which Direct3D COM interfaces released matter?


As an example consider this struct

struct Foo
{
    ComPtr<ID3D11Texture2D> back_buffer;
    ComPtr<IDXGISwapChain> swap_chain;
    ComPtr<ID3D11DeviceContext> device_context;
    ComPtr<ID3D11Device> device;
}

The order of release() calls here is the same as the order in which those COM objects were created. Can it cause any problems?


Solution

  • In general, the order of release for COM objects is strictly speaking not supposed to matter. That said, Direct3D doesn't use strict COM rules on lifetime. Once you release the last reference to a Direct3D device, then everything that's a child object of that device is invalid no matter what their individual reference counts were.

    To make it a little easier to do cleanup, there is 'object leak detection' in the Direct3D Debug Device so it's helpful to cleanly release everything before you release the final device instance. See Direct3D SDK Debug Layer Tricks and DXGI Debug Device.

    Keep in mind that object-to-object references can also keep counts alive, and that Direct3D makes use of 'deferred destruction'. Therefore, a 'clean exit' requires a flush after you unbind all the objects:

    m_d3dContext->ClearState();
    m_d3dContext->Flush();
    // Release all your objects except the device
    // Final release of the device here
    

    You don't have to use such a clear & flush for cleanup with Direct3D 11, but you'll end up with a lot of 'false reports' of live objects by the Debug Layer if you don't Flush after unbinding. With Direct3D 12, you have to ensure the GPU is idle before you start releasing things to get a clean exit.