ストリーミング リソース テクスチャ サンプリング機能

ストリーミング リソース テクスチャ サンプリングの機能は複数あります。たとえば、マップの領域についてシェーダー状態のフィードバックを取得する機能、アクセスされている全データがリソース内にマップされたかどうか確認する機能、マップされていないことがわかっているミップマップ ストリーミング リソース内の領域をシェーダーが避けられるようにクランプする機能、テクスチャ フィルターのフットプリント全体に完全にマップされる最小の LOD を検出する機能などがあります。

ストリーミング リソース テクスチャ サンプリング機能の要件

ここで説明するテクスチャ サンプリング機能には、階層 2 レベルのストリーミング リソース サポートが必要です。

マップ領域についてのシェーダー状態のフィードバック

ストリーミング リソースの読み取りや書き込みをするシェーダー命令が発生すると、状態情報が記録されます。 この状態は、リソース アクセス命令が発生するたびに、省略可能な追加の戻り値として公開され、32 ビットの一時レジスタに保存されます。 この戻り値の内容は "不透明" です。 つまり、シェーダー プログラムによる直接の読み取りは認められていません。 ただし、CheckAccessFullyMapped 関数を使用して、状態情報を抽出できます。

完全なマップのチェック

CheckAccessFullyMapped 関数は、メモリ アクセスから返された状態を解釈し、アクセスされるすべてのデータがリソースにマップされていたかどうかを示します。 CheckAccessFullyMapped は、データがマップされている場合は true (0xFFFFFFFF) を、マップされていない場合は false (0x00000000) を返します。

フィルター操作中に、特定のテクセルの重み付けが 0.0 になることがあります。 例としては、テクセルの中央に直接置かれるテクスチャ座標を持つリニア サンプルです。3 つのその他のテクセル (どれが該当するかは、ハードウェアによって決まります) は、フィルターでは考慮されますが、重みは 0 です。 このような重みが 0 であるテクセルはフィルター結果にはまったく影響しないため、このようなテクセルが偶然 NULL タイルに適用された場合、マップされていないアクセスとしてカウントされません。 複数の mip レベルを含むテクスチャ フィルターにも、同じことが言えます。ミップマップの 1 つに適用されたテクセルがマップされていなくて、そのようなテクセルの重みが 0 の場合、それらのテクセルはマップされていないアクセスとしてカウントされません。

コンポーネント数が 4 個未満の形式 (DXGI_FORMAT_R8_UNORM など) からサンプリングをする場合、結果のどのコンポーネントをシェーダーが実際に参照するかは問わず、NULL タイルに適用されるテクセルは、NULL マップ アクセスとしてレポートされます。 たとえば、シェーダーで R8_UNORM から読み取りを行い、.gba/.yzw を使用して読み取り結果をマスクした場合、テクスチャの読み取りはまったく必要ないような結果になります。 ただし、テクセル アドレスが NULL マップ タイルの場合、操作はやはり NULL マップ アクセスとしてカウントされます。

シェーダーは状態を確認し、エラーが発生している場合は一連の対応策を実行できます。 たとえば、一連の対応策としては 'ミス' をログに記録すること (UAV 書き込みなど) であったり、より詳細度の低い、マップされていることがわかっている LOD にクランプした別の読み取りを発行することが該当します。 タイルのマップ済みセットのどの部分がアクセスされたかを把握するため、成功したアクセスもアプリケーションで追跡したい場合があります。

ログで 1 つ厄介なのは、アクセスされたと思われる一連のタイルを正確にレポートできるメカニズムが存在しないことです。 アプリケーションは、アクセスに使用した座標の知識を基に控えめに推測を行うことも、LOD 命令を使用することもできます。たとえば、tex2Dlod はハードウェア LOD の計算を返します。

