Win32 API 日本語リファレンス
ホームGraphics.Direct3D11 › ID3D11DeviceContext2

ID3D11DeviceContext2

COM
IID420d5b32-b90c-4da4-bef0-359f6a24a83a継承元ID3D11DeviceContext1自前メソッド開始 vtbl134

公式ドキュメント

デバイスコンテキストインターフェイスはデバイスコンテキストを表し、レンダリングコマンドの発行に使用します。ID3D11DeviceContext2 は ID3D11DeviceContext1 のメソッドに新しいメソッドを追加します。

メソッド 10

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 134 HRESULT UpdateTileMappings(ID3D11Resource* pTiledResource, DWORD NumTiledResourceRegions, D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates, D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes, ID3D11Buffer* pTilePool, DWORD NumRanges, DWORD* pRangeFlags, DWORD* pTilePoolStartOffsets, DWORD* pRangeTileCounts, DWORD Flags)

タイルリソース内のタイル位置と、タイルプール内のメモリ位置とのマッピングを更新します。

pTiledResourceID3D11Resource*inタイルリソースへのポインターです。
NumTiledResourceRegionsDWORDinタイルリソース領域の数です。
pTiledResourceRegionStartCoordinatesD3D11_TILED_RESOURCE_COORDINATE*inoptionalタイルリソース領域の開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体の配列です。配列内の D3D11_TILED_RESOURCE_COORDINATE 構造体の数は、NumTiledResourceRegions パラメーターで指定します。
pTiledResourceRegionSizesD3D11_TILE_REGION_SIZE*inoptionalタイルリソース領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体の配列です。配列内の D3D11_TILE_REGION_SIZE 構造体の数は、NumTiledResourceRegions パラメーターで指定します。
pTilePoolID3D11Buffer*inoptionalタイルプールへのポインターです。
NumRangesDWORDinタイルプール範囲の数です。
pRangeFlagsDWORD*inoptional各タイルプール範囲を記述する D3D11_TILE_RANGE_FLAG 値の配列です。配列内の値の数は、NumRanges パラメーターで指定します。
pTilePoolStartOffsetsDWORD*inoptionalタイルプール内へのオフセットの配列です。これらは 0 から始まるタイルオフセットで、バイト単位ではなくタイル単位で数えます。
pRangeTileCountsDWORD*inoptional

タイルの配列です。

各タイルプール範囲内のタイル数を指定する値の配列です。配列内の値の数は、NumRanges パラメーターで指定します。

FlagsDWORDinビット単位の OR 演算で組み合わせた D3D11_TILE_MAPPING_FLAGS 値の組み合わせです。

戻り値

型: HRESULT

成功した場合は S_OK を返します。それ以外の場合は、次のいずれかを返します。

解説(Remarks)

UpdateTileMappings の 1 回の呼び出しで、1 つ以上のリソースタイルの範囲を、1 つ以上のタイルプールタイルの範囲にマップできます。

更新を実行するには、UpdateTileMappings のパラメーターを次のように構成します。

アプリが RenderTargetView または DepthStencilView を通じてレンダリングするタイルリソースのタイルマッピングが変更された場合、アプリはレンダリング対象領域内で変更されたタイル (マップされているかどうかを問わず) を、固定機能の Clear API を使用してクリアする必要があります。こうした状況でクリアを行わないと、アプリがそのタイルリソースから読み取ったときに未定義の値が返されます。
メモ Direct3D 11.2 では、ハードウェアが深度のみのフォーマットに対する ClearView をサポートできるようになりました。詳細については、D3D11_FEATURE_DATA_D3D11_OPTIONS1 を参照してください。
マッピングが変更されたタイルリソース内の領域について、既存のメモリ内容を保持する必要がある場合、アプリはタイルマッピングが変更される箇所の内容を、たとえば CopyTiles を使用して一時的なサーフェスにコピーして保存し、必要な Clear を発行してから、内容を書き戻すことができます。

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 で破棄されます。
// 
// 検証に関する注意:
//
// コピー先とコピー元の領域は、それぞれのリソース内に完全に収まっている必要があります。そうでない場合の動作は未定義です
// (デバッグレイヤーがエラーを出力します)。
vtbl 135 HRESULT CopyTileMappings(ID3D11Resource* pDestTiledResource, D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate, ID3D11Resource* pSourceTiledResource, D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate, D3D11_TILE_REGION_SIZE* pTileRegionSize, DWORD Flags)

