ID3D11DeviceContext2
COM公式ドキュメント
デバイスコンテキストインターフェイスはデバイスコンテキストを表し、レンダリングコマンドの発行に使用します。ID3D11DeviceContext2 は ID3D11DeviceContext1 のメソッドに新しいメソッドを追加します。
メソッド 10
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
タイルリソース内のタイル位置と、タイルプール内のメモリ位置とのマッピングを更新します。
| pTiledResource | ID3D11Resource* | in | タイルリソースへのポインターです。 |
| NumTiledResourceRegions | DWORD | in | タイルリソース領域の数です。 |
| pTiledResourceRegionStartCoordinates | D3D11_TILED_RESOURCE_COORDINATE* | inoptional | タイルリソース領域の開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体の配列です。配列内の D3D11_TILED_RESOURCE_COORDINATE 構造体の数は、NumTiledResourceRegions パラメーターで指定します。 |
| pTiledResourceRegionSizes | D3D11_TILE_REGION_SIZE* | inoptional | タイルリソース領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体の配列です。配列内の D3D11_TILE_REGION_SIZE 構造体の数は、NumTiledResourceRegions パラメーターで指定します。 |
| pTilePool | ID3D11Buffer* | inoptional | タイルプールへのポインターです。 |
| NumRanges | DWORD | in | タイルプール範囲の数です。 |
| pRangeFlags | DWORD* | inoptional | 各タイルプール範囲を記述する D3D11_TILE_RANGE_FLAG 値の配列です。配列内の値の数は、NumRanges パラメーターで指定します。 |
| pTilePoolStartOffsets | DWORD* | inoptional | タイルプール内へのオフセットの配列です。これらは 0 から始まるタイルオフセットで、バイト単位ではなくタイル単位で数えます。 |
| pRangeTileCounts | DWORD* | inoptional | タイルの配列です。 各タイルプール範囲内のタイル数を指定する値の配列です。配列内の値の数は、NumRanges パラメーターで指定します。 |
| Flags | DWORD | in | ビット単位の OR 演算で組み合わせた D3D11_TILE_MAPPING_FLAGS 値の組み合わせです。 |
戻り値
型: HRESULT
成功した場合は S_OK を返します。それ以外の場合は、次のいずれかを返します。
- 無効なフラグなどのさまざまな条件によって呼び出しが破棄された場合は E_INVALIDARG を返します。デバッグレイヤーはエラーを出力します。
- 呼び出しの結果、ドライバーが新しいページテーブルマッピング用の領域を確保する必要が生じ、メモリが不足した場合は E_OUTOFMEMORY を返します。コマンドリスト内でこのメソッドが呼び出され、そのコマンドリストが実行されているときにメモリ不足が発生すると、デバイスは削除されます。アプリは、コマンドリスト内ではタイルリソースの既存のマッピングを変更する更新呼び出しのみを行うことで、この状況を回避できます (これによりドライバーはページテーブルメモリを確保する必要がなく、マッピングを変更するだけで済みます)。
- ビデオカードがシステムから物理的に取り外された場合、またはビデオカードのドライバーがアップグレードされた場合は DXGI_ERROR_DEVICE_REMOVED を返します。
解説(Remarks)
UpdateTileMappings の 1 回の呼び出しで、1 つ以上のリソースタイルの範囲を、1 つ以上のタイルプールタイルの範囲にマップできます。
更新を実行するには、UpdateTileMappings のパラメーターを次のように構成します。
- マッピングを更新するタイルリソース。 これは D3D11_RESOURCE_MISC_TILED フラグを指定して作成されたリソースです。リソースを最初に作成した時点では、マッピングはすべて NULL です。
- マッピングを更新する、タイルリソース上のタイル領域のセット。 1 回の UpdateTileMappings 呼び出しで多数のマッピングを更新することも、都合がよければ、API 呼び出しのオーバーヘッドは少し増えますが複数回の呼び出しに分けることもできます。NumTiledResourceRegions は領域の数を指定し、pTiledResourceRegionStartCoordinates と pTiledResourceRegionSizes はそれぞれ各領域の開始位置と範囲を示す配列です。NumTiledResourceRegions が 1 の場合、便宜上、領域を記述するこれらの配列の一方または両方を NULL にできます。pTiledResourceRegionStartCoordinates が NULL の場合は開始座標がすべて 0 であることを意味し、pTiledResourceRegionSizes が NULL の場合は、すべてのミップマップや配列スライスを含むタイルリソース全体のタイルセットを既定の領域として示します。pTiledResourceRegionStartCoordinates が NULL でなく pTiledResourceRegionSizes が NULL の場合、領域サイズはすべての領域で 1 タイルが既定になります。これにより、pRangeTileCounts ではなく pTiledResourceRegionStartCoordinates に位置の配列を渡すだけで、すべて 1 に設定した pTiledResourceRegionSizes の配列を渡すことなく、離れた位置にある個々のタイルのセットに対するマッピングを簡単に定義できます。
更新は最初の領域から最後の領域へと順に適用されます。したがって、1 回の呼び出しの中で領域が重なり合う場合、リスト内で後にある更新が、それ以前の更新と重なる領域を上書きします。
- タイルマッピングの配置先となるメモリを提供するタイルプール。 1 つのタイルリソースは、一度に 1 つのタイルプールのみを参照できます。新しいタイルプールを指定した場合 (初回、または前回指定したタイルプールと異なる場合)、そのタイルリソースの既存のタイルマッピングはすべてクリアされ、今回の UpdateTileMappings 呼び出しで指定した新しいマッピングのセットが新しいタイルプールに対して適用されます。タイルプールを指定しない (NULL の) 場合、または以前の UpdateTileMappings 呼び出しと同じタイルプールを指定した場合、UpdateTileMappings の呼び出しは既存のマッピングに新しいマッピングを追加するだけです (重なる部分は上書きされます)。UpdateTileMappings が NULL マッピングのみを定義する場合、タイルプールは無関係なので指定する必要はありません。ただし、それでもタイルプールを指定した場合は、前述したタイルプール指定時と同じ動作になります。
- マッピング先となるタイル範囲のセット。 指定する各タイル範囲は、次のいずれかの種類の範囲を指定できます。タイルプール内のタイルの範囲 (既定)、タイルプール内の単一のタイルにマップするタイルリソース内のタイル数 (タイルの共有)、変更せずにそのままにするタイルリソース内のタイルマッピング数、NULL にマップするタイルプール内のタイル数です。NumRanges はタイル範囲の数を指定します。すべての範囲にわたって示されるタイルの合計は、前述したタイルリソースのタイル領域内のタイルの総数と一致する必要があります。マッピングは、タイル領域内のタイルを順番に (ボックス領域の場合は x、y、z の順に) たどりながら、同時にタイル範囲のセットを順番に進めることで定義されます。タイル領域の区切りとタイル範囲の区切りは一致している必要はありませんが、指定した各タイルリソースのタイルにマッピングが指定されるよう、双方のタイルの総数は等しくなければなりません。
pRangeFlags、pTilePoolStartOffsets、pRangeTileCounts はいずれもサイズが NumRanges の配列で、タイル範囲を記述します。pRangeFlags が NULL の場合、すべての範囲はタイルプール内の連続したタイルになります。そうでない場合、各範囲 i について pRangeFlags[i] がその範囲のタイルのマッピング方法を示します。
- pRangeFlags[i] が 0 の場合、その範囲はタイルプール内の連続したタイルを定義します。タイル数は pRangeTileCounts[i]、開始位置は pTilePoolStartOffsets[i] です。NumRanges が 1 の場合、pRangeTileCounts は NULL でもよく、既定ではすべてのタイル領域で指定されたタイルの総数になります。
- pRangeFlags[i] が D3D11_TILE_RANGE_REUSE_SINGLE_TILE の場合、pTilePoolStartOffsets[i] はマップ先となるタイルプール内の単一のタイルを示し、pRangeTileCounts[i] はタイル領域内の何個のタイルをそのタイルプール位置にマップするかを指定します。NumRanges が 1 の場合、pRangeTileCounts は NULL でもよく、既定ではすべてのタイル領域で指定されたタイルの総数になります。
- pRangeFlags[i] が D3D11_TILE_RANGE_NULL の場合、pRangeTileCounts[i] はタイル領域内の何個のタイルを NULL にマップするかを指定します。NumRanges が 1 の場合、pRangeTileCounts は NULL でもよく、既定ではすべてのタイル領域で指定されたタイルの総数になります。NULL マッピングでは pTilePoolStartOffsets[i] は無視されます。
- pRangeFlags[i] が D3D11_TILE_RANGE_SKIP の場合、pRangeTileCounts[i] はタイル領域内の何個のタイルをスキップし、既存のマッピングを変更せずに残すかを指定します。これは、更新対象のタイルマッピング領域をタイル領域で都合よく囲めるものの、一部については以前のマッピングのままにしておきたい場合に便利です。SKIP マッピングでは pTilePoolStartOffsets[i] は無視されます。
- 全体的なオプションを指定する Flags パラメーター。 D3D11_TILE_MAPPING_NO_OVERWRITE は、まだ実行中の可能性があるデバイスへの送信済みコマンドが、更新対象のタイル領域を一切参照していないことを呼び出し元が保証することを意味します。これにより、デバイスはタイルマッピングの更新のために送信済みの処理をフラッシュする必要がなくなります。未処理のコマンドがまだ参照しているタイルリソースの位置についてタイルマッピングを更新してこの保証に違反すると、レンダリング動作は未定義となり、一部のアーキテクチャでは大幅な速度低下を招く可能性があります。これは Direct3D API の他の場所に存在する「no overwrite」の概念と同様ですが、ハードウェア上ではページテーブルであるタイルマッピングのデータ構造そのものに適用される点が異なります。このフラグを指定しない場合、この UpdateTileMappings 呼び出しで指定されたタイルマッピングの更新は、後続の Direct3D コマンドが進行する前に完了している必要があります。
1 つのタイルが同時に複数のタイルリソースにマップされており、いずれかのタイルリソースを通じて何らかの方法 (レンダリング、コピーなど) でタイルの内容が操作されたとします。この場合、同じタイルを他のタイルリソースを通じてレンダリングするには、前述のとおり、まずそのタイルをクリアする必要があります。
タイルリソースの詳細については、「タイルリソース」を参照してください。
一般的な UpdateTileMappings の使用例をいくつか示します。
例
サーフェス全体のマッピングを NULL にクリアする:
// - GPU が実行中の他の処理が以前のマッピングを参照していないことが分かっている前提で、no-overwrite を指定しています
// - pTiledResourceRegionStatCoordinates と pTiledResourceRegionSizes に NULL を指定すると、既定でリソース全体が対象になります
// - タイルを NULL にマップする場合には不要なため、pTilePoolStartOffsets には NULL を指定します
// - NumRanges が 1 のとき pRangeTileCounts に NULL を指定すると、既定でタイルリソース領域と同じタイル数になります
// (この場合はサーフェス全体)
//
// UINT RangeFlags = D3D11_TILE_MAPPING_NULL;
// pDeviceContext2->UpdateTileMappings(pTiledResource,1,NULL,NULL,NULL,1,&RangeFlags,NULL,NULL,D3D11_TILE_MAPPING_NO_OVERWRITE);
タイル領域を単一のタイルにマップする:
// - タイルリソース内のタイルオフセット (1,1) にある 2x3 のタイル領域を、タイルプール内のタイル [12] にマップします
//
// D3D11_TILED_RESOURCE_COORDINATE TRC;
// TRC.X = 1;
// TRC.Y = 1;
// TRC.Z = 0;
// TRC.Subresource = 0;
//
// D3D11_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 = D3D11_TILE_MAPPING_REUSE_SINGLE_TILE;
// UINT StartOffset = 12;
// pDeviceContext2->UpdateTileMappings(pTiledResource,1,&TRC,&TRS,pTilePool,1,&RangeFlags,&StartOffset,
// NULL,D3D11_TILE_MAPPING_NO_OVERWRITE);
離れた位置にある個々のタイルのセットに対してマッピングを定義する:
// - これは複数回の呼び出しでも実現できます。1 回の呼び出しで複数のマッピング更新を定義すると、
// パラメーターとして配列を渡す必要はありますが、CPU の呼び出しオーバーヘッドをわずかに削減できます。
// - pTiledResourceRegionSizes に NULL を渡すと、既定でタイルリソース内の各領域が
// 単一のタイルになります。したがって、必要なのは各タイルの座標だけです。
// - Range Flags に NULL を渡すと、既定でフラグなしになります (この場合はフラグが不要なため)
// - pRangeTileCounts に NULL を渡すと、既定でタイルプール内の各範囲のサイズが 1 になります。
// したがって、必要なのはタイルプール内の各タイルの開始オフセットだけです
//
// D3D11_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;
//
// pDeviceContext2->UpdateTileMappings(pTiledResource,NumSingleTiles,&TRC,NULL,pTilePool,NumSingleTiles,NULL,StartOffsets,
// NULL,D3D11_TILE_MAPPING_NO_OVERWRITE);
複雑な例 - 一部にスキップと NULL マッピングを含む領域のマッピングを定義する:
// - この複雑な例ではパラメーターの配列をハードコードしていますが、実際のアプリケーションでは
// プログラム的またはデータ駆動的にパラメーターを構成することになるでしょう。
// - タイルリソース内にマッピングを構成したい領域が 3 つあるとします。座標 (1,1) の 2x3、
// 座標 (4,7) の 3x3、座標 (20,30) の 7x1 です。
// - 領域内のタイルは最初から最後へ、X、Y、Z の順にたどられ、
// 同時に指定されたタイル範囲を順に進めながら各マッピングが決定されます。
// この例では、22 個のタイルマッピングを定義する必要があります。
// - 最初の 3 タイルはタイルプール内の位置 [9] から始まる連続した範囲にマップし、次の 8 タイルは
// スキップ (変更しない)、次の 2 タイルは NULL にマップ、次の 5 タイルは単一のタイル
// (タイルプール位置 [17]) を共有し、残りの 4 タイルはそれぞれ固有のタイルプール位置
// [2]、[9]、[4]、[17] にマップしたいとします。
//
// D3D11_TILED_RESOURCE_COORDINATE TRC[3];
// D3D11_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 TilePoolStartOffsets[8];
// UINT RangeTileCounts[8];
//
// RangeFlags[0] = 0;
// TilePoolStartOffsets[0] = 9;
// RangeTileCounts[0] = 3;
//
// RangeFlags[1] = D3D11_TILE_MAPPING_SKIP;
// TilePoolStartOffsets[1] = 0; // skip マッピングではオフセットは無視されます
// RangeTileCounts[1] = 8;
//
// RangeFlags[2] = D3D11_TILE_MAPPING_NULL;
// TilePoolStartOffsets[2] = 0; // NULL マッピングではオフセットは無視されます
// RangeTileCounts[2] = 2;
//
// RangeFlags[3] = D3D11_TILE_MAPPING_REUSE_SINGLE_TILE;
// TilePoolStartOffsets[3] = 17;
// RangeTileCounts[3] = 5;
//
// RangeFlags[4] = 0;
// TilePoolStartOffsets[4] = 2;
// RangeTileCounts[4] = 1;
//
// RangeFlags[5] = 0;
// TilePoolStartOffsets[5] = 9;
// RangeTileCounts[5] = 1;
//
// RangeFlags[6] = 0;
// TilePoolStartOffsets[6] = 4;
// RangeTileCounts[6] = 1;
//
// RangeFlags[7] = 0;
// TilePoolStartOffsets[7] = 17;
// RangeTileCounts[7] = 1;
//
// pDeviceContext2->UpdateTileMappings(pTiledResource,NumRegions,TRC,TRS,pTilePool,NumRanges,RangeFlags,
// TilePoolStartOffsets,RangeTileCounts,D3D11_TILE_MAPPING_NO_OVERWRITE);
CopyTileMappings
// CopyTileMappings は、タイルリソース内またはタイルリソース間でマッピングをずらす (タイルのスクロールなど) といった作業に役立ちます。
// コピー元とコピー先の領域は重なり合っても構いません。この場合のコピー結果は、コピー元をいったん一時領域に保存し、
// そこからコピー先へ書き込んだ場合と同じになります (実装によってはより効率的に処理される場合があります)。
//
// Flags フィールドには D3D11_TILE_MAPPING_NO_OVERWRITE を指定できます。これは、まだ実行中の可能性がある
// デバイスへの送信済みコマンドが、更新対象のタイル領域を一切参照していないことを呼び出し元が保証することを意味します。
// これにより、デバイスはタイルマッピングの更新のために送信済みの処理をフラッシュする必要がなくなります。
// 未処理のコマンドがまだ参照しているタイルリソースの位置についてタイルマッピングを更新してこの保証に違反すると、
// レンダリング動作は未定義となり、一部のアーキテクチャでは大幅な速度低下を招く可能性があります。
// これは API の他の場所に存在する「no overwrite」の概念と同様ですが、タイルマッピングのデータ構造そのもの
// (ハードウェア上ではページテーブル) に適用される点が異なります。
// このフラグを指定しない場合、この呼び出しで指定されたタイルマッピングの更新は、後続の D3D コマンドが
// 進行する前に完了している必要があります。
//
// 戻り値:
//
// S_OK、E_INVALIDARG、または E_OUTOFMEMORY を返します。E_OUTOFMEMORY は、呼び出しの結果ドライバーが
// 新しいページテーブルマッピング用の領域を確保する必要が生じ、メモリが不足した場合に発生します。
//
// コマンドリスト内でこれが呼び出され、そのコマンドリストが実行されているときにメモリ不足が発生すると、デバイスは削除されます。
// アプリケーションは、コマンドリスト内ではタイルリソースの既存のマッピングを変更する更新呼び出しのみを行うことで、
// この状況を回避できます (これによりドライバーはページテーブルメモリを確保する必要がなく、マッピングを変更するだけで済みます)。
//
// 無効なフラグの指定や、タイルリソースでないリソースの受け渡しなど、その他のさまざまな基本的な条件により、
// 呼び出しは E_INVALIDARG で破棄されます。
//
// 検証に関する注意:
//
// コピー先とコピー元の領域は、それぞれのリソース内に完全に収まっている必要があります。そうでない場合の動作は未定義です
// (デバッグレイヤーがエラーを出力します)。
コピー元のタイルリソースからコピー先のタイルリソースへ、マッピングをコピーします。
| pDestTiledResource | ID3D11Resource* | in | コピー先のタイルリソースへのポインターです。 |
| pDestRegionStartCoordinate | D3D11_TILED_RESOURCE_COORDINATE* | in | コピー先のタイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。 |
| pSourceTiledResource | ID3D11Resource* | in | コピー元のタイルリソースへのポインターです。 |
| pSourceRegionStartCoordinate | D3D11_TILED_RESOURCE_COORDINATE* | in | コピー元のタイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。 |
| pTileRegionSize | D3D11_TILE_REGION_SIZE* | in | タイル領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体へのポインターです。 |
| Flags | DWORD | in | ビット単位の OR 演算で組み合わせた D3D11_TILE_MAPPING_FLAGS 値の組み合わせです。有効な値は D3D11_TILE_MAPPING_NO_OVERWRITE のみで、これはまだ実行中の可能性があるデバイスへの送信済みコマンドが、更新対象のタイル領域を一切参照していないことを示します。これにより、デバイスはタイルマッピングの更新のために送信済みの処理をフラッシュする必要がなくなります。未処理のコマンドがまだ参照しているタイルリソースの位置についてタイルマッピングを更新してこの保証に違反すると、レンダリング動作は未定義となり、一部のアーキテクチャでは大幅な速度低下を招く可能性があります。これは Direct3D API の他の場所に存在する「no overwrite」の概念と同様ですが、タイルマッピングのデータ構造そのもの (ハードウェア上ではページテーブル) に適用される点が異なります。D3D11_TILE_MAPPING_NO_OVERWRITE 値を指定しない場合、CopyTileMappings が指定するタイルマッピングの更新は、後続の Direct3D コマンドが進行する前に完了している必要があります。 |
戻り値
型: HRESULT
成功した場合は S_OK を返します。それ以外の場合は、次のいずれかを返します。
- 無効なフラグの指定や、タイルリソースでないリソースの受け渡しなど、さまざまな条件によって呼び出しが破棄された場合は E_INVALIDARG を返します。 コピー先とコピー元の領域は、それぞれのリソース内に完全に収まっている必要があります。そうでない場合の動作は未定義です (デバッグレイヤーがエラーを出力します)。
- 呼び出しの結果、ドライバーが新しいページテーブルマッピング用の領域を確保する必要が生じ、メモリが不足した場合は E_OUTOFMEMORY を返します。 コマンドリスト内でこれが呼び出され、そのコマンドリストが実行されているときにメモリ不足が発生すると、デバイスは削除されます。アプリケーションは、コマンドリスト内ではタイルリソースの既存のマッピングを変更する更新呼び出しのみを行うことで、この状況を回避できます (これによりドライバーはページテーブルメモリを確保する必要がなく、マッピングを変更するだけで済みます)。
解説(Remarks)
CopyTileMappings は、タイルリソース内またはタイルリソース間でマッピングをずらす (たとえばタイルのスクロール) といった作業に役立ちます。コピー元とコピー先の領域は重なり合っても構いません。この場合のコピー結果は、コピー元をいったん一時的な場所に保存し、そこからコピー先へ書き込んだ場合と同じになります。
タイルリソースの詳細については、「タイルリソース」を参照してください。
バッファーからタイルリソースへ、またはその逆方向にタイルをコピーします。(ID3D11DeviceContext2.CopyTiles)
| pTiledResource | ID3D11Resource* | in | タイルリソースへのポインターです。 |
| pTileRegionStartCoordinate | D3D11_TILED_RESOURCE_COORDINATE* | in | タイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。 |
| pTileRegionSize | D3D11_TILE_REGION_SIZE* | in | タイル領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体へのポインターです。 |
| pBuffer | ID3D11Buffer* | in | デフォルト、ダイナミック、またはステージングのバッファーを表す ID3D11Buffer へのポインターです。 |
| BufferStartOffsetInBytes | ULONGLONG | in | 操作を開始する、pBuffer のバッファー内へのバイト単位のオフセットです。 |
| Flags | DWORD | in | ビット単位の OR 演算で組み合わせた D3D11_TILE_COPY_FLAG 型の値の組み合わせで、タイルをどのようにコピーするかを指定します。 |
解説(Remarks)
CopyTiles は、マップされていない領域への書き込み操作を破棄し、マップされていない領域からの読み取り操作を処理します (Tier_1 のタイルリソースを除きます。Tier_1 では、マップされていない領域の読み取りと書き込みは無効です)。
コピー先リソース内の複数の位置が同じタイルメモリにマップされているために、同じメモリ位置への書き込みが複数回発生するコピー操作では、多重マップされたタイルへの書き込み結果は非決定的かつ再現性がありません。つまり、タイルメモリへのアクセスは、ハードウェアがコピー操作を実行する順序に依存します。
コピー操作の対象となるタイルには、パックされたミップマップを含むタイルを含めることはできません。含めた場合、コピー操作の結果は未定義になります。パックされたミップを構成する 1 つ以上のタイルにハードウェアがパックするミップマップとの間でデータを転送するには、標準の (つまりタイル固有ではない) コピーおよび更新 API (ID3D11DeviceContext1::CopySubresourceRegion1 や ID3D11DeviceContext1::UpdateSubresource1 など) を使用するか、ミップマップチェーン全体に対して ID3D11DeviceContext::GenerateMips を使用する必要があります。
コピー操作のうちタイルリソースでないバッファーリソース側におけるタイルのメモリレイアウトは、64 KB のタイル内で線形になっており、タイルリソースとの間で転送する際に、ハードウェアとドライバーがタイルごとに適宜スウィズル/デスウィズルを行います。マルチサンプルアンチエイリアシング (MSAA) のサーフェスでは、ハードウェアとドライバーは各ピクセルのサンプルをサンプルインデックス順にたどってから次のピクセルへ移ります。右側が部分的にしか埋まっていないタイル (幅がタイル幅のピクセル数の倍数でないサーフェスの場合) では、次の行へ移るためのピッチとストライドは、タイルが完全に埋まっていた場合にタイル幅に収まるピクセル数分のバイト単位のサイズ全体になります。したがって、メモリ内のピクセルの行と行の間にすき間ができることがあります。タイルより小さいミップマップは線形レイアウト内でまとめてパックされないため、メモリ空間の無駄に見えるかもしれませんが、前述のとおり、ハードウェアがまとめてパックするミップマップへのコピーには CopyTiles や ID3D11DeviceContext2::UpdateTiles を使用できません。小さなミップマップを個別にコピーするには、汎用のコピーおよび更新 API (ID3D11DeviceContext1::CopySubresourceRegion1 や ID3D11DeviceContext1::UpdateSubresource1 など) を使用すればよいだけです。ただし、汎用のコピー API (ID3D11DeviceContext1::CopySubresourceRegion1 など) の場合、線形メモリはタイルリソースと同じ次元でなければなりません。たとえば ID3D11DeviceContext1::CopySubresourceRegion1 は、バッファーリソースから Texture2D へコピーすることはできません。
タイルリソースの詳細については、「タイルリソース」を参照してください。
アプリのメモリからタイルリソースへコピーすることで、タイルを更新します。
| pDestTiledResource | ID3D11Resource* | in | 更新するタイルリソースへのポインターです。 |
| pDestTileRegionStartCoordinate | D3D11_TILED_RESOURCE_COORDINATE* | in | タイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。 |
| pDestTileRegionSize | D3D11_TILE_REGION_SIZE* | in | タイル領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体へのポインターです。 |
| pSourceTileData | void* | in | UpdateTiles がタイルリソースの更新に使用する、コピー元のタイルデータが格納されたメモリへのポインターです。 |
| Flags | DWORD | in | ビット単位の OR 演算で組み合わせた D3D11_TILE_COPY_FLAG 型の値の組み合わせです。有効な値は D3D11_TILE_COPY_NO_OVERWRITE のみです。 他の値はここでは意味を持ちません。ただし 定義上、D3D11_TILE_COPY_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE の値は基本的に UpdateTiles が行う処理と同じですが、コピー元がアプリのメモリである点が異なります。 |
解説(Remarks)
UpdateTiles は、マップされていない領域への書き込み操作を破棄します (Tier_1 のタイルリソースを除きます。Tier_1 では、マップされていない領域への書き込みは無効です)。
コピー先リソース内の複数の位置が同じタイルメモリにマップされているために、同じメモリ位置への書き込みが複数回発生するコピー操作では、多重マップされたタイルへの書き込み結果は非決定的かつ再現性がありません。つまり、タイルメモリへのアクセスは、ハードウェアがコピー操作を実行する順序に依存します。
コピー操作の対象となるタイルには、パックされたミップマップを含むタイルを含めることはできません。含めた場合、コピー操作の結果は未定義になります。ハードウェアが 1 つのタイルにパックするミップマップとの間でデータを転送するには、標準の (つまりタイル固有ではない) コピーおよび更新 API (ID3D11DeviceContext1::CopySubresourceRegion1 や ID3D11DeviceContext1::UpdateSubresource1 など) を使用するか、ミップマップチェーン全体に対して ID3D11DeviceContext::GenerateMips を使用する必要があります。
コピー操作のコピー元側におけるデータのメモリレイアウトは、64 KB のタイル内で線形になっており、タイルリソースとの間で転送する際に、ハードウェアとドライバーがタイルごとに適宜スウィズル/デスウィズルを行います。マルチサンプルアンチエイリアシング (MSAA) のサーフェスでは、ハードウェアとドライバーは各ピクセルのサンプルをサンプルインデックス順にたどってから次のピクセルへ移ります。右側が部分的にしか埋まっていないタイル (幅がタイル幅のピクセル数の倍数でないサーフェスの場合) では、次の行へ移るためのピッチとストライドは、タイルが完全に埋まっていた場合にタイル幅に収まるピクセル数分のバイト単位のサイズ全体になります。したがって、メモリ内のピクセルの行と行の間にすき間ができることがあります。タイルより小さいミップマップは線形レイアウト内でまとめてパックされないため、メモリ空間の無駄に見えるかもしれませんが、前述のとおり、ハードウェアがまとめてパックするミップマップへのコピーには ID3D11DeviceContext2::CopyTiles や UpdateTiles を使用できません。小さなミップマップを個別にコピーするには、汎用のコピーおよび更新 API (ID3D11DeviceContext1::CopySubresourceRegion1 や ID3D11DeviceContext1::UpdateSubresource1 など) を使用すればよいだけです。ただし、汎用のコピー API (ID3D11DeviceContext1::CopySubresourceRegion1 など) の場合、線形メモリはタイルリソースと同じ次元でなければなりません。たとえば ID3D11DeviceContext1::CopySubresourceRegion1 は、バッファーリソースから Texture2D へコピーすることはできません。
タイルリソースの詳細については、「タイルリソース」を参照してください。
タイルプールのサイズを変更します。
| pTilePool | ID3D11Buffer* | in | サイズを変更するタイルプールの ID3D11Buffer へのポインターです。 |
| NewSizeInBytes | ULONGLONG | in | タイルプールの新しいサイズ (バイト単位) です。サイズは 64 KB の倍数または 0 でなければなりません。 |
戻り値
型: HRESULT
成功した場合は S_OK を返します。それ以外の場合は、次のいずれかを返します。
- 新しいタイルプールのサイズが 64 KB の倍数でも 0 でもない場合は E_INVALIDARG を返します。
- 呼び出しの結果、ドライバーが新しいページテーブルマッピング用の領域を確保する必要が生じ、メモリが不足した場合は E_OUTOFMEMORY を返します。
- ビデオカードがシステムから物理的に取り外された場合、またはビデオカードのドライバーがアップグレードされた場合は DXGI_ERROR_DEVICE_REMOVED を返します。
解説(Remarks)
ResizeTilePool は、タイルプールにマップされているタイルリソースに対してアプリがより多くの、あるいはより少ないワーキングセットを必要とするかに応じて、タイルプールのサイズを増減します。アプリは新しいタイルリソース用に追加のタイルプールを割り当てることもできますが、単一のタイルリソースがそのタイルプール内で当初利用可能な容量を超える領域を必要とする場合、アプリはそのリソースのタイルプールのサイズを増やすことができます。1 つのタイルリソースが同時に複数のタイルプールへマッピングを持つことはできません。
タイルプールのサイズを増やすと、ドライバーによる 1 つ以上の新しい割り当てを通じて、タイルプールの末尾に追加のタイルが加えられます。アプリが新しい割り当ての内訳を知ることはできません。タイルプール内の既存のメモリはそのまま保たれ、そのメモリへの既存のタイルリソースのマッピングも維持されます。
タイルプールのサイズを減らすと、末尾からタイルが取り除かれます (当初の割り当てサイズを下回り、0 まで減らすことも可能です)。つまり、新しいサイズを超える位置には新しいマッピングを作成できなくなります。ただし、新しいサイズの末尾を超える既存のマッピングはそのまま維持され、使用可能です。タイルプールのメモリとして使用されている割り当ての一部にマッピングが残っている限り、そのメモリはアクティブなまま保持されます。サイズを減らした後、タイルマッピングがそこを指しているためにメモリの一部がアクティブなまま保持されている状態でタイルプールのサイズを再び (どれだけであれ) 増やした場合、増加分に対応するための追加の割り当てが行われる前に、まず既存のメモリが再利用されます。
メモリを節約するには、アプリはタイルプールのサイズを減らすだけでなく、新しい小さなタイルプールサイズの末尾を超える既存のマッピングを削除し、マップし直す必要があります。
サイズを減らして (マッピングを削除して) も、必ずしも即座にメモリが節約されるわけではありません。メモリが解放されるかどうかは、タイルプールに対するドライバー内部の割り当ての粒度に依存します。タイルプールのサイズ減少がドライバーの割り当てを未使用にするのに十分であれば、ドライバーはその割り当てを解放できます。タイルプールのサイズを増やした後、以前のサイズまで減らした場合 (かつ、それに応じてタイルマッピングを削除して再マップした場合)、多くの場合メモリが節約されます。ただし、サイズがドライバーの選択した内部の割り当てサイズと正確に一致しない場合、これは保証されません。
タイルリソースの詳細については、「タイルリソース」を参照してください。
複数のタイルリソース間のデータアクセス順序の制約を指定します。
| pTiledResourceOrViewAccessBeforeBarrier | ID3D11DeviceChild* | inoptional | D3D11_RESOURCE_MISC_TILED フラグを指定して作成されたリソースの ID3D11Resource または ID3D11View へのポインターです。このオブジェクトに対するアクセス操作は、pTiledResourceOrViewAccessAfterBarrier で指定されるオブジェクトに対するアクセス操作より前に完了している必要があります。 |
| pTiledResourceOrViewAccessAfterBarrier | ID3D11DeviceChild* | inoptional | D3D11_RESOURCE_MISC_TILED フラグを指定して作成されたリソースの ID3D11Resource または ID3D11View へのポインターです。このオブジェクトに対するアクセス操作は、pTiledResourceOrViewAccessBeforeBarrier で指定されるオブジェクトに対するアクセス操作より後に開始される必要があります。 |
解説(Remarks)
アプリはタイルリソースを使用して、異なるリソース間でタイルを再利用できます。しかし、デバイスやドライバーは、レンダリング直後のタイルプール内のメモリが読み取りに使用されているかどうかを判断できない場合があります。
たとえば、アプリがあるタイルリソースを使ってタイルプール内の一部のタイルにレンダリングし、その後、別のタイルリソースを使って同じタイルから読み取ることがあります。こうしたタイルリソースの操作は、1 つのリソースを使用して ID3D11RenderTargetView での書き込みから ID3D11ShaderResourceView での読み取りへ切り替えるだけの場合とは異なります。ID3D11RenderTargetView と ID3D11ShaderResourceView を使用する 1 つのリソースに対するこうした操作は、ランタイムが既に追跡して処理しています。
アプリが、あるリソースを通じてタイルプール内のある位置にアクセス (読み取りまたは書き込み) する状態から、同じメモリへのマッピングを持つ別のタイルリソースを通じて同じメモリにアクセス (読み取りまたは書き込み) する状態へ移行する場合、アプリは最初のリソースの使用後、2 番目の使用前に TiledResourceBarrier を呼び出す必要があります。パラメーターは、バリアより前のアクセス (レンダリングやコピーによる) に対する pTiledResourceOrViewAccessBeforeBarrier と、同じタイルプールのメモリを使用するバリアより後のアクセスに対する pTiledResourceOrViewAccessAfterBarrier です。リソースが同一である場合、この種のハザードは既に追跡・処理されているため、アプリが TiledResourceBarrier を呼び出す必要はありません。
バリアの呼び出しは、その呼び出しより前にリソースに対して発行された操作が、同じメモリを共有する別のタイルリソースを通じて呼び出し後に行われるアクセスより前に完了しなければならないことをドライバーに伝えます。
パラメーター (バリアの前または後) の一方または両方を NULL にできます。バリアより前が NULL の場合は、バリアより後に指定されたリソースをグラフィックスプロセッシングユニット (GPU) が参照できるようになる前に、バリアより前のすべてのタイルリソースへのアクセスが完了していなければならないことを意味します。バリアより後が NULL の場合は、バリアより後にアクセスされるすべてのタイルリソースが、バリアより前のタイルリソースへのアクセスが完了した後にのみ GPU で実行できることを意味します。両方が NULL の場合は、後続のタイルリソースへのアクセスが進行する前に、それ以前のすべてのタイルリソースへのアクセスが完了していることを意味します。
アプリは各パラメーターに、ビューへのポインター、リソース、または NULL を渡すことができます。ビューを指定できるのは利便性のためだけでなく、バリアの効果をリソースの関連する部分に限定できるようにするためでもあります。
タイルリソースの詳細については、「タイルリソース」を参照してください。
キャプチャ要求またはプロファイリング要求が有効になっているかどうかをアプリが判断できるようにします。
戻り値
キャプチャまたはプロファイリングが有効な場合は TRUE を、それ以外の場合は FALSE を返します。
解説(Remarks)
キャプチャツールが存在してキャプチャを実行している場合、またはアプリがプロファイリングされていて SetMarkerInt や BeginEventInt が ETW に記録される状態である場合は TRUE を返します。それ以外の場合は FALSE を返します。アプリはこれを利用して自己スロットリングの仕組みを無効にし、現在のアプリの出力を正確にキャプチャできます。また、イベントマーカーの生成に意味がない場合には、その生成とそれに伴うオーバーヘッドを避けることもできます。
アプリがキャプチャの実行を検出した場合、Microsoft Visual Studio 2013 などの Direct3D デバッグツールによるキャプチャを防止できます。Windows 8.1 より前における D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY フラグの目的は、Direct3D ランタイムがデバッグツールによるアプリのキャプチャを防止できるようにすることでした。
アプリケーションがグラフィックスコマンドに注釈を付けられるようにします。
| pLabel | LPWSTR | in | ETW ログが有効な場合に ETW に記録される、省略可能な文字列です。文字列内に ‘#d’ が含まれている場合、printf と同様に Data パラメーターの値に置き換えられます。 |
| Data | INT | in | ETW ログが有効な場合に ETW に記録される符号付きのデータ値です。 |
解説(Remarks)
SetMarkerInt を使用すると、アプリケーションはグラフィックスコマンドに注釈を付け、GPU が何を実行しているかについてより多くのコンテキストを提供できます。ETW ログまたはサポートツールが有効な場合、CPU と GPU のタイムライン間で対応付けられる追加のマーカーが記録されます。pLabel と Data の値が ETW に記録されます。該当する ETW ログが有効でない場合、このメソッドは何も行いません。
アプリケーションが一連のグラフィックスコマンドの開始位置に注釈を付けられるようにします。
| pLabel | LPWSTR | in | ETW ログが有効な場合に ETW に記録される、省略可能な文字列です。文字列内に ‘#d’ が含まれている場合、printf と同様に Data パラメーターの値に置き換えられます。 |
| Data | INT | in | ETW ログが有効な場合に ETW に記録される符号付きのデータ値です。 |
解説(Remarks)
BeginEventInt を使用すると、アプリケーションは一連のグラフィックスコマンドの開始位置に注釈を付け、GPU が何を実行しているかについてより多くのコンテキストを提供できます。ETW ログ (またはサポートされているツール) が有効な場合、CPU と GPU のタイムライン間で対応付けられる追加のマーカーが記録されます。pLabel と Data の値が ETW に記録されます。該当する ETW ログが有効でない場合、このメソッドは何も行いません。
アプリケーションが一連のグラフィックスコマンドの終了位置に注釈を付けられるようにします。
解説(Remarks)
EndEvent を使用すると、アプリケーションは一連のグラフィックスコマンドの終了位置に注釈を付け、GPU が何を実行しているかについてより多くのコンテキストを提供できます。該当する ETW ログが有効でない場合、このメソッドは何も行いません。ETW ログが有効な場合、CPU と GPU のタイムライン間で対応付けられる追加のマーカーが記録されます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_ID3D11DeviceContext2 "{420D5B32-B90C-4DA4-BEF0-359F6A24A83A}" #usecom global ID3D11DeviceContext2 IID_ID3D11DeviceContext2 "{}" #comfunc global ID3D11DeviceContext2_UpdateTileMappings 134 sptr,int,var,var,sptr,int,var,var,var,int #comfunc global ID3D11DeviceContext2_CopyTileMappings 135 sptr,var,sptr,var,var,int #comfunc global ID3D11DeviceContext2_CopyTiles 136 sptr,var,var,sptr,int64,int #comfunc global ID3D11DeviceContext2_UpdateTiles 137 sptr,var,var,sptr,int #comfunc global ID3D11DeviceContext2_ResizeTilePool 138 sptr,int64 #comfunc global ID3D11DeviceContext2_TiledResourceBarrier 139 sptr,sptr #comfunc global ID3D11DeviceContext2_IsAnnotationEnabled 140 #comfunc global ID3D11DeviceContext2_SetMarkerInt 141 wstr,int #comfunc global ID3D11DeviceContext2_BeginEventInt 142 wstr,int #comfunc global ID3D11DeviceContext2_EndEvent 143 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_ID3D11DeviceContext2 "{420D5B32-B90C-4DA4-BEF0-359F6A24A83A}" #usecom global ID3D11DeviceContext2 IID_ID3D11DeviceContext2 "{}" #comfunc global ID3D11DeviceContext2_UpdateTileMappings 134 sptr,int,sptr,sptr,sptr,int,sptr,sptr,sptr,int #comfunc global ID3D11DeviceContext2_CopyTileMappings 135 sptr,sptr,sptr,sptr,sptr,int #comfunc global ID3D11DeviceContext2_CopyTiles 136 sptr,sptr,sptr,sptr,int64,int #comfunc global ID3D11DeviceContext2_UpdateTiles 137 sptr,sptr,sptr,sptr,int #comfunc global ID3D11DeviceContext2_ResizeTilePool 138 sptr,int64 #comfunc global ID3D11DeviceContext2_TiledResourceBarrier 139 sptr,sptr #comfunc global ID3D11DeviceContext2_IsAnnotationEnabled 140 #comfunc global ID3D11DeviceContext2_SetMarkerInt 141 wstr,int #comfunc global ID3D11DeviceContext2_BeginEventInt 142 wstr,int #comfunc global ID3D11DeviceContext2_EndEvent 143 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。