Search code examples
graphicsdirectxdirectx-11direct3ddirect3d11

Can't release the ID3DX11Effect pointer?


I use Effect framework in my demo.

here are my defination in header file

    ID3D11Buffer*                   m_pVertexBuffer;
    ID3D11Buffer*                   m_pIndexBuffer;
    ID3D11InputLayout*              m_pInputLayout;

    ID3DX11Effect*                  m_pFx;
    ID3DX11EffectTechnique*         m_pTechnique;
    ID3DX11EffectMatrixVariable*    m_pFxWorldViewProj;

I release them as follow

void HillsDemo::UnLoadContent()
{
    if (m_pVertexBuffer) m_pVertexBuffer->Release();
    if (m_pIndexBuffer) m_pIndexBuffer->Release();
    if (m_pInputLayout) m_pInputLayout->Release();
    if (m_pTechnique) m_pTechnique->Release();
    if (m_pFx) m_pFx->Release();
}

error picture

then I run the demo,when I close the demo window, there is an error which means HillsDemo has stopped working.Why?Then I delete the lineif (m_pFx) m_pFx->Release();,there is no error. So is releasing the m_pFx make the error?

I view the documents of Effect11 https://github.com/Microsoft/FX11/wiki/Effects-11, there are on the document:

The following types are now derived from IUnknown: ID3DX11EffectType, ID3DX11EffectVariable, I3DX11EffectPass, ID3DX11EffectTechnique, ID3DX11EffectGroup. Note that these objects do not follow standard COM reference-counting rules and they are released when the parent ID3DX11Effect is released. This is mostly to simplify use of Effects 11 from managed languages.

Does it means that I should only release the m_pFx rather than release both m_pFx and m_pTechnique? Any ideas?


Solution

  • I assume you are using the latest version of Effects 11 from GitHub rather than the legacy DirectX SDK copy based on your reference to the project wiki.

    You should really look at using ComPtr instead of raw pointers to COM objects. In the case of Effects 11, you'd just use them for ID3DX11Effect instances. You should stick with 'raw pointers' for ID3DX11EffectType, ID3DX11EffectVariable, I3DX11EffectPass, ID3DX11EffectTechnique, and ID3DX11EffectGroup. Don't bother calling Release on these raw pointers as the lifetime controlled by the ID3DX11Effect.

    Something like:

    Microsoft::WRL::ComPtr<ID3D11Buffer> m_pVertexBuffer;
    Microsoft::WRL::ComPtr<ID3D11Buffer> m_pIndexBuffer;
    Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayout;
    
    Microsoft::WRL::ComPtr<ID3DX11Effect> m_pFx;
    ID3DX11EffectTechnique* m_pTechnique;
    ID3DX11EffectMatrixVariable* m_pFxWorldViewProj;
    
    void HillsDemo::UnLoadContent()
    {
        m_pVertexBuffer.Reset();
        m_pIndexBuffer.Reset();
        m_pInputLayout.Reset();
        m_pFx.Reset();
        m_pTechnique = nullptr;
        pFxWorldViewProj = nullptr;
    }