コピー元のタイルリソースからコピー先のタイルリソースへ、マッピングをコピーします。

pDestTiledResourceID3D11Resource*inコピー先のタイルリソースへのポインターです。
pDestRegionStartCoordinateD3D11_TILED_RESOURCE_COORDINATE*inコピー先のタイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。
pSourceTiledResourceID3D11Resource*inコピー元のタイルリソースへのポインターです。
pSourceRegionStartCoordinateD3D11_TILED_RESOURCE_COORDINATE*inコピー元のタイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。
pTileRegionSizeD3D11_TILE_REGION_SIZE*inタイル領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体へのポインターです。
FlagsDWORDinビット単位の OR 演算で組み合わせた D3D11_TILE_MAPPING_FLAGS 値の組み合わせです。有効な値は D3D11_TILE_MAPPING_NO_OVERWRITE のみで、これはまだ実行中の可能性があるデバイスへの送信済みコマンドが、更新対象のタイル領域を一切参照していないことを示します。これにより、デバイスはタイルマッピングの更新のために送信済みの処理をフラッシュする必要がなくなります。未処理のコマンドがまだ参照しているタイルリソースの位置についてタイルマッピングを更新してこの保証に違反すると、レンダリング動作は未定義となり、一部のアーキテクチャでは大幅な速度低下を招く可能性があります。これは Direct3D API の他の場所に存在する「no overwrite」の概念と同様ですが、タイルマッピングのデータ構造そのもの (ハードウェア上ではページテーブル) に適用される点が異なります。D3D11_TILE_MAPPING_NO_OVERWRITE 値を指定しない場合、CopyTileMappings が指定するタイルマッピングの更新は、後続の Direct3D コマンドが進行する前に完了している必要があります。

戻り値

型: HRESULT

成功した場合は S_OK を返します。それ以外の場合は、次のいずれかを返します。

解説(Remarks)

CopyTileMappings は、タイルリソース内またはタイルリソース間でマッピングをずらす (たとえばタイルのスクロール) といった作業に役立ちます。コピー元とコピー先の領域は重なり合っても構いません。この場合のコピー結果は、コピー元をいったん一時的な場所に保存し、そこからコピー先へ書き込んだ場合と同じになります。

タイルリソースの詳細については、「タイルリソース」を参照してください。

vtbl 136 void CopyTiles(ID3D11Resource* pTiledResource, D3D11_TILED_RESOURCE_COORDINATE* pTileRegionStartCoordinate, D3D11_TILE_REGION_SIZE* pTileRegionSize, ID3D11Buffer* pBuffer, ULONGLONG BufferStartOffsetInBytes, DWORD Flags)

バッファーからタイルリソースへ、またはその逆方向にタイルをコピーします。(ID3D11DeviceContext2.CopyTiles)

pTiledResourceID3D11Resource*inタイルリソースへのポインターです。
pTileRegionStartCoordinateD3D11_TILED_RESOURCE_COORDINATE*inタイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。
pTileRegionSizeD3D11_TILE_REGION_SIZE*inタイル領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体へのポインターです。
pBufferID3D11Buffer*inデフォルト、ダイナミック、またはステージングのバッファーを表す ID3D11Buffer へのポインターです。
BufferStartOffsetInBytesULONGLONGin操作を開始する、pBuffer のバッファー内へのバイト単位のオフセットです。
FlagsDWORDinビット単位の OR 演算で組み合わせた D3D11_TILE_COPY_FLAG 型の値の組み合わせで、タイルをどのようにコピーするかを指定します。

解説(Remarks)

CopyTiles は、マップされていない領域への書き込み操作を破棄し、マップされていない領域からの読み取り操作を処理します (Tier_1 のタイルリソースを除きます。Tier_1 では、マップされていない領域の読み取りと書き込みは無効です)。

