GPUViewのEvent ViewでDX11のPerf Eventを確認する手順です。
テストした環境
- Windows10 RS1 (Version 1607)
- Windows_SDK 10.0.10586.11
WindowsSDKをインストールする際には、Windows Performance Toolkitを選択するのを忘れると、GPUViewはインストールされないので注意が必要です。
アプリ内でのPerfEventの設定方法
GPUViewで確認可能なDX11 Eventは、下記のID3DUserDefinedAnnotationインターフェースを用いて設定されたものになります。DX9のPerfEventはGPUView上では確認できません。
このインターフェースが宣言されているのは、d3d11_1.hになります。しかし使用する際にはID3D11Device1のインターフェースの作成が必須ではないようです。手元で試したところ、D3D11のDeviceContextからQueryInterfaceすることで、インターフェースが取得できました。既存のアプリでD3D11_1.hをインクルードするのに問題がある場合は、下記ののインターフェースだけ抜粋して宣言すれば使えると思います。
MIDL_INTERFACE("b2daad8b-03d4-4dbf-95eb-32ab4b63d0ab") ID3DUserDefinedAnnotation : public IUnknown { public: virtual INT STDMETHODCALLTYPE BeginEvent( /* [annotation] */ _In_ LPCWSTR Name) = 0; virtual INT STDMETHODCALLTYPE EndEvent(void) = 0; virtual void STDMETHODCALLTYPE SetMarker( /* [annotation] */ _In_ LPCWSTR Name) = 0; virtual BOOL STDMETHODCALLTYPE GetStatus(void) = 0; }; . . . CComPtr pPerf; HRESULT hr = pID3D11DeviceContext->QueryInterface( __uuidof(pPerf), reinterpret_cast(&pPerf) );
Eventをキャプチャする
Eventをキャプチャする際は、Admin権限で、下記のコマンドを実行します。
Log.cmd normal
特別なことをする必要はありません。エラーが出てないことを確認して、もう一度Log.cmdを実行してキャプチャを終了します。
GPUViewで確認
生成されたMerged.etlをGPUViewで開いて確認します。EditメニューからEvent Viewを開いて、Eventを確認したい期間を設定します。適当にグラフをズームして、Cur ViewTimeボタンで設定できます。GUID ListのDirect3D11 Markerの項を選択すれば、選択した期間で発生したMarker Eventが表示されます。EventDataのLabelには、PerfMarkerの文字列が表示されるので、複数のイベントが存在する場合でも容易に確認できます。Marker Eventとして表示されるのは、SetMarker()とBeginEvent()のようです。
注意事項として、以下のグラフを見ても分かるとおり、イベントのタイミングはGPU側ではなくCPU側のものと思われます。おそらくはDeviceContextがMarkerをParseしたタイミングと思われます。したがって、Maker間の経過時間を測っても、あまり意味はありません。しかし、CPU-GPU間でのリソース同期などが発生しているケースや、CPU側で大きなStallなどが発生しているケースでは、Markerから十分有用な情報が得られると思います。