リソースの選択 (Direct3D 10)
リソースは 3D パイプラインによって使用されるデータの集まりです。リソースを作成しその動作を定義することが、アプリケーションをプログラムするための最初の手順となります。このガイドでは、アプリケーションに必要なリソースを選択するための基本事項について説明します。
- リソースを必要とするパイプラインのステージの特定
- 各リソースの使用方法の特定
- リソースからパイプラインのステージへのバインド
リソースを必要とするパイプラインのステージの特定
最初の手順はリソースを使用するパイプラインのステージの選択です。このとき、リソースからデータを読み込むステージだけでなくリソースにデータを書き込むステージも特定します。リソースを使用するパイプラインのステージを把握できれば、リソースをステージにバインドするために呼び出す API を決定できます。
次の表は、各パイプラインのステージにバインドすることのできるリソースの種類を示しています。バインド API の他にも、リソースが入力または出力としてバインドできるかどうかも示しています。
パイプラインのステージ | 入力/出力 | リソース | リソースの種類 | バインド API |
---|---|---|---|---|
入力アセンブラー | 入力 | 頂点バッファー | バッファー | ID3D10Device::IASetVertexBuffers |
入力アセンブラー | 入力 | インデックス バッファー | バッファー | ID3D10Device::IASetIndexBuffer |
シェーダー ステージ | 入力 | シェーダー リソース ビュー | バッファー、Texture1D、Texture2D、Texture3D | ID3D10Device::VSSetShaderResources, ID3D10Device::GSSetShaderResources, ID3D10Device::PSSetShaderResources |
シェーダー ステージ | 入力 | シェーダー定数バッファー | バッファー | ID3D10Device::VSSetConstantBuffers, ID3D10Device::GSSetConstantBuffers, ID3D10Device::PSSetConstantBuffers |
ストリーム出力 | 出力 | バッファー | バッファー | ID3D10Device::SOSetTargets |
出力結合 | 出力 | レンダー ターゲット ビュー | バッファー、Texture1D、Texture2D、Texture3D | ID3D10Device::OMSetRenderTargets |
出力結合 | 出力 | 深度/ステンシル ビュー | Texture1D、Texture2D | ID3D10Device::OMSetRenderTargets |
各リソースの使用方法の特定
アプリケーションが使用するパイプラインのステージ (および各ステージが必要とするリソース) を選択したら、各リソースの使用方法つまりリソースを CPU または GPU からアクセス可能にするかどうかを決定します。
アプリケーションを実行するハードウェアには、最低でも CPU と GPU が 1 つずつあります。使用方法の値を選ぶ際には、リソースの読み取りまたは書き込みに必要なプロセッサの種類が次の選択肢のいずれになるかを検討します (「D3D10_USAGE」を参照)。
リソースの使用方法 | 更新の実行 | 更新頻度 |
---|---|---|
既定 | GPU | 低頻度 |
動的 | CPU | 高頻度 |
ステージング | GPU | なし |
固定 | CPU (リソースの作成時のみ) | なし |
CPU によるリソースの更新が低頻度 (フレームごとに 1 回未満) であると予想される場合は、既定の使用方法を選択します。パフォーマンス低下を避けるため、既定の使用方法では CPU からリソースに直接書き込まないことが理想です。
CPU によるリソースの更新が比較的高頻度 (フレームごとに 1 回以上) である場合は、動的の使用方法を選択します。動的リソースの一般的なシナリオは、動的な頂点バッファーとインデックス バッファーを作成し、ユーザーの視点から見えるジオメトリのデータを使用して、実行時にフレームごとに描画することです。これらのバッファーは、各フレームでユーザーから見えるジオメトリのみをレンダリングするために使用されます。
ステージングの使用方法は、他のリソースとの間のコピーに使用します。一般的なシナリオは、既定の使用方法おける (CPU がアクセスできない) リソースのデータをステージングの使用方法における (CPU がアクセス可能な) リソースにコピーすることです。
固定のリソースは、リソース内のデータが決して変更されない場合に使用します。
この問題を別の視点から見ると、アプリケーションがリソースにどのような処理を実行するか考えることになります。
アプリケーションによるリソースの使用方法 | リソースの使用方法 |
---|---|
1 度だけロードし更新しない | 固定または既定 |
アプリケーションが頻繁にデータをリソースに格納する | 動的 |
テクスチャーへのレンダリング | 既定 |
GPU データの CPU アクセス | ステージング |
どの使用法を選択すべきかよくわからない場合は、一般的なほとんどのケースに対応可能な既定の使用方法から始めてください。シェーダー定数バッファーは、常に既定の使用方法にする必要のあるリソース タイプの 1 つです。
リソースからパイプラインのステージへのバインド
リソースは、作成時に指定された制限 (利用フラグ、バインド フラグ、CPU アクセス フラグ) を満たす限り、同時に複数のパイプラインのステージにバインドすることができます。リソースの読み取り部分と書き込み部分の同時発生がない場合には、特に、リソースを入力と出力に同時にバインドすることができます。
リソースをバインドするときは、CPU と GPU がリソースにどのようにアクセスするかを考えます。多くの場合、単一の用途に設計された (複数の利用フラグ、バインド フラグ、および CPU アクセス フラグを持たない) リソースの方がより高いパフォーマンスを得られます。
たとえば、テクスチャーとして複数回使用されるレンダー ターゲットを考えてください。この場合、リソースを 2 つにする方が速くなる可能性があります (1 つのシェーダー リソースとしてレンダー ターゲットとテクスチャーを使用)。各リソースは、バインド フラグ (D3D10_BIND_RENDER_TARGET または D3D10_BIND_SHADER_RESOURCE) を 1 つだけ使用します。データは、ID3D10Device::CopyResource または ID3D10Device::CopySubresourceRegion によってレンダー ターゲット テクスチャーからシェーダー テクスチャーにコピーされます。このようにシェーダー テクスチャーの読み取りとレンダー ターゲットの書き込みを分離することでパフォーマンスが向上する可能性があります。当然のことながら、実際にどうなるかを確かめるにはアプリケーションに両方の方法を実装して、パフォーマンスの違いを測定する必要があります。