コピー先リソース内の複数の位置が同じタイルメモリにマップされているために、同じメモリ位置への書き込みが複数回発生するコピー操作では、多重マップされたタイルへの書き込み結果は非決定的かつ再現性がありません。つまり、タイルメモリへのアクセスは、ハードウェアがコピー操作を実行する順序に依存します。

コピー操作の対象となるタイルには、パックされたミップマップを含むタイルを含めることはできません。含めた場合、コピー操作の結果は未定義になります。パックされたミップを構成する 1 つ以上のタイルにハードウェアがパックするミップマップとの間でデータを転送するには、標準の (つまりタイル固有ではない) コピーおよび更新 API (ID3D11DeviceContext1::CopySubresourceRegion1ID3D11DeviceContext1::UpdateSubresource1 など) を使用するか、ミップマップチェーン全体に対して ID3D11DeviceContext::GenerateMips を使用する必要があります。

コピー操作のうちタイルリソースでないバッファーリソース側におけるタイルのメモリレイアウトは、64 KB のタイル内で線形になっており、タイルリソースとの間で転送する際に、ハードウェアとドライバーがタイルごとに適宜スウィズル/デスウィズルを行います。マルチサンプルアンチエイリアシング (MSAA) のサーフェスでは、ハードウェアとドライバーは各ピクセルのサンプルをサンプルインデックス順にたどってから次のピクセルへ移ります。右側が部分的にしか埋まっていないタイル (幅がタイル幅のピクセル数の倍数でないサーフェスの場合) では、次の行へ移るためのピッチとストライドは、タイルが完全に埋まっていた場合にタイル幅に収まるピクセル数分のバイト単位のサイズ全体になります。したがって、メモリ内のピクセルの行と行の間にすき間ができることがあります。タイルより小さいミップマップは線形レイアウト内でまとめてパックされないため、メモリ空間の無駄に見えるかもしれませんが、前述のとおり、ハードウェアがまとめてパックするミップマップへのコピーには CopyTilesID3D11DeviceContext2::UpdateTiles を使用できません。小さなミップマップを個別にコピーするには、汎用のコピーおよび更新 API (ID3D11DeviceContext1::CopySubresourceRegion1ID3D11DeviceContext1::UpdateSubresource1 など) を使用すればよいだけです。ただし、汎用のコピー API (ID3D11DeviceContext1::CopySubresourceRegion1 など) の場合、線形メモリはタイルリソースと同じ次元でなければなりません。たとえば ID3D11DeviceContext1::CopySubresourceRegion1 は、バッファーリソースから Texture2D へコピーすることはできません。

タイルリソースの詳細については、「タイルリソース」を参照してください。

vtbl 137 void UpdateTiles(ID3D11Resource* pDestTiledResource, D3D11_TILED_RESOURCE_COORDINATE* pDestTileRegionStartCoordinate, D3D11_TILE_REGION_SIZE* pDestTileRegionSize, void* pSourceTileData, DWORD Flags)

アプリのメモリからタイルリソースへコピーすることで、タイルを更新します。

pDestTiledResourceID3D11Resource*in更新するタイルリソースへのポインターです。
pDestTileRegionStartCoordinateD3D11_TILED_RESOURCE_COORDINATE*inタイルリソースの開始座標を記述する D3D11_TILED_RESOURCE_COORDINATE 構造体へのポインターです。
pDestTileRegionSizeD3D11_TILE_REGION_SIZE*inタイル領域のサイズを記述する D3D11_TILE_REGION_SIZE 構造体へのポインターです。
pSourceTileDatavoid*inUpdateTiles がタイルリソースの更新に使用する、コピー元のタイルデータが格納されたメモリへのポインターです。
FlagsDWORDinビット単位の 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::CopySubresourceRegion1ID3D11DeviceContext1::UpdateSubresource1 など) を使用するか、ミップマップチェーン全体に対して ID3D11DeviceContext::GenerateMips を使用する必要があります。

