記念すべき初投稿は、DirectX11のデバッグレイヤーの話です。
DirectXでは、COMオブジェクトを使った設計がされています。 COMオブジェクトについては詳しく知らないので、ここでは割愛します。
ようは、Release()忘れを絶対にするなよということです。 とはいっても結構やってしまったりします。
そこで、Release忘れが発生しているかを調べる方法があります。それがデバッグレイヤーです。 デバッグレイヤーというのはD3Dデバイスの話です。 CreateDeviceをする時に、D3D11_CREATE_DEVICE_DEBUGを第4引数に渡すことで作成できます。
デバッグレイヤーはRelease忘れのチェックなどの処理をするため、普通よりも重たいです。 デバッグビルド時のみ有効にするとかしておくと便利ですね。
さて、Release忘れはこんなふうに、VisualStudioの出力ウィンドウに表示されます。
出力されるのは、アプリケーションが終了した時です。
ズラリと並んでいます。文字に色が付いているのは、拡張機能を入れているからです。
便利です。
VSColorOutput extension (VS2013です)
これすべてがRelease忘れなんですが、各文の後ろにUNKNOWNと出ています。 これでは何がRelease忘れかわかりません。レンダーターゲットビューやらテクスチャやら色々とあるのに、 これでは困ります。
しかし画像の中の一番上で、
Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting.
と書いてあります。ReportLiveObjects()を呼べば詳細を見れそうな気がします。
ここから私の長い旅が始まります。
ググってみると、IDXGIDebug::ReportLiveObjects()
とID3D11Debug::ReportLiveDeviceObjects()
が引っかかりました。
前者を解説する前に後者の説明をしたいと思います。
前者はWindows8以降でしか使えないです。
2015年2月現在、実装に至っていません。
ID3DDebug::ReportLiveDeviceObjects()
は、D3Dデバイスがデバッグレイヤーであることが前提です。
以下ソースコードです。
// dxgidebug.hをインクルードしてください。 HRESULT hr; ID3D11Device* pD3dDevice; ID3D11Debug* pD3dDebug; // デバイス作成は割愛 // 作成 hr = pD3dDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&m_pD3dDebug)); if( FAILED(hr)) { return E_FAIL; } // 詳細表示 hr = m_pD3dDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
これだけです。超簡単です。注意すべきなのは、詳細が出力ウィンドウに表示されるのは、 メソッドが呼ばれた時です。そのときのCOMオブジェクトの状況を見ることが出来ます。
先ほどと違い、オブジェクトのインターフェースが見えるようになり、InitRefというものも追加されています。
RefCount、InitRefの両方が0になって初めてCOMオブジェクトは解放されます。
(2つの違いは残念ながら私にはわかりません...)
しかし先程の一文、
Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting.
と書いてあります。あくまでReportLiveObjects()
の方です。ReportLiveDeviceObjects()
ではありません。
次回は、それを実装しようと悪戦苦闘し、あと一歩まで行った記録を記事にします。出来ました。
それではまた次回。