また、同じタイルに対して大量のアクセスが発生するため、冗長なログも大量に発生し、メモリで競合が起きる可能性があります。 タイルのアクセスについて別の場所で既にレポートされている場合は、レポートを不要にするオプションがハードウェアに用意されると便利である可能性があります。 おそらく、そのような追跡の状態は、(おそらくフレーム境界において) API からリセットできるでしょう。

サンプルごとの MinLOD クランプ

マップされていないことがわかっているミップマップ ストリーミング リソース内の領域をシェーダーが回避できるように、サンプラー (フィルタリング) の使用を伴うほとんどのシェーダー命令には、シェーダーが追加の float32 MinLOD クランプ パラメーターをテクスチャ サンプルに渡すことができるモードがあります。 基盤のリソースと異なり、この値はビューのミップマップ番号のスペースに保持されます。

ハードウェアは、リソースごとの MinLOD クランプが発生する LOD 計算と同じ場所で実行max(fShaderMinLODClamp,fComputedLOD)されます。これは max() でもあります。

サンプラーに定義されているサンプルごとの LOD クランプとその他の LOD クランプを適用した結果、空のセットが返された場合、結果は、リソースごとの minLOD クランプの結果と同様に境界外アクセスになり、サーフェス形式内に存在するコンポーネントに対しては 0、欠落しているコンポーネントに対しては既定値が使用されます。

ここで説明するサンプルごとの minLOD クランプより前の LOD 命令 ( tex2Dlod など) は、クランプされた LOD と非クランプされた LOD の両方を返します。 この LOD 命令から返されたクランプありの LOD は、リソースごとのクランプも含め、すべてのクランプを反映しますが、サンプルごとのクランプは反映されません。 サンプルごとのクランプは、いずれにせよシェーダーによって制御および認識されているため、必要に応じて、シェーダーの作成者は手動でそのクランプを LOD 命令の戻り値に適用できます。

最小および最大除去フィルタリング

アプリケーションは、ストリーミング リソースのマッピングの状態を通知する独自のデータ構造を管理することもできます。 例としては、ストリーミング リソースのすべてのタイルの情報を保持するテクセルを含むサーフェスがあります。 たとえば、任意のタイルの場所でマップされている最初の LOD を保存する必要があるとします。 ストリーミング リソースをサンプリングする場合と同様の方法でこのデータ構造を慎重にサンプリングすることで、テクスチャー フィルターのフットプリント全体を完全にマップする最小の LOD はどのようになるかを知ることができます。 このプロセスを簡単にするため、Direct3D 11.2 では、最小/最大フィルタリングという新しい汎用サンプラー モードが導入されています。

LOD 追跡用の最小/最大フィルタリングのユーティリティは、おそらく深度サーフェスのフィルタリングなど、他の用途にも便利であると思われます。

最小/最大フィルタリングは、通常のテクスチャ フィルターがフェッチするのと同じテクセルのセットをフェッチするサンプラーのモードです。 ただし、値をブレンドして回答を出すのではなく、コンポーネントごとに、フェッチされたテクセルの min() または max() を返します (たとえば、すべての G 値の min とは別に、すべての R 値の min を返すなど)。

最小/最大操作は、Direct3D の演算精度のルールに従います。 比較の順序は問題になりません。

最小/最大フィルタリングではないフィルター操作中に、特定のテクセルの重み付けが 0.0 になることがあります。 例としては、テクセルの中央に直接置かれるテクスチャ座標を持つリニア サンプルです。この場合、3 つのその他のテクセル (どれが該当するかは、ハードウェアによって決まります) は、フィルターでは考慮されますが、重みは 0 です。 最小/最大フィルター以外のフィルターで重みが 0 になるテクセルの場合、最小/最大のフィルターを使用しても、このようなテクセルは結果に影響を及ぼしません (重みも最小/最大操作に影響しません)。

この機能のサポートは、ストリーミング リソースの階層 2 のサポートによって決まります。

ストリーミング リソースへのパイプライン アクセス