タイル プールへのマッピング
D3D11_RESOURCE_MISC_TILED フラグを使用してリソースを作成すると、リソースを構成するタイルはタイル プール内の場所を指すようになります。 タイル プールはメモリのプールです (バックグラウンドで 1 つ以上の割り当てによってサポートされ、アプリケーションでは見えなくなります)。 オペレーティング システムとディスプレイ ドライバーは、メモリのこのプールを管理し、メモリのフットプリントは、アプリケーションによって簡単に理解されます。 タイル化されたリソースは、タイル プール内の場所をポイントすることで、64 KB のリージョンをマップします。 このセットアップの 1 つのフォールアウトは、複数のリソースが同じタイルを共有して再利用し、必要に応じてリソース内の異なる場所で同じタイルを再利用できる点です。
タイル プールからリソースのタイルを柔軟に設定するためのコストは、タイル プール内のどのタイルがリソースに必要なタイルを表すかのマッピングを定義および維持する作業をリソースが行う必要があるということです。 タイル マッピングは変更できます。 また、リソース内のすべてのタイルを一度にマップする必要はありません。リソースは、NULL マッピングを持つことができます。 NULL マッピングでは、タイルはアクセスするリソースの観点からは使用できないと定義されます。
複数のタイル プールを作成でき、任意の数のタイル リソースを任意のタイル プールに同時にマップできます。 タイル プールは、拡大または縮小することもできます。 詳細については、「タイル プールのサイズ変更 」を参照してください。 ディスプレイ ドライバーとランタイムの実装を簡略化するために存在する制約の 1 つは、(複数のタイル プールへの同時マッピングではなく) 特定のタイル リソースが一度に最大 1 つのタイル プールへのマッピングのみを持つことです。
タイル リソース自体 (つまり、独立したタイル プール メモリ) に関連付けられているストレージの量は、特定の時点でプールに実際にマップされるタイルの数とほぼ比例します。 ハードウェアでは、この事実は、マップされるタイルの量 (たとえば、必要に応じてマルチレベル ページ テーブル スキームを使用するなど) でページ テーブル ストレージのメモリ占有領域を大まかにスケーリングするために沸騰します。
タイル プールは、Direct3D アプリケーションが低レベルの実装の詳細を知らなくても (またはポインター アドレスを直接処理する) ことなく、グラフィックス処理装置 (GPU) 上のページ テーブルを効果的にプログラミングできるようにする完全なソフトウェア抽象化と考えることができます。 タイル プールでは、ハードウェアに追加レベルの間接参照は適用されません。 ページ ディレクトリなどのコンストラクトを使用した単一レベルのページ テーブルの最適化は、タイル プールの概念とは無関係です。
最悪の場合、ページ テーブル自体が必要とするストレージを調べてみましょう (ただし、実際の実装では、マップされているものとほぼ比例したストレージのみが必要です)。
各ページ テーブルエントリが 64 ビットであるとします。
Direct3D 11 のリソース制限を考えると、1 つのサーフェスに対する最悪のケースのページ テーブル サイズヒットの場合、タイル化されたリソースが要素ごとに 128 ビット形式 (RGBA float など) で作成されるため、64 KB タイルには 4096 ピクセルのみが含まれているとします。 サポートされている最大 Texture2DArray サイズは 16384*16384*2048 です (ただし、ミップマップは 1 つだけです)。 ミップマップを追加すると、完全にマップされた (最悪の場合) ページ テーブル ストレージが約 3 分の 1、約 1.3 GB に拡張されます。
この場合、約 10.6 テラバイトのアドレス指定可能なメモリにアクセスできます。 ただし、アドレス指定可能なメモリの量には制限がある可能性があります。これにより、これらの量が減り、おそらくテラバイトの範囲を超える可能性があります。
考慮すべきもう 1 つのケースは、1 つの Texture2D 16384*16384 のタイル リソースで、ミップマップを含む 32 ビット/要素形式です。 完全に設定されたページ テーブルに必要な領域は、64 ビット テーブル エントリで約 170 KB になります。
最後に、BC 形式 (たとえば、4 x 4 ピクセルのタイルあたり 128 ビットの BC7) を使用する例を考えてみましょう。 これはピクセルあたり 1 バイトです。 ミップマップを含む 16384*16384*2048 の Texture2DArray では、ページ テーブルにこのメモリを完全に設定するには約 85 MB が必要です。 これは、タイル化された 1 つのリソースが 550 ギガピクセル (この場合は 512 GB のメモリ) にまたがることを考えると悪いわけではありません。
実際には、使用可能な物理メモリの量によって、その近くの場所で一度にマップおよび参照できないことを考えると、これらの完全なマッピングに近い場所は定義されません。 ただし、タイル プールを使用すると、アプリケーションはタイルを再利用することを選択できます (単純な例として、イメージ内の大きな黒い領域に対して "黒" 色のタイルを再利用します)。タイル プール (つまり、ページ テーブル マッピング) をメモリ圧縮のツールとして効果的に使用できます。
ページ テーブルの初期コンテンツは、すべてのエントリに対して NULL されます。 また、メモリ バッキングなしで起動するため、アプリケーションはサーフェスのメモリコンテンツの初期データを渡すことができません。
このセクションでは、次の操作を行います。
話題 | 形容 |
---|---|
タイル プールの作成 |
タイル プールは、pDesc パラメーターが指す D3D11_BUFFER_DESC 構造体の MiscFlags メンバーに D3D11_RESOURCE_MISC_TILE_POOL フラグを渡すことによって、ID3D11Device::CreateBuffer API を使用して作成されます。 |
タイル プールのサイズ変更 |
ID3D11DeviceContext2::ResizeTilePool API を使用して、タイル プールにマップするタイル リソースのワーキング セットがアプリケーションに必要な場合は、タイル プールを拡張するか、必要な領域が少ない場合は縮小します。 |
ハザード追跡とタイル プール リソースの |
タイル化されていないリソースの場合、Direct3D はレンダリング中に特定の危険状態を防ぐことができますが、タイル化されたリソースのタイル レベルでハザード追跡が行われるため、タイル化されたリソースのレンダリング中に危険状況を追跡するとコストが高すぎる可能性があります。 |
関連トピック
-
タイル リソース の作成