none
Direct3D10.1の警告について RRS feed

  • 質問

  • 以前からシェーダープログラミングしていると以下のような謎の警告が出て気になります。

    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x04FD0628, Refcount: 4. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x00660FF0, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live                         Object :      1 [ STATE_CREATION WARNING #0: ]

    今までは実行はできるので無視していたのですが、たまにプログラムが落ちるのはこれが原因ではと心配です。

    この警告の意味と解決方法を教えてください。

    Windows7

    Visual Studio 2012 ProfessionalのC++言語でMFC

    Microsoft DirectX SDK (June 2010)

    2014年3月22日 23:07

回答

  • DirectX COMオブジェクトのRelease忘れにより、終了時に参照カウントが正しくゼロになっていないことが原因でしょう。COMプログラミングをやったことがある人だったらDXGIレイヤーが出力してくれているメッセージ中のRefcountというキーワードでピンときます。とりあえずD3Dデバイス、スワップチェーン、バックバッファテクスチャなどのDirectXオブジェクトをきちんと順番通り解放しているかどうかのチェックをします。

    例えばウィンドウのWM_CREATEメッセージハンドラーOnCreate()でDirectXオブジェクトを生成している場合は、WM_DESTROYメッセージハンドラーOnDestroy()において、ウィンドウハンドルが無効になる前にDirectXオブジェクトを解放します。

    まずはCOMプログラミングの基本に関して情報収集・学習されてからDirectXプログラミングを行なうことを強くお勧めします。DirectXプログラミングの場合はたいていの場合COMクライアントのみで十分ですが、COMサーバーに関しても知っておいて損はありません。少なくともAddRef(), QueryInterface()に関する知識がないと後々苦労すると思います。ある程度COMプログラミングに慣れ、参照カウントの仕組みを理解したら、COM用のスマートポインタテンプレートであるATL::CComPtrやMicrosoft::WRL::ComPtrを使ってCOMオブジェクトを管理するようにするとコーディングが楽になります。

    なお、D3D10CreateDevice1(), D3D10CreateDeviceAndSwapChain1()のFlagsパラメータには、デバッグビルドの場合(DEBUGもしくは_DEBUGシンボルが定義されている場合)D3D10_CREATE_DEVICE_DEBUGフラグを指定しておくことを推奨します。このフラグを立てることで、DXGIリソースのほかにDirect3Dリソースがリークしている箇所や、Direct3Dプログラミングミスがあればデバッグレイヤーが指摘してくれます。

    	HRESULT hr = D3D10CreateDeviceAndSwapChain1(
    		nullptr,
    		D3D10_DRIVER_TYPE_HARDWARE,
    		nullptr,
    #if defined(DEBUG) || defined(_DEBUG)
    		D3D10_CREATE_DEVICE_DEBUG | D3D10_CREATE_DEVICE_BGRA_SUPPORT,
    #else
    		D3D10_CREATE_DEVICE_BGRA_SUPPORT,
    #endif
    		D3D10_FEATURE_LEVEL_10_1,
    		D3D10_1_SDK_VERSION,
    		&swapChainDesc,
    		&m_pSwapChain,
    		&m_pD3DDevice);

    プログラムがクラッシュするという現象の原因は分かりませんが、オブジェクトを解放することなく新しく作成するようなことを繰り返していればリソース不足で落ちることは考えられます。デバッガーをアタッチするか、もしくはイベントビューアーで異常終了時の例外エラーコード(スタックオーバーフロー、アクセス違反、……)をチェックするなりして根気強くPostmortemデバッグすればたいていの原因は掴めるはずです。

    • 編集済み sygh 2014年3月24日 17:07
    • 回答としてマーク たけし 2014年3月24日 17:56
    2014年3月24日 16:32

すべての返信

  • Live、つまり「生きている」あるいは「生き残っている」です。
    終了時に通常、解放しておくべき要素を何か解放していないから「生き残っている」と警告されるのでしょう。

    ソースコードを見直すなどして、適切に解法処理がなされるようにコードを修正してください。

    2014年3月23日 0:53
    モデレータ
  • DirectX COMオブジェクトのRelease忘れにより、終了時に参照カウントが正しくゼロになっていないことが原因でしょう。COMプログラミングをやったことがある人だったらDXGIレイヤーが出力してくれているメッセージ中のRefcountというキーワードでピンときます。とりあえずD3Dデバイス、スワップチェーン、バックバッファテクスチャなどのDirectXオブジェクトをきちんと順番通り解放しているかどうかのチェックをします。

    例えばウィンドウのWM_CREATEメッセージハンドラーOnCreate()でDirectXオブジェクトを生成している場合は、WM_DESTROYメッセージハンドラーOnDestroy()において、ウィンドウハンドルが無効になる前にDirectXオブジェクトを解放します。

    まずはCOMプログラミングの基本に関して情報収集・学習されてからDirectXプログラミングを行なうことを強くお勧めします。DirectXプログラミングの場合はたいていの場合COMクライアントのみで十分ですが、COMサーバーに関しても知っておいて損はありません。少なくともAddRef(), QueryInterface()に関する知識がないと後々苦労すると思います。ある程度COMプログラミングに慣れ、参照カウントの仕組みを理解したら、COM用のスマートポインタテンプレートであるATL::CComPtrやMicrosoft::WRL::ComPtrを使ってCOMオブジェクトを管理するようにするとコーディングが楽になります。

    なお、D3D10CreateDevice1(), D3D10CreateDeviceAndSwapChain1()のFlagsパラメータには、デバッグビルドの場合(DEBUGもしくは_DEBUGシンボルが定義されている場合)D3D10_CREATE_DEVICE_DEBUGフラグを指定しておくことを推奨します。このフラグを立てることで、DXGIリソースのほかにDirect3Dリソースがリークしている箇所や、Direct3Dプログラミングミスがあればデバッグレイヤーが指摘してくれます。

    	HRESULT hr = D3D10CreateDeviceAndSwapChain1(
    		nullptr,
    		D3D10_DRIVER_TYPE_HARDWARE,
    		nullptr,
    #if defined(DEBUG) || defined(_DEBUG)
    		D3D10_CREATE_DEVICE_DEBUG | D3D10_CREATE_DEVICE_BGRA_SUPPORT,
    #else
    		D3D10_CREATE_DEVICE_BGRA_SUPPORT,
    #endif
    		D3D10_FEATURE_LEVEL_10_1,
    		D3D10_1_SDK_VERSION,
    		&swapChainDesc,
    		&m_pSwapChain,
    		&m_pD3DDevice);

    プログラムがクラッシュするという現象の原因は分かりませんが、オブジェクトを解放することなく新しく作成するようなことを繰り返していればリソース不足で落ちることは考えられます。デバッガーをアタッチするか、もしくはイベントビューアーで異常終了時の例外エラーコード(スタックオーバーフロー、アクセス違反、……)をチェックするなりして根気強くPostmortemデバッグすればたいていの原因は掴めるはずです。

    • 編集済み sygh 2014年3月24日 17:07
    • 回答としてマーク たけし 2014年3月24日 17:56
    2014年3月24日 16:32
  • Azuleanさん、ありがとうございます。

    ソースコードを見直します。

    2014年3月24日 17:50
  • syghさん、ありがとうございます。

    根気強く探してみます。

    2014年3月24日 17:55
  • syghさん、ありがとうございます。

    OnDestroy()でDirectXオブジェクトを解放していませんでした。

    DirectX9の時はOnDestroy()で解放していたのですが、それが原因とはわかりませんでした。

    2014年5月11日 15:35