ID3D12CommandQueue
COM公式ドキュメント
コマンドリストの送信、コマンドリスト実行の同期、コマンドキューへの計測情報の挿入、およびリソースのタイルマッピングの更新を行うためのメソッドを提供します。
解説(Remarks)
コマンドキューオブジェクトを作成するには ID3D12Device::CreateCommandQueue を使用します。
使用例
D3D12nBodyGravity サンプルでは、ID3D12CommandQueue を次のように使用しています。
ヘッダーファイルでの宣言。
// Compute objects.
ComPtr<ID3D12CommandAllocator> m_computeAllocator[ThreadCount];
ComPtr<ID3D12CommandQueue> m_computeCommandQueue[ThreadCount];
ComPtr<ID3D12GraphicsCommandList> m_computeCommandList[ThreadCount];
非同期コンピュートスレッド。
DWORD D3D12nBodyGravity::AsyncComputeThreadProc(int threadIndex)
{
ID3D12CommandQueue* pCommandQueue = m_computeCommandQueue[threadIndex].Get();
ID3D12CommandAllocator* pCommandAllocator = m_computeAllocator[threadIndex].Get();
ID3D12GraphicsCommandList* pCommandList = m_computeCommandList[threadIndex].Get();
ID3D12Fence* pFence = m_threadFences[threadIndex].Get();
while (0 == InterlockedGetValue(&m_terminating))
{
// Run the particle simulation.
Simulate(threadIndex);
// Close and execute the command list.
ThrowIfFailed(pCommandList->Close());
ID3D12CommandList* ppCommandLists[] = { pCommandList };
pCommandQueue->ExecuteCommandLists(1, ppCommandLists);
// Wait for the compute shader to complete the simulation.
UINT64 threadFenceValue = InterlockedIncrement(&m_threadFenceValues[threadIndex]);
ThrowIfFailed(pCommandQueue->Signal(pFence, threadFenceValue));
ThrowIfFailed(pFence->SetEventOnCompletion(threadFenceValue, m_threadFenceEvents[threadIndex]));
WaitForSingleObject(m_threadFenceEvents[threadIndex], INFINITE);
// Wait for the render thread to be done with the SRV so that
// the next frame in the simulation can run.
UINT64 renderContextFenceValue = InterlockedGetValue(&m_renderContextFenceValues[threadIndex]);
if (m_renderContextFence->GetCompletedValue() < renderContextFenceValue)
{
ThrowIfFailed(pCommandQueue->Wait(m_renderContextFence.Get(), renderContextFenceValue));
InterlockedExchange(&m_renderContextFenceValues[threadIndex], 0);
}
// Swap the indices to the SRV and UAV.
m_srvIndex[threadIndex] = 1 - m_srvIndex[threadIndex];
// Prepare for the next frame.
ThrowIfFailed(pCommandAllocator->Reset());
ThrowIfFailed(pCommandList->Reset(pCommandAllocator, m_computeState.Get()));
}
return 0;
}
D3D12 リファレンスのサンプルコードについて も参照してください。
メソッド 11
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
予約リソース内のタイル位置から、リソースヒープ内のメモリ位置へのマッピングを更新します。
| pResource | ID3D12Resource* | in | 予約リソースへのポインター。 |
| NumResourceRegions | DWORD | in | 予約リソース領域の数。 |
| pResourceRegionStartCoordinates | D3D12_TILED_RESOURCE_COORDINATE* | inoptional | 予約リソース領域の開始座標を記述する D3D12_TILED_RESOURCE_COORDINATE 構造体の配列。配列内の D3D12_TILED_RESOURCE_COORDINATE 構造体の数は NumResourceRegions パラメーターで指定します。 |
| pResourceRegionSizes | D3D12_TILE_REGION_SIZE* | inoptional | 予約リソース領域のサイズを記述する D3D12_TILE_REGION_SIZE 構造体の配列。配列内の D3D12_TILE_REGION_SIZE 構造体の数は NumResourceRegions パラメーターで指定します。 |
| pHeap | ID3D12Heap* | inoptional | リソースヒープへのポインター。 |
| NumRanges | DWORD | in | タイル範囲の数。 |
| pRangeFlags | D3D12_TILE_RANGE_FLAGS* | inoptional | 各タイル範囲を記述する D3D12_TILE_RANGE_FLAGS 値の配列へのポインター。配列内の値の数は NumRanges パラメーターで指定します。 |
| pHeapRangeStartOffsets | DWORD* | inoptional | リソースヒープ内へのオフセットの配列。これらは 0 起点のタイルオフセットで、バイト単位ではなくタイル単位で数えます。 |
| pRangeTileCounts | DWORD* | inoptional | タイル数の配列。 各タイル範囲に含まれるタイルの数を指定する値の配列です。配列内の値の数は NumRanges パラメーターで指定します。 |
| Flags | D3D12_TILE_MAPPING_FLAGS | in | ビットごとの OR 演算で組み合わせた D3D12_TILE_MAPPING_FLAGS 値の組み合わせ。 |
解説(Remarks)
UpdateTileMappings を使用すると、予約リソースの仮想ページをヒープの物理ページにマップできます。マッピングは順序どおりである必要はありません。この操作は ID3D11DeviceContext2::UpdateTileMappings に似ていますが、D3D12 では予約リソースが複数のヒープのタイルを持てるという重要な違いがあります。
UpdateTileMappings の 1 回の呼び出しで、1 つ以上のリソースタイル範囲を 1 つ以上のヒープタイル範囲にマップできます。
更新を行うには、UpdateTileMappings のパラメーターを次のように構成できます。
- マッピングを更新する予約リソース。 リソースを最初に作成した時点では、マッピングはすべて NULL です。
- マッピングを更新する、予約リソース上のタイル領域の集合。 1 回の UpdateTileMappings 呼び出しで多数のマッピングを更新することも、都合がよければ、API 呼び出しのオーバーヘッドは多少増えますが複数回に分けて呼び出すこともできます。
- NumResourceRegions は領域の数を指定します。
- pResourceRegionStartCoordinates と pResourceRegionSizes はそれぞれ配列で、各領域の開始位置と範囲を指定します。NumResourceRegions が 1 の場合は、便宜上、領域を記述するこれらの配列のいずれか、または両方を NULL にできます。pResourceRegionStartCoordinates が NULL の場合は開始座標がすべて 0 であることを意味し、pResourceRegionSizes が NULL の場合は、すべてのミップマップや配列スライスを含む予約リソース全体のタイル一式を表す既定の領域を指します。
- pResourceRegionStartCoordinates が NULL でなく、pResourceRegionSizes が NULL の場合、すべての領域のサイズは既定で 1 タイルになります。これにより、すべて 1 に設定した pResourceRegionSizes の配列を渡すことなく、pResourceRegionStartCoordinates に位置の配列を指定するだけで、離れた位置にある個々のタイルの集合に対するマッピングを簡単に定義できます。
- タイルマッピングの割り当て先となるメモリを提供するヒープ。 UpdateTileMappings が NULL マッピングのみを定義する場合、ヒープを指定する必要はありません。
- マッピング先となるタイル範囲の集合。 各タイル範囲では、いくつかの種類の範囲のうち 1 つを指定できます。すなわち、ヒープ内のタイルの範囲(既定)、ヒープ内の単一タイルにマップする予約リソース内のタイル数(タイルの共有)、変更せずにそのまま残す予約リソース内のタイルマッピングの数、または NULL にマップするタイルの数です。NumRanges はタイル範囲の数を指定します。すべての範囲にわたるタイルの総数は、前述の予約リソースのタイル領域に含まれるタイルの総数と一致する必要があります。マッピングは、タイル領域内のタイルを順番に(ボックス領域の場合は x、y、z の順に)たどりながら、タイル範囲の集合を順番に進めていくことで定義されます。タイル領域の区切りとタイル範囲の区切りが揃っている必要はありませんが、指定した各予約リソースタイルにマッピングが割り当てられるよう、両者のタイル総数は等しくなければなりません。
pRangeFlags、pHeapRangeStartOffsets、pRangeTileCounts はいずれもサイズ NumRanges の配列で、タイル範囲を記述します。pRangeFlags が NULL の場合、すべての範囲はヒープ内の連続したタイルになります。そうでない場合、各範囲 i について pRangeFlags[i] がそのタイル範囲におけるマッピングの動作を指定します。
- pRangeFlags[i] が D3D12_TILE_RANGE_FLAG_NONE の場合、その範囲はヒープ内の連続したタイルを表し、タイル数は pRangeTileCounts[i]、開始位置は pHeapRangeStartOffsets[i] です。NumRanges が 1 の場合、pRangeTileCounts は NULL にでき、既定ですべてのタイル領域で指定されたタイルの総数になります。
- pRangeFlags[i] が D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE の場合、pHeapRangeStartOffsets[i] はマップ先となるヒープ内の単一タイルを指定し、pRangeTileCounts[i] はタイル領域内の何個のタイルをそのヒープ位置にマップするかを指定します。NumRanges が 1 の場合、pRangeTileCounts は NULL にでき、既定ですべてのタイル領域で指定されたタイルの総数になります。
- pRangeFlags[i] が D3D12_TILE_RANGE_FLAG_NULL の場合、pRangeTileCounts[i] はタイル領域内の何個のタイルを NULL にマップするかを指定します。NumRanges が 1 の場合、pRangeTileCounts は NULL にでき、既定ですべてのタイル領域で指定されたタイルの総数になります。NULL マッピングでは pHeapRangeStartOffsets[i] は無視されます。
- pRangeFlags[i] が D3D12_TILE_RANGE_FLAG_SKIP の場合、pRangeTileCounts[i] はタイル領域内の何個のタイルをスキップし、既存のマッピングを変更しないまま残すかを指定します。これは、更新対象のタイルマッピング領域をタイル領域で都合よく囲めるものの、一部については以前のマッピングのまま残したい場合に便利です。SKIP マッピングでは pHeapRangeStartOffsets[i] は無視されます。
以下に、代表的な UpdateTileMappings の使用例を示します。
使用例
これらの例では次の構造体および列挙型を参照します。
サーフェス全体のマッピングを NULL にクリアする// - NULL for pResourceRegionStartCoordinates and pResourceRegionSizes defaults to the entire resource
// - NULL for pHeapRangeStartOffsets since it isn't needed for mapping tiles to NULL
// - NULL for pRangeTileCounts when NumRanges is 1 defaults to the same number of tiles as the resource region (which is
// the entire surface in this case)
//
UINT RangeFlags = D3D12_TILE_RANGE_FLAG_NULL;
pCommandQueue->UpdateTileMappings(pResource, 1, NULL, NULL, NULL, 1, &RangeFlags, NULL, NULL, D3D12_TILE_MAPPING_FLAG_NONE);
タイル領域を単一のタイルにマップする:
// - This maps a 2x3 tile region at tile offset (1,1) in a resource to tile [12] in a heap
//
D3D12_TILED_RESOURCE_COORDINATE TRC;
TRC.X = 1;
TRC.Y = 1;
TRC.Z = 0;
TRC.Subresource = 0;
D3D12_TILE_REGION_SIZE TRS;
TRS.bUseBox = TRUE;
TRS.Width = 2;
TRS.Height = 3;
TRS.Depth = 1;
TRS.NumTiles = TRS.Width * TRS.Height * TRS.Depth;
UINT RangeFlags = D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE;
UINT StartOffset = 12;
pCommandQueue->UpdateTileMappings(pResource,1,&TRC,&TRS,pHeap,1,&RangeFlags,&StartOffset,NULL,D3D12_TILE_MAPPING_FLAG_NONE);
離れた位置にある個々のタイルの集合に対してマッピングを定義する:
// - This can also be accomplished in multiple calls.
// A single call to define multiple mapping updates can reduce CPU call overhead slightly,
// at the cost of having to pass arrays as parameters.
// - Passing NULL for pResourceRegionSizes defaults to each region in the resource
// being a single tile. So all that is needed are the coordinates of each one.
// - Passing NULL for pRangeFlags defaults to no flags (since none are needed in this case)
// - Passing NULL for pRangeTileCounts defaults to each range in the heap being size 1.
// So all that is needed are the start offsets for each tile in the heap
//
D3D12_TILED_RESOURCE_COORDINATE TRC[3];
UINT StartOffsets[3];
UINT NumSingleTiles = 3;
TRC[0].X = 1;
TRC[0].Y = 1;
TRC[0].Subresource = 0;
StartOffsets[0] = 1;
TRC[1].X = 4;
TRC[1].Y = 7;
TRC[1].Subresource = 0;
StartOffsets[1] = 4;
TRC[2].X = 2;
TRC[2].Y = 3;
TRC[2].Subresource = 0;
StartOffsets[2] = 7;
pCommandQueue->UpdateTileMappings(pResource,NumSingleTiles,&TRC,NULL,pHeap,NumSingleTiles,NULL,StartOffsets,
NULL,D3D12_TILE_MAPPING_FLAG_NONE);
複雑な例 - 一部をスキップし、一部を NULL マッピングにする領域のマッピング定義。
// - This complex example hard codes the parameter arrays, whereas in practice the
// application would likely configure the parameters programatically or in a data driven way.
// - Suppose we have 3 regions in a resource to configure mappings for, 2x3 at coordinate (1,1),
// 3x3 at coordinate (4,7), and 7x1 at coordinate (20,30)
// - The tiles in the regions are walked from first to last, in X then Y then Z order,
// while stepping forward through the specified Tile Ranges to determine each mapping.
// In this example, 22 tile mappings need to be defined.
// - Suppose we want the first 3 tiles to be mapped to a contiguous range in the heap starting at
// heap location [9], the next 8 to be skipped (left unchanged), the next 2 to map to NULL,
// the next 5 to share a single tile (heap location [17]) and the remaining
// 4 tiles to each map to to unique heap locations, [2], [9], [4] and [17]:
//
D3D12_TILED_RESOURCE_COORDINATE TRC[3];
D3D12_TILE_REGION_SIZE TRS[3];
UINT NumRegions = 3;
TRC[0].X = 1;
TRC[0].Y = 1;
TRC[0].Subresource = 0;
TRS[0].bUseBox = TRUE;
TRS[0].Width = 2;
TRS[0].Height = 3;
TRS[0].NumTiles = TRS[0].Width * TRS[0].Height;
TRC[1].X = 4;
TRC[1].Y = 7;
TRC[1].Subresource = 0;
TRS[1].bUseBox = TRUE;
TRS[1].Width = 3;
TRS[1].Height = 3;
TRS[1].NumTiles = TRS[1].Width * TRS[1].Height;
TRC[2].X = 20;
TRC[2].Y = 30;
TRC[2].Subresource = 0;
TRS[2].bUseBox = TRUE;
TRS[2].Width = 7;
TRS[2].Height = 1;
TRS[2].NumTiles = TRS[2].Width * TRS[2].Height;
UINT NumRanges = 8;
UINT RangeFlags[8];
UINT HeapRangeStartOffsets[8];
UINT RangeTileCounts[8];
RangeFlags[0] = 0;
HeapRangeStartOffsets[0] = 9;
RangeTileCounts[0] = 3;
RangeFlags[1] = D3D12_TILE_RANGE_FLAG_SKIP;
HeapRangeStartOffsets[1] = 0; // offset is ignored for skip mappings
RangeTileCounts[1] = 8;
RangeFlags[2] = D3D12_TILE_RANGE_FLAG_NULL;
HeapRangeStartOffsets[2] = 0; // offset is ignored for NULL mappings
RangeTileCounts[2] = 2;
RangeFlags[3] = D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE;
HeapRangeStartOffsets[3] = 17;
RangeTileCounts[3] = 5;
RangeFlags[4] = 0;
HeapRangeStartOffsets[4] = 2;
RangeTileCounts[4] = 1;
RangeFlags[5] = 0;
HeapRangeStartOffsets[5] = 9;
RangeTileCounts[5] = 1;
RangeFlags[6] = 0;
HeapRangeStartOffsets[6] = 4;
RangeTileCounts[6] = 1;
RangeFlags[7] = 0;
HeapRangeStartOffsets[7] = 17;
RangeTileCounts[7] = 1;
pCommandQueue->UpdateTileMappings(pResource,NumRegions,TRC,TRS,pHeap,NumRanges,RangeFlags,
HeapRangeStartOffsets,RangeTileCounts,D3D12_TILE_MAPPING_FLAG_NONE);
マッピングをコピー元の予約リソースからコピー先の予約リソースへコピーします。
| pDstResource | ID3D12Resource* | in | コピー先の予約リソースへのポインター。 |
| pDstRegionStartCoordinate | D3D12_TILED_RESOURCE_COORDINATE* | in | コピー先予約リソースの開始座標を記述する D3D12_TILED_RESOURCE_COORDINATE 構造体へのポインター。 |
| pSrcResource | ID3D12Resource* | in | コピー元の予約リソースへのポインター。 |
| pSrcRegionStartCoordinate | D3D12_TILED_RESOURCE_COORDINATE* | in | コピー元予約リソースの開始座標を記述する D3D12_TILED_RESOURCE_COORDINATE 構造体へのポインター。 |
| pRegionSize | D3D12_TILE_REGION_SIZE* | in | 予約領域のサイズを記述する D3D12_TILE_REGION_SIZE 構造体へのポインター。 |
| Flags | D3D12_TILE_MAPPING_FLAGS | in | D3D12_TILE_MAPPING_FLAGS のメンバーの 1 つ。 |
解説(Remarks)
CopyTileMappings を使用すると、ある予約リソースのタイルマッピングを別の予約リソースへコピーできます。リソースのマッピングを複製する場合や、UpdateTileMappings で変更する前に新しいマッピングを初期化する場合に利用します。
CopyTileMappings は、予約リソース内および予約リソース間でマッピングを移動する処理(タイルのスクロールなど)に役立ちます。 コピー元とコピー先の領域は重なっていても構いません。その場合の結果は、コピー元を一時的な場所に保存し、そこからコピー先へ書き込んだ場合と同じになります。
コピー先およびコピー元の領域は、それぞれのリソース内に完全に収まっている必要があります。収まっていない場合、動作は未定義であり、デバッグレイヤーがエラーを出力します。
コマンドリストの配列を実行のために送信します。
| NumCommandLists | DWORD | in | 実行するコマンドリストの数。 |
| ppCommandLists | ID3D12CommandList** | in | 実行する ID3D12CommandList コマンドリストの配列。 |
解説(Remarks)
ExecuteCommandLists を(同一スレッドからでも異なるスレッドからでも)続けて 2 回呼び出した場合、1 つ目の処理 (A) が完了してから 2 つ目の処理 (B) が実行されることが保証されます。一方、ExecuteCommandLists を 2 つ のコマンドリストで呼び出すと、ドライバーは 2 つのコマンドリストをマージでき、1 つ目のコマンドリスト (C) のすべての処理が完了する前に 2 つ目のコマンドリスト (D) の処理を開始できる場合があります。具体的には、アプリケーションは A と B の間にフェンスのシグナルや待機を挿入できますが、ドライバーはそれを認識できないため、フェンス操作の前に A のすべてが完了していることを保証しなければなりません。API を 1 回呼び出す場合にはそのような余地がないため、ドライバーはそのシナリオを最適化できます。
ドライバーは、送信されたコマンドリストにパッチを当てることができます。以前の実行によって GPU (graphics processing unit) が、送信されたコマンドリストのいずれかを現在読み取っていないことを保証するのは、呼び出し側アプリケーションの責任です。
GPU へのコマンド送信に伴う固定コストを削減するため、アプリケーションではコマンドリストの実行をまとめてバッチ処理することを推奨します。
ランタイムの検証
バンドルをコマンドキューへ直接送信することはできません。このメソッドにバンドルが渡された場合、ランタイムは呼び出しを破棄します。また、いずれかのコマンドリストに対して Close 関数が呼び出されていない場合も、ランタイムは呼び出しを破棄します。
ランタイムは、Close の呼び出し後にコマンドリストに関連付けられたコマンドアロケーターがリセットされたかどうかを検出します。この場合、ランタイムは呼び出しを破棄し、デバイスを削除します。
コマンドキューのフェンスが、いずれかのコマンドリストの以前の実行がまだ完了していないことを示している場合、ランタイムは呼び出しを破棄し、デバイスを削除します。
ランタイムは、ExecuteCommandLists 内でリソース遷移バリアの「before」および「after」状態を検証します。ある遷移の「before」状態が、それ以前の遷移の「after」状態と一致しない場合、ランタイムは呼び出しを破棄し、デバイスを削除します。
ランタイムは、コマンドリストで使用されるクエリの「before」および「after」状態も検証します。エラーが検出された場合、ランタイムは呼び出しを破棄し、デバイスを削除します。
デバッグレイヤー
デバッグレイヤーは、ランタイムが呼び出しを破棄するすべてのケースについてエラーを発行します。
デバッグレイヤーは、コマンドリストから参照されているリソース(クエリを含む)が破棄されたことを検出した場合にエラーを発行します。
使用例
シーンを描画します。
// Pipeline objects.
D3D12_VIEWPORT m_viewport;
ComPtr<IDXGISwapChain3> m_swapChain;
ComPtr<ID3D11DeviceContext> m_d3d11DeviceContext;
ComPtr<ID3D11On12Device> m_d3d11On12Device;
ComPtr<ID3D12Device> m_d3d12Device;
ComPtr<IDWriteFactory> m_dWriteFactory;
ComPtr<ID2D1Factory3> m_d2dFactory;
ComPtr<ID2D1Device2> m_d2dDevice;
ComPtr<ID2D1DeviceContext2> m_d2dDeviceContext;
ComPtr<ID3D12Resource> m_renderTargets[FrameCount];
ComPtr<ID3D11Resource> m_wrappedBackBuffers[FrameCount];
ComPtr<ID2D1Bitmap1> m_d2dRenderTargets[FrameCount];
ComPtr<ID3D12CommandAllocator> m_commandAllocators[FrameCount];
ComPtr<ID3D12CommandQueue> m_commandQueue;
ComPtr<ID3D12RootSignature> m_rootSignature;
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
ComPtr<ID3D12PipelineState> m_pipelineState;
ComPtr<ID3D12GraphicsCommandList> m_commandList;
D3D12_RECT m_scissorRect;
// Render the scene.
void D3D1211on12::OnRender()
{
// Record all the commands we need to render the scene into the command list.
PopulateCommandList();
// Execute the command list.
ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
RenderUI();
// Present the frame.
ThrowIfFailed(m_swapChain->Present(1, 0));
MoveToNextFrame();
}
D3D12 リファレンスのサンプルコードについて も参照してください。
直接呼び出すことは想定されていません。コマンドキューにイベントを挿入するには PIX イベントランタイムを使用してください。(ID3D12CommandQueue.SetMarker)
| Metadata | DWORD | in | 内部使用。 |
| pData | void* | inoptional | 内部使用。 |
| Size | DWORD | in | 内部使用。 |
解説(Remarks)
これは PIX イベントランタイムが内部的に使用するサポート用メソッドです。直接呼び出すことは想定されていません。
D3D12 コマンドキュー内の現在の位置に計測用マーカーを挿入するには、PIXSetMarker 関数を使用してください。これは WinPixEventRuntime NuGet パッケージで提供されます。
直接呼び出すことは想定されていません。コマンドキューにイベントを挿入するには PIX イベントランタイムを使用してください。(ID3D12CommandQueue.BeginEvent)
| Metadata | DWORD | in | 内部使用。 |
| pData | void* | inoptional | 内部使用。 |
| Size | DWORD | in | 内部使用。 |
解説(Remarks)
これは PIX イベントランタイムが内部的に使用するサポート用メソッドです。直接呼び出すことは想定されていません。
D3D12 コマンドキュー内の現在の位置で計測領域の開始を示すには、PIXBeginEvent 関数または PIXScopedEvent マクロを使用してください。これらは WinPixEventRuntime NuGet パッケージで提供されます。
直接呼び出すことは想定されていません。コマンドキューにイベントを挿入するには PIX イベントランタイムを使用してください。(ID3D12CommandQueue.EndEvent)
解説(Remarks)
これは PIX イベントランタイムが内部的に使用するサポート用メソッドです。直接呼び出すことは想定されていません。
D3D12 コマンドキュー内の現在の位置で計測領域の終了を示すには、PIXEndEvent 関数または PIXScopedEvent マクロを使用してください。これらは WinPixEventRuntime NuGet パッケージで提供されます。
フェンスを指定した値に更新します。
| pFence | ID3D12Fence* | in | ID3D12Fence オブジェクトへのポインター。 |
| Value | ULONGLONG | in | フェンスに設定する値。 |
戻り値
型: HRESULT
このメソッドは Direct3D 12 のリターンコード のいずれかを返します。
解説(Remarks)
GPU 側からフェンス値を設定するには、このメソッドを使用します。CPU 側からフェンスを設定するには ID3D12Fence::Signal を使用してください。
使用例
コマンドキューにシグナルを追加し、コンピュートシェーダーがシミュレーションを完了するまで待機した後、フェンス値をシグナルしてインクリメントします。
// Wait for the compute shader to complete the simulation.
UINT64 threadFenceValue = InterlockedIncrement(&m_threadFenceValues[threadIndex]);
ThrowIfFailed(pCommandQueue->Signal(pFence, threadFenceValue));
ThrowIfFailed(pFence->SetEventOnCompletion(threadFenceValue, m_threadFenceEvents[threadIndex]));
WaitForSingleObject(m_threadFenceEvents[threadIndex], INFINITE);
// Add a signal command to the queue.
ThrowIfFailed(m_commandQueue->Signal(m_renderContextFence.Get(), m_renderContextFenceValue));
// Signal and increment the fence value.
ThrowIfFailed(m_commandQueue->Signal(m_renderContextFence.Get(), m_renderContextFenceValue));
m_renderContextFenceValue++;
D3D12 リファレンスのサンプルコードについて も参照してください。
GPU 側の待機をキューに登録し、直ちに制御を返します。GPU 側の待機とは、指定したフェンスが指定した値に到達するか、それを超えるまで GPU が待機することを指します。
| pFence | ID3D12Fence* | in | ID3D12Fence オブジェクトへのポインター。 |
| Value | ULONGLONG | in | コマンドキューがフェンスに対して到達または超過を待機する値。すなわち、ID3D12Fence::GetCompletedValue が Value 以上になった時点で待機が終了します。 |
戻り値
型: HRESULT
このメソッドは Direct3D 12 のリターンコード のいずれかを返します。
解説(Remarks)
待機はキューに登録されるため、API は直ちに制御を返します。指定したフェンスが要求された値に到達するまで待機する(その間は処理が実行されない)のはコマンドキューです。
CPU 側の待機(呼び出し元スレッドがフェンスが特定の値に到達するまでブロックする)を行いたい場合は、ID3D12Fence::SetEventOnCompletion API を WaitForSingleObject(または同様の API)と組み合わせて使用してください。
GPU のタイムスタンプカウンターが増加する速度を取得するためのメソッドです。
| pFrequency | ULONGLONG* | out | GPU タイムスタンプカウンターの周波数(ティック/秒)。 |
戻り値
型: HRESULT
このメソッドは Direct3D 12 のリターンコード のいずれかを返します。
解説(Remarks)
詳細については タイミング を参照してください。
CPU と GPU のタイムスタンプカウンターを同一時点でサンプリングするメソッドです。
| pGpuTimestamp | ULONGLONG* | out | GPU タイムスタンプカウンターの値。 |
| pCpuTimestamp | ULONGLONG* | out | CPU タイムスタンプカウンターの値。 |
戻り値
型: HRESULT
このメソッドは Direct3D 12 のリターンコード のいずれかを返します。
解説(Remarks)
詳細については タイミング を参照してください。
コマンドキューの記述(デスクリプション)を取得します。
戻り値
D3D12_COMMAND_QUEUE_DESC 構造体としてのコマンドキューの記述。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_ID3D12CommandQueue "{0EC870A6-5D7E-4C22-8CFC-5BAAE07616ED}" #usecom global ID3D12CommandQueue IID_ID3D12CommandQueue "{}" #comfunc global ID3D12CommandQueue_UpdateTileMappings 8 sptr,int,var,var,sptr,int,var,var,var,int #comfunc global ID3D12CommandQueue_CopyTileMappings 9 sptr,var,sptr,var,var,int #comfunc global ID3D12CommandQueue_ExecuteCommandLists 10 int,sptr #comfunc global ID3D12CommandQueue_SetMarker 11 int,sptr,int #comfunc global ID3D12CommandQueue_BeginEvent 12 int,sptr,int #comfunc global ID3D12CommandQueue_EndEvent 13 #comfunc global ID3D12CommandQueue_Signal 14 sptr,int64 #comfunc global ID3D12CommandQueue_Wait 15 sptr,int64 #comfunc global ID3D12CommandQueue_GetTimestampFrequency 16 var #comfunc global ID3D12CommandQueue_GetClockCalibration 17 var,var #comfunc global ID3D12CommandQueue_GetDesc 18 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_ID3D12CommandQueue "{0EC870A6-5D7E-4C22-8CFC-5BAAE07616ED}" #usecom global ID3D12CommandQueue IID_ID3D12CommandQueue "{}" #comfunc global ID3D12CommandQueue_UpdateTileMappings 8 sptr,int,sptr,sptr,sptr,int,sptr,sptr,sptr,int #comfunc global ID3D12CommandQueue_CopyTileMappings 9 sptr,sptr,sptr,sptr,sptr,int #comfunc global ID3D12CommandQueue_ExecuteCommandLists 10 int,sptr #comfunc global ID3D12CommandQueue_SetMarker 11 int,sptr,int #comfunc global ID3D12CommandQueue_BeginEvent 12 int,sptr,int #comfunc global ID3D12CommandQueue_EndEvent 13 #comfunc global ID3D12CommandQueue_Signal 14 sptr,int64 #comfunc global ID3D12CommandQueue_Wait 15 sptr,int64 #comfunc global ID3D12CommandQueue_GetTimestampFrequency 16 sptr #comfunc global ID3D12CommandQueue_GetClockCalibration 17 sptr,sptr #comfunc global ID3D12CommandQueue_GetDesc 18 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。