コピー操作のコピー元側におけるデータのメモリレイアウトは、64 KB のタイル内で線形になっており、タイルリソースとの間で転送する際に、ハードウェアとドライバーがタイルごとに適宜スウィズル/デスウィズルを行います。マルチサンプルアンチエイリアシング (MSAA) のサーフェスでは、ハードウェアとドライバーは各ピクセルのサンプルをサンプルインデックス順にたどってから次のピクセルへ移ります。右側が部分的にしか埋まっていないタイル (幅がタイル幅のピクセル数の倍数でないサーフェスの場合) では、次の行へ移るためのピッチとストライドは、タイルが完全に埋まっていた場合にタイル幅に収まるピクセル数分のバイト単位のサイズ全体になります。したがって、メモリ内のピクセルの行と行の間にすき間ができることがあります。タイルより小さいミップマップは線形レイアウト内でまとめてパックされないため、メモリ空間の無駄に見えるかもしれませんが、前述のとおり、ハードウェアがまとめてパックするミップマップへのコピーには ID3D11DeviceContext2::CopyTilesUpdateTiles を使用できません。小さなミップマップを個別にコピーするには、汎用のコピーおよび更新 API (ID3D11DeviceContext1::CopySubresourceRegion1ID3D11DeviceContext1::UpdateSubresource1 など) を使用すればよいだけです。ただし、汎用のコピー API (ID3D11DeviceContext1::CopySubresourceRegion1 など) の場合、線形メモリはタイルリソースと同じ次元でなければなりません。たとえば ID3D11DeviceContext1::CopySubresourceRegion1 は、バッファーリソースから Texture2D へコピーすることはできません。

タイルリソースの詳細については、「タイルリソース」を参照してください。

vtbl 138 HRESULT ResizeTilePool(ID3D11Buffer* pTilePool, ULONGLONG NewSizeInBytes)

タイルプールのサイズを変更します。

pTilePoolID3D11Buffer*inサイズを変更するタイルプールの ID3D11Buffer へのポインターです。
NewSizeInBytesULONGLONGinタイルプールの新しいサイズ (バイト単位) です。サイズは 64 KB の倍数または 0 でなければなりません。

戻り値

型: HRESULT

成功した場合は S_OK を返します。それ以外の場合は、次のいずれかを返します。

E_INVALIDARG または E_OUTOFMEMORY の場合、既存のタイルプールは既存のマッピングを含めて変更されません。

解説(Remarks)

ResizeTilePool は、タイルプールにマップされているタイルリソースに対してアプリがより多くの、あるいはより少ないワーキングセットを必要とするかに応じて、タイルプールのサイズを増減します。アプリは新しいタイルリソース用に追加のタイルプールを割り当てることもできますが、単一のタイルリソースがそのタイルプール内で当初利用可能な容量を超える領域を必要とする場合、アプリはそのリソースのタイルプールのサイズを増やすことができます。1 つのタイルリソースが同時に複数のタイルプールへマッピングを持つことはできません。

タイルプールのサイズを増やすと、ドライバーによる 1 つ以上の新しい割り当てを通じて、タイルプールの末尾に追加のタイルが加えられます。アプリが新しい割り当ての内訳を知ることはできません。タイルプール内の既存のメモリはそのまま保たれ、そのメモリへの既存のタイルリソースのマッピングも維持されます。

タイルプールのサイズを減らすと、末尾からタイルが取り除かれます (当初の割り当てサイズを下回り、0 まで減らすことも可能です)。つまり、新しいサイズを超える位置には新しいマッピングを作成できなくなります。ただし、新しいサイズの末尾を超える既存のマッピングはそのまま維持され、使用可能です。タイルプールのメモリとして使用されている割り当ての一部にマッピングが残っている限り、そのメモリはアクティブなまま保持されます。サイズを減らした後、タイルマッピングがそこを指しているためにメモリの一部がアクティブなまま保持されている状態でタイルプールのサイズを再び (どれだけであれ) 増やした場合、増加分に対応するための追加の割り当てが行われる前に、まず既存のメモリが再利用されます。

