Share via


タイルリソースが必要なのはなぜですか?

タイル化されたリソースが必要になるため、グラフィックス処理装置 (GPU) のメモリが少なくて済み、アプリケーションがアクセスできないことを認識しているサーフェスの領域を格納する必要がなくなり、ハードウェアは隣接するタイル全体でフィルター処理する方法を理解できます。

タイル リソースをサポートしていないグラフィックス システム (オペレーティング システム、ディスプレイ ドライバー、グラフィックス ハードウェア) では、グラフィックス システムはサブリソースの細分性ですべての Direct3D メモリ割り当てを管理します。 Buffer の場合、Buffer 全体がサブリソースです。 テクスチャ (Texture2D など) の場合、各ミップ レベルはサブリソースです。テクスチャ配列 (Texture2DArray など) の場合、特定の配列スライスの各 mip レベルはサブリソースです。 グラフィックス システムは、このサブリソースの詳細レベルで割り当てのマッピングを管理できることだけを公開します。 タイル化されたリソースのコンテキストでは、"マッピング" とは、GPU にデータを表示することを指します。

特定のレンダリング操作で、画像のミップマップ チェーンの一部 (特定のミップマップの全領域でもない) にのみアクセスする必要があることがアプリケーションにわかっているとします。 理想的には、アプリはこの必要性についてグラフィックス システムに通知できます。 そして、グラフィックス システムは、大量のメモリでページングせず、必要なメモリが GPU にマップされることだけを考えればよくなります。 実際には、タイル リソースのサポートがない場合、グラフィックス システムには、サブリソースの粒度で GPU にマップする必要があるメモリ (たとえば、アクセス可能な完全なミップマップ レベルの範囲) についてのみ通知できます。 グラフィックス システムにはデマンド フォールトがないため、潜在的にはメモリのいずれかの部分を参照するレンダリング コマンドが実行される前に、サブリソースの完全なマッピングを行うために余分な GPU メモリを大量に使用することが必要になる可能性があります。 これは、タイル リソースをサポートせずに Direct3D で大きなメモリ割り当てを使用するのが困難になる問題の 1 つに過ぎません。

Direct3D 11 は、特定の側に最大 16384 ピクセルの Texture2D サーフェスをサポートします。 幅 16384 × 高さ 16384、1 ピクセルあたり 4 バイトの画像は、1 GB のビデオ メモリを消費します (ミップマップを追加すると、その量の倍になります)。 実際には、1 つのレンダリング操作で 1 GB 全体の参照が必要になることはほとんどありません。

一部のゲーム開発者は、地形のサーフェスを 128 K × 128 K の大きさでモデル化します。 彼らがこれを既存の GPU で動作させる方法は、サーフェスをハードウェアが処理できる小さいタイルに分割することです。 アプリケーションは、どのタイルが必要になるかを調べて、それらを GPU でテクスチャのキャッシュに読み込む必要があります。これがソフトウェア ページング システムです。 このアプローチの大きな欠点は、実行中のページングについてハードウェアが何も知らないことです。タイルにまたがる画面に画像の一部を表示する必要がある場合、ハードウェアはタイル間で固定機能 (つまり効率的) のフィルター処理を実行する方法を知りません。 つまり、ソフトウェアのタイル処理を管理しているアプリケーションが、シェーダー コードでテクスチャのフィルター処理を手動で行うか (これは、高品質の異方性フィルターが必要な場合に非常に高価になります)、固定関数によるハードウェア フィルター処理が補助し続けられるように、メモリを浪費して隣接するタイルのデータを格納するガターをタイルの周囲に作成する必要があります。

サーフェス割り当てのタイル化された表現がグラフィックス システムのファースト クラスの機能である可能性がある場合、アプリケーションは使用可能にするタイルをハードウェアに指示できます。 この方法で、アクセスされないことがアプリケーションにわかっているサーフェイスの領域を保存するために浪費する GPU メモリが少なくなり、ハードウェアは隣接するタイルにわたってフィルター処理する方法を理解でき、ソフトウェアのタイル処理を実行している開発者が経験する問題点の一部が軽減されます。

しかし、完全なソリューションを提供するには、サーフェス内のタイル処理がサポートされるかどうかに関係なく、サーフェスの現在の最大サイズは既にアプリケーションが必要としている 128 K 以上にはほど遠い 16384 であることに対応するために何かをする必要があります。 ハードウェアにより大きいテクスチャ サイズをサポートするように求めることも 1 つの方法ですが、その方向に進むことには大きなコスト増やトレードオフがあります。 Direct3D 11 のテクスチャ フィルター パスとレンダリング パスは、16K テクスチャを他の要件でサポートする精度の点で既に飽和しています。たとえば、レンダリング中にサーフェスから落ちるビューポートの範囲をサポートしたり、フィルター処理中にサーフェスエッジをラップするテクスチャをサポートしたりします。 可能な方法は、テクスチャ サイズが 16K を超えて増えるにつれて、機能/精度をある程度落とすようにトレードオフを定義することです。 ただし、ここで譲歩しても、より大きいテクスチャ サイズに移行できるようにハードウェア システム全体にわたる能力を増強するためには、追加のハードウェア コストが必要になることがあります。

テクスチャが非常に大きくなるにつれて出てくる問題の 1 つは、単精度浮動小数点のテクスチャ座標 (およびラスター化をサポートするための関連する補間操作) では、サーフェス上の位置を正確に指定する精度が足りなくなることです。 テクスチャのフィルター処理が不安定になります。 高価なオプションの 1 つは倍精度の補間操作のサポートを求めることですが、妥当な代替案としては過剰になる可能性があります。

タイル化されたリソースの代替名は、"スパース テクスチャ" です。"スパース" は、リソースのタイル化された性質と、それらを並べて表示する主な理由の両方を伝えます。すべてのリソースが一度にマップされるとは限りません。 実際、アプリケーションは、リソースのすべてのリージョンと mips に対してデータが意図的に作成されないタイル リソースを作成する可能性があります。 そのため、コンテンツ自体はスパースである可能性があり、特定の時点での GPU メモリ内のコンテンツのマッピングは、そのサブセットになります (さらにスパース)。

タイル化されたリソースで処理できるもう 1 つのシナリオは、異なるディメンション/形式の複数のリソースが同じメモリを共有できるようにすることです。 アプリケーションで、同時に使用しないことがわかっている排他的なリソースのセットや、非常に短時間だけ使用するために作成されて破棄されるリソース (その後に他のリソースが作成される) を処理することがあります。 "タイル化されたリソース" から除外される可能性がある一般的な形式は、ユーザーが複数の異なるリソースを同じ (重複する) メモリでポイントできるようにすることです。 つまり、"リソース" の作成と破棄 (サイズ/形式を定義するなど) は、アプリケーションの視点からリソースの基になるメモリの管理から切り離すことができます。

タイル化されたリソース