GPUViewのEvent ViewでDX11のPerf Eventを確認する

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から十分有用な情報が得られると思います。

dx11perfmarker