メモリを節約するには、アプリはタイルプールのサイズを減らすだけでなく、新しい小さなタイルプールサイズの末尾を超える既存のマッピングを削除し、マップし直す必要があります。

サイズを減らして (マッピングを削除して) も、必ずしも即座にメモリが節約されるわけではありません。メモリが解放されるかどうかは、タイルプールに対するドライバー内部の割り当ての粒度に依存します。タイルプールのサイズ減少がドライバーの割り当てを未使用にするのに十分であれば、ドライバーはその割り当てを解放できます。タイルプールのサイズを増やした後、以前のサイズまで減らした場合 (かつ、それに応じてタイルマッピングを削除して再マップした場合)、多くの場合メモリが節約されます。ただし、サイズがドライバーの選択した内部の割り当てサイズと正確に一致しない場合、これは保証されません。

タイルリソースの詳細については、「タイルリソース」を参照してください。

vtbl 139 void TiledResourceBarrier(ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier)

複数のタイルリソース間のデータアクセス順序の制約を指定します。

pTiledResourceOrViewAccessBeforeBarrierID3D11DeviceChild*inoptionalD3D11_RESOURCE_MISC_TILED フラグを指定して作成されたリソースの ID3D11Resource または ID3D11View へのポインターです。このオブジェクトに対するアクセス操作は、pTiledResourceOrViewAccessAfterBarrier で指定されるオブジェクトに対するアクセス操作より前に完了している必要があります。
pTiledResourceOrViewAccessAfterBarrierID3D11DeviceChild*inoptionalD3D11_RESOURCE_MISC_TILED フラグを指定して作成されたリソースの ID3D11Resource または ID3D11View へのポインターです。このオブジェクトに対するアクセス操作は、pTiledResourceOrViewAccessBeforeBarrier で指定されるオブジェクトに対するアクセス操作より後に開始される必要があります。

解説(Remarks)

アプリはタイルリソースを使用して、異なるリソース間でタイルを再利用できます。しかし、デバイスやドライバーは、レンダリング直後のタイルプール内のメモリが読み取りに使用されているかどうかを判断できない場合があります。

たとえば、アプリがあるタイルリソースを使ってタイルプール内の一部のタイルにレンダリングし、その後、別のタイルリソースを使って同じタイルから読み取ることがあります。こうしたタイルリソースの操作は、1 つのリソースを使用して ID3D11RenderTargetView での書き込みから ID3D11ShaderResourceView での読み取りへ切り替えるだけの場合とは異なります。ID3D11RenderTargetViewID3D11ShaderResourceView を使用する 1 つのリソースに対するこうした操作は、ランタイムが既に追跡して処理しています。

アプリが、あるリソースを通じてタイルプール内のある位置にアクセス (読み取りまたは書き込み) する状態から、同じメモリへのマッピングを持つ別のタイルリソースを通じて同じメモリにアクセス (読み取りまたは書き込み) する状態へ移行する場合、アプリは最初のリソースの使用後、2 番目の使用前に TiledResourceBarrier を呼び出す必要があります。パラメーターは、バリアより前のアクセス (レンダリングやコピーによる) に対する pTiledResourceOrViewAccessBeforeBarrier と、同じタイルプールのメモリを使用するバリアより後のアクセスに対する pTiledResourceOrViewAccessAfterBarrier です。リソースが同一である場合、この種のハザードは既に追跡・処理されているため、アプリが TiledResourceBarrier を呼び出す必要はありません。

バリアの呼び出しは、その呼び出しより前にリソースに対して発行された操作が、同じメモリを共有する別のタイルリソースを通じて呼び出し後に行われるアクセスより前に完了しなければならないことをドライバーに伝えます。

パラメーター (バリアの前または後) の一方または両方を NULL にできます。バリアより前が NULL の場合は、バリアより後に指定されたリソースをグラフィックスプロセッシングユニット (GPU) が参照できるようになる前に、バリアより前のすべてのタイルリソースへのアクセスが完了していなければならないことを意味します。バリアより後が NULL の場合は、バリアより後にアクセスされるすべてのタイルリソースが、バリアより前のタイルリソースへのアクセスが完了した後にのみ GPU で実行できることを意味します。両方が NULL の場合は、後続のタイルリソースへのアクセスが進行する前に、それ以前のすべてのタイルリソースへのアクセスが完了していることを意味します。

