タイミング (Direct3D 12 グラフィックス)
このセクションでは、タイムスタンプのクエリと、GPU と CPU のタイムスタンプ カウンターの調整について説明します。
タイムスタンプの頻度
アプリケーションでは、コマンド キューごとに GPU タイムスタンプの頻度を照会できます ( ID3D12CommandQueue::GetTimestampFrequency メソッドを 参照してください)。
返される周波数は Hz (ティック/秒) 単位で測定されます。 指定したコマンド キューでタイムスタンプがサポートされていない場合 ( 「クエリ 」セクションの表を参照)、この API は失敗します ( E_FAILを返します)。 D3D12_COMMAND_LIST_TYPE_DIRECT と D3D12_COMMAND_LIST_TYPE_COMPUTEでは 、常にタイムスタンプがサポートされます。 D3D12_COMMAND_LIST_TYPE_COPY 必要に応じて、 D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported メンバーが TRUE の場合にタイムスタンプをサポートします。
タイムスタンプの調整
D3D12 を使用すると、アプリケーションでは、タイムスタンプのクエリから取得された結果を QueryPerformanceCounter
の呼び出しから取得された結果と関連付けることができます。 これは ID3D12CommandQueue::GetClockCalibration の呼び出しによって有効になります。
タイムスタンプは、GPU が上記のすべてのワークロードで終了した時点で GPU によってサンプリングされます。 Direct3D 11 で採用されているのと同じ動作です (「GitHub の Direct3D 11.3 機能仕様の D3D11_QUERY_TIMESTAMP 」を参照してください)。 つまり、タイムスタンプ クエリは、Direct3D 12でのパイプの下部 (BOP) 操作です。
GetClockCalibration によって、指定されたコマンド キューの GPU タイムスタンプ カウンターがサンプリングされ、ほぼ同時に QueryPerformanceCounter
を介して CPU カウンターがサンプリングされます。 指定したコマンド キューでタイムスタンプがサポートされていない場合、この API は失敗します (E_FAILを返します)。
GPU と CPU のタイムスタンプ カウンターは、必ずしもこれらのプロセッサのクロック速度に直接関係しているわけではなく、タイムスタンプのティックから機能します。
タイムスタンプ クエリ
タイムスタンプ クエリを使用して、(コマンド キューでの CPU 側の呼び出しではなく) コマンド リストの一部としてタイムスタンプを取得できます。 (一般的な クエリ の詳細については、「クエリ」を参照してください)。
すべてのタイムスタンプ クエリでは、実際のクエリ にD3D12_QUERY_TYPE_TIMESTAMP 型が使用されます。 ただし、ハードウェアの制限により、 D3D12_COMMAND_LIST_TYPE_DIRECT と D3D12_COMMAND_LIST_TYPE_COMPUTE は、D3D12_COMMAND_LIST_TYPE_COPYが使用する D3D12_QUERY_HEAP_TYPEとは異 なる D3D12_QUERY_HEAP_TYPE を使用します。
ダイレクト キューとコンピューティング キューでは 、D3D12_QUERY_HEAP_TYPE_TIMESTAMPが使用されます。
コピー キューでは 、D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMPを使用します。
コピー キュー クエリは、 D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported メンバーが TRUE の場合にのみサポートされます。
ID3D12GraphicsCommandList::ResolveQueryData を使用して解決されたタイムスタンプ クエリは、ID3D12CommandQueue::GetClockCalibration によって返されるティックを表す UINT64 であり、長さを秒単位で取得するにはキューの頻度で除算する必要があります。
重要
精度を高めるためには、タイムスタンプの 2 番目またはミリ秒の間隔を計算するときに浮動小数点演算を使用します。 たとえば、queriedTicks / Frequency
の代わりに queriedTicks / (double)Frequency
を使用します。