アプリは各パラメーターに、ビューへのポインター、リソース、または NULL を渡すことができます。ビューを指定できるのは利便性のためだけでなく、バリアの効果をリソースの関連する部分に限定できるようにするためでもあります。

タイルリソースの詳細については、「タイルリソース」を参照してください。

vtbl 140 BOOL IsAnnotationEnabled()

キャプチャ要求またはプロファイリング要求が有効になっているかどうかをアプリが判断できるようにします。

戻り値

キャプチャまたはプロファイリングが有効な場合は TRUE を、それ以外の場合は FALSE を返します。

解説(Remarks)

キャプチャツールが存在してキャプチャを実行している場合、またはアプリがプロファイリングされていて SetMarkerIntBeginEventIntETW に記録される状態である場合は TRUE を返します。それ以外の場合は FALSE を返します。アプリはこれを利用して自己スロットリングの仕組みを無効にし、現在のアプリの出力を正確にキャプチャできます。また、イベントマーカーの生成に意味がない場合には、その生成とそれに伴うオーバーヘッドを避けることもできます。

アプリがキャプチャの実行を検出した場合、Microsoft Visual Studio 2013 などの Direct3D デバッグツールによるキャプチャを防止できます。Windows 8.1 より前における D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY フラグの目的は、Direct3D ランタイムがデバッグツールによるアプリのキャプチャを防止できるようにすることでした。

vtbl 141 void SetMarkerInt(LPWSTR pLabel, INT Data)

アプリケーションがグラフィックスコマンドに注釈を付けられるようにします。

pLabelLPWSTRinETW ログが有効な場合に ETW に記録される、省略可能な文字列です。文字列内に ‘#d’ が含まれている場合、printf と同様に Data パラメーターの値に置き換えられます。
DataINTinETW ログが有効な場合に ETW に記録される符号付きのデータ値です。

解説(Remarks)

SetMarkerInt を使用すると、アプリケーションはグラフィックスコマンドに注釈を付け、GPU が何を実行しているかについてより多くのコンテキストを提供できます。ETW ログまたはサポートツールが有効な場合、CPU と GPU のタイムライン間で対応付けられる追加のマーカーが記録されます。pLabelData の値が ETW に記録されます。該当する ETW ログが有効でない場合、このメソッドは何も行いません。

vtbl 142 void BeginEventInt(LPWSTR pLabel, INT Data)

アプリケーションが一連のグラフィックスコマンドの開始位置に注釈を付けられるようにします。

pLabelLPWSTRinETW ログが有効な場合に ETW に記録される、省略可能な文字列です。文字列内に ‘#d’ が含まれている場合、printf と同様に Data パラメーターの値に置き換えられます。
DataINTinETW ログが有効な場合に ETW に記録される符号付きのデータ値です。

解説(Remarks)

BeginEventInt を使用すると、アプリケーションは一連のグラフィックスコマンドの開始位置に注釈を付け、GPU が何を実行しているかについてより多くのコンテキストを提供できます。ETW ログ (またはサポートされているツール) が有効な場合、CPU と GPU のタイムライン間で対応付けられる追加のマーカーが記録されます。pLabelData の値が ETW に記録されます。該当する ETW ログが有効でない場合、このメソッドは何も行いません。

vtbl 143 void EndEvent()

アプリケーションが一連のグラフィックスコマンドの終了位置に注釈を付けられるようにします。

解説(Remarks)

EndEvent を使用すると、アプリケーションは一連のグラフィックスコマンドの終了位置に注釈を付け、GPU が何を実行しているかについてより多くのコンテキストを提供できます。該当する ETW ログが有効でない場合、このメソッドは何も行いません。ETW ログが有効な場合、CPU と GPU のタイムライン間で対応付けられる追加のマーカーが記録されます。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
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 指定が可能。