リソース タイプ (Direct3D 10)
Direct3D パイプラインで使用されるすべてのリソースは、2 つの基本的なリソース タイプであるバッファーとテクスチャーから派生したものです。バッファーは未処理のデータ (要素) の集合であり、テクスチャーはテクセル (テクスチャー要素) の集合です。
- バッファー リソース
- テクスチャー リソース
リソースのレイアウト (またはメモリー フットプリント) を完全に指定する方法は 2 つあります。
- 型指定あり
リソース作成時に型を完全指定します。 - 型指定なし
リソースをパイプラインにバインドするときに型を完全指定します。
バッファー リソース
バッファー リソースは完全型付きデータの集合であり、内部ではバッファーに要素が格納されます。要素は 1 から 4 までの成分によって構成されます。要素のデータ型の例としては、圧縮済みデータ (R8G8B8A8 など)、1 つの 8 ビット整数、4 つの 32 ビット浮動小数点などがあります。これらのデータ型は、位置ベクトル、法線ベクトル、頂点バッファーのテクスチャー座標、インデックス バッファーのインデックス、またはデバイス ステートなどのデータの格納に使用されます。
バッファーは構造化されていないリソースとして作成されます。構造を持たないため、バッファーはミップマップ レベルを持つことができず、読み込み時にフィルターを適用したり、マルチサンプリングを実行したりすることもできません。
バッファーの種類
- 頂点バッファー
- インデックス バッファー
- 定数バッファー
頂点バッファー
バッファーは要素の集合であり、頂点バッファーは頂点ごとのデータを格納します。頂点バッファーの最も単純な例は、位置データのようなデータを 1 種類だけ持つ頂点バッファーです。これを図で表現すると次のようになります。
図形 1. 位置データを含む頂点バッファー
多くの場合、頂点バッファーには 3D の頂点を完全に指定するために必要なすべてのデータが含まれています。頂点ごとの位置座標、法線座標、およびテクスチャー座標を含む頂点バッファーなどは、その一例です。このようなデータは、頂点ごとの要素の集合として次のように構成されます。
図形 2. 位置、法線、およびテクスチャーのデータを含む頂点バッファー
この頂点バッファーは 8 つの頂点に関する頂点ごとのデータを含み、各頂点には 3 つの要素 (位置座標、法線座標、およびテクスチャー座標) が格納されます。一般的に、位置と法線のそれぞれは 3 つの 32 ビット浮動小数点 (DXGI_FORMAT_R32G32B32_FLOAT) を使って指定され、テクスチャーは 2 つの 32 ビット浮動小数点 (DXGI_FORMAT_R32G32_FLOAT) を使って指定されます。
頂点バッファーからデータにアクセスするには、アクセスする頂点と、次のバッファー パラメーターについての情報が必要です。
- オフセット - バッファーの先頭から最初の頂点データまでのバイト数です。オフセットは ID3D10Device::IASetVertexBuffers に指定します。
- BaseVertexLocation - オフセットから最初の頂点までのバイト数です。対応する描画の呼び出しで使用されます (「描画メソッド」を参照)。
頂点バッファーを作成する前に、入力レイアウト オブジェクトを作成して頂点バッファーのレイアウトを定義する必要があります。これは ID3D10Device::CreateInputLayout を呼び出すことによって行います。入力レイアウト オブジェクトを作成したら、ID3D10Device::IASetInputLayout を呼び出して入力アセンブラー ステージへバインドします。
頂点バッファーを作成するには、ID3D10Device::CreateBuffer を呼び出します。
インデックス バッファー
インデックス バッファーは 16 ビットまたは 32 ビットの連続するインデックスを格納します。各インデックスは頂点バッファーの頂点を識別するのに使用されます。IA ステージでデータを指定するために、1 つまたは複数の頂点バッファーと共にインデックス バッファーを使用することをインデックス付けと呼びます。インデックス バッファーを図で表現すると次のようになります。
図形 3. インデックス バッファーの概念図
インデックス バッファーに格納される一連のインデックスは、次のパラメーターによって位置指定されます。
- オフセット - バッファーの先頭から最初のインデックスまでのバイト数です。オフセットは ID3D10Device::IASetIndexBuffer に指定します。
- StartIndexLocation - オフセットから最初の頂点までのバイト数です。対応する描画の呼び出しで使用されます (「描画メソッド」を参照)。
- IndexCount - レンダリングするインデックスの数です。
インデックス バッファーを作成するには、ID3D10Device::CreateBuffer を呼び出します。
インデックス バッファーは、複数のラインまたはトライアングル ストリップを、それぞれをストリップ カット インデックスで区別することによりつなぎ合わせることができます。ストリップ カット インデックスを使用すると、複数のラインまたはトライアングル ストリップを 1 回の描画メソッド呼び出しで描画できます。ストリップ カット インデックスは、インデックスの可能な最大値にすぎません (16 ビット インデックスでは 0xffff、32 ビット インデックスでは 0xffffffff)。ストリップ カット インデックスは、インデックス付けしたプリミティブでワインディング順序をリセットします。ストリップ カット インデックスを使用すれば、縮退トライアングルを使用しなくても、トライアングル ストリップで適切なワインディング順序を維持できます。
図形 4. ストリップ カット インデックス
定数バッファー
Direct3D 10 には、シェーダー定数バッファーまたは単に定数バッファーと呼ばれるシェーダー定数を提供するための新しいバッファーが追加されています。これは概念的には、要素が 1 つの頂点バッファーに類似しています。
図形 5. シェーダー定数バッファーの概念図
各要素は 1 から 4 までの成分定数を格納します。この数は格納されるデータのフォーマットによって決定されます。
定数バッファーを使用すると、複数のシェーダー定数をまとめて同時にコミットできます。それぞれのシェーダー定数を個別の呼び出しで別々にコミットすることがないので、シェーダー定数の更新に必要な帯域を少なくすることができます。
シェーダー定数バッファーを作成するには、ID3D10Device::CreateBuffer を呼び出して定数バッファー バインド フラグ D3D10_BIND_CONSTANT_BUFFER (「D3D10_BIND_FLAG」を参照) を指定します。
シェーダー定数バッファーをパイプラインにバインドするには、以下のメソッドのいずれかを呼び出します。それらは、ID3D10Device::GSSetConstantBuffers、ID3D10Device::PSSetConstantBuffers、および ID3D10Device::VSSetConstantBuffers です。
ID3D10Effect インターフェイス インターフェイスを使用すると、定数バッファーの作成、バインド、およびコミットの各プロセスは ID3D10Effect インターフェイス インスタンスで扱われます。この場合、いずれかの GetVariable メソッド (ID3D10Effect::GetVariableByName など) でエフェクトから変数を取得し、いずれかの SetVariable メソッド (ID3D10EffectMatrixVariable::SetMatrix など) で変数を更新するだけで済みます。ID3D10Effect インターフェイス を使用して定数バッファーを管理する例については、「チュートリアル 7」を参照してください。
シェーダーは、定数バッファーにない変数を読み取るときと同様に、変数名によって定数バッファー内の変数を直接読み取り続けます。
各シェーダー ステージは 15 個までのシェーダー定数バッファーを持つことができ、各バッファーでは最大 4096 の定数を保持できます。
ストリーム出力ステージの結果の保存には定数バッファーを使用します。
シェーダーで定数バッファーを宣言する例については、「シェーダー定数 (DirectX HLSL)」を参照してください。
テクスチャー リソース
テクスチャー リソースは、テクセルの格納のために設計された、一連のデータを構造化したものです。バッファーと異なり、テクスチャーは、シェーダー ユニットによる読み取りの際に、テクスチャー サンプラーでフィルタリングが可能です。テクスチャーをフィルタリングする方法は、テクスチャーの種類に影響されます。テクセルは、パイプラインで読み取りまたは書き込みできるテクスチャーの最小単位を表します。各テクセルは 1 つから 4 つまでの成分を含み、DXGI フォーマットのどれか 1 つで配置されます (「DXGI_FORMAT」を参照)。
テクスチャーは構造化されたリソースとして作成されるので、そのサイズを知ることができます。ただし、リソース作成時に各テクスチャーは型付きか型なしのいずれかになるため、テクスチャーをパイプラインにバインドするときにビューを使用して型を完全に指定していることが条件です。
- テクスチャーのタイプ
- サブリソース
- 強い型付きと弱い型付き
テクスチャーのタイプ
テクスチャーのタイプには 1D、2D、および 3D があり、それぞれミップマップ付きまたはミップマップなしで作成できます。Direct3D 10 では、テクスチャー配列とマルチサンプル テクスチャーもサポートされています。
- 1D テクスチャー
- 1D テクスチャー配列
- 2D テクスチャーと 2D テクスチャー配列
- 3D テクスチャー
1D テクスチャー
1D は最も単純なフォーマットで、格納されているテクスチャー データは 1 つのテクスチャー座標に関連付けることができます。これを図で表現するとテクスチャーの配列になります。
図形 6. 1D テクスチャーの概念図
各テクセルは、いくつかのカラー成分を持ち、その数は格納するデータのフォーマットによって決まります。複雑なものとしては、ミップマップ レベル付きの 1D テクスチャーを作成できます。これを図で表現すると次のようになります。
図形 7. ミップマップ レベル付き 1D テクスチャーの概念図
ミップマップ レベルは、上のレベルより小さい 2 の累乗のテクスチャーです。最上位レベルが最も詳細で (大きく)、レベルが下がるほど小さくなります。1D ミップマップの最小レベルはテクセルを 1 つだけ含みます。各レベルの識別は、詳細レベル (LOD) と呼ばれるインデックスによって行われます。カメラにさほど近くないジオメトリをレンダリングルする場合は、LOD を使って小さいテクスチャーにアクセスします。
1D テクスチャー配列
Direct3D 10 では、テクスチャーの配列用の新しいデータ構造もサポートされています。1D テクスチャーの配列の 1 つを概念図で表現すると次のようになります。
図形 8. 1D テクスチャー配列の概念図
このテクスチャー配列は 3 つのテクスチャーを含んでいます。3 つのテクスチャーは、それぞれ 5 のテクスチャー幅を持ちます (5 は最初のレイヤーにある要素の数)。また、各テクスチャーは 3 つのレイヤー ミップマップを含みます。
Direct3D のすべてのテクスチャー配列は、テクスチャーの同次配列です。つまり、同じテクスチャー配列にあるテクスチャーは、すべて同じデータ フォーマットとサイズ (テクスチャー幅とミップマップ レベルの数) を持つ必要があります。各配列内のテクスチャーのサイズがすべて一致している限り、異なるサイズのテクスチャー配列を作成することは可能です。
2D テクスチャーと 2D テクスチャー配列
Texture2D リソースは、テクセルの 2D グリッドを 1 つを含みます。各テクセルは u ベクトルと v ベクトルによって指定されます。これはテクスチャー リソースの一種であるため、ミップマップ レベルとサブリソースを含むことが可能です。すべての要素が設定された 2D テクスチャー リソースは次のようになります。
図形 9. Texture2D リソース
このテクスチャー リソースには、1 つの 3x5 テクスチャーと 3 つのミップマップ レベルがあります。
Texture2DArray リソースは同次配列で、各テクスチャーは同じデータ フォーマットとサイズ (ミップマップ レベルを含む) を持ちます。この配列は、テクスチャーに 2D データが含まれることを除けば 1D テクスチャー配列と同様のレイアウトを持ち、次のようになります。
図形 10. Texture2DArray リソース
このテクスチャー配列は 3 つのテクスチャーを含み、各テクスチャーは 3x5 テクスチャーで、2 つのミップマップ レベルを持ちます。
Texture2DArray のテクスチャー キューブとしての使用
テクスチャー キューブは、キューブの各面に 1 つずつ 6 つのテクスチャーを含む 2D テクスチャー配列です。すべての要素が設定されたテクスチャー キューブは次のようになります。
図形 11. テクスチャー キューブを表現する 2D テクスチャーの配列
6 つのテクスチャーを含む 2D テクスチャー配列は、キューブ テクスチャー ビューでパイプラインにバインドした後、キューブ マップ組み込み関数を使ってシェーダー内から読み取ることができます。テクスチャー キューブは、テクスチャー キューブの中心を起点とする 3D ベクトルによってシェーダーで処理されます。
3D テクスチャー
Texture3D リソースは、ボリューム テクスチャーとも呼ばれ、テクセルの 3D ボリュームを含みます。これはテクスチャー リソースの一種であるため、ミップマップ レベルを含むことができます。すべての要素が設定された 3D テクスチャーは次のようになります。
図形 12. Texture3D リソース
3D テクスチャー ミップマップ スライスを (レンダー ターゲット ビューを使って) レンダー ターゲット出力としてバインドすると、3D テクスチャーは n スライスの 2D テクスチャーと同じように動作します。出力データのスカラー成分を SV_RenderTargetArrayIndex システム値として宣言すると、ジオメトリシェーダー ステージから特定のレンダリング スライスが選択されます。
3D テクスチャー配列という概念は存在しません。そのため、3D テクスチャーのサブリソースは単一のミップマップ レベルとなります。
サブリソース
Direct3D 10 API は、すべてのリソースまたはリソースの一部を参照します。一部のリソースを指定できるようにするため、リソースのサブセットを意味するサブリソースという用語が新たに Direct3D に追加されました。
バッファーは 1 つのサブリソースとして定義されます。テクスチャーは複数の異なるテクスチャー タイプ (1D、2D など) があり一部のテクスチャーはミップマップ レベルやテクスチャー配列をサポートするため少し複雑になります。まず、一番単純な場合の 1D テクスチャーは単一のサブリソースとして定義されます。
つまり、1D テクスチャーを構成するテクセルの配列は単一のサブリソースに分類されます。
1D テクスチャーを 3 つのミップマップ レベルを使って拡張した場合、図で表現すると次のようになります。
これを 3 つのサブテクスチャーで構成される単一のテクスチャーと考えます。各サブテクスチャーは 1 つのサブリソースとしてカウントされます。つまり、この 1D テクスチャーには 3 つのサブリソースが含まれます。サブテクスチャー (またはサブリソース) には、単一テクスチャー用の詳細レベル (LOD) を使ってインデックスを指定できます。テクスチャーの配列を使用する際、特定のサブテクスチャーにアクセスするには LOD と該当するテクスチャーの両方を指定する必要があります。または、API によってこの 2 つの情報を 0 から始まる次のサブリソース インデックスに結合します。
サブリソースの選択
一部の API はリソース全体にアクセスし (ID3D10Device::CopyResource など)、その他の API はリソースの一部にアクセスします (ID3D10Device::UpdateSubresource、ID3D10Device::CopySubresourceRegion など)。リソースの一部にアクセスする API は、一般的にビュー記述 (D3D10_TEX2D_ARRAY_DSV など) を使用してアクセスするサブリソースを指定します。
下の図は、テクスチャーの配列にアクセスする際にビュー記述で使用する用語を表しています。
配列スライス
あるテクスチャーの配列で、各テクスチャーにミップマップがある場合、配列スライスは白い長方形で表わされている部分であり、1 つのテクスチャーとそのすべてのサブテクスチャーを含みます。
ミップ スライス
ミップ スライスは白い長方形で表わされている部分であり、配列内のすべてのテクスチャーについて 1 つのミップマップ レベルを含みます。
単一サブリソースの選択
単一のリソースを選択する場合には、これらの 2 種類のスライスを使用します。
複数のサブリソースの選択
また、これらの 2 種類のリソースを複数のミップマップ レベル、複数のテクスチャー、またはそれらの両方と共に使用することで、複数のサブリソースを選択できます。
使用するテクスチャーの種類、ミップマップの有無、およびテクスチャー配列の有無にかかわらず、D3D10CalcSubresource ヘルパー関数を使用して、特定のサブリソースのインデックスを計算することができます。
強い型付きと弱い型付き
完全型付きリソースを作成すると、そのリソースのフォーマットはリソースを作成したときのフォーマットに制限されます。これによりランタイムによるアクセスを最適化することができます。特に、アプリケーションによってマップできないことを示すフラグで作成されたリソースに有効です。特定の型で作成されたリソースは、ビューの機能よる再解釈ができません。
型なしリソースでは、最初にリソースを作成したときのデータ型は不明です。アプリケーションで、利用可能な型なしフォーマットのいずれかを選択する必要があります (「DXGI_FORMAT」を参照)。また、割り当てるメモリーのサイズと、ランタイムがミップマップにサブテクスチャーを生成する必要があるかどうかを指定する必要があります。ただし、正確なデータ フォーマット (メモリーが整数、浮動小数点値、符号なし整数などのいずれに解釈されるか) はビューによってリソースがパイプラインにバインドされるまで決定されません。テクスチャー フォーマットはテクスチャーがパイプラインにバインドされるまで柔軟性があり、そのためこのリソースは弱い型付きストレージと呼ばれます。弱い型付きストレージには、新しいフォーマットの成分ビットが古いフォーマットのビット数と一致している限り、(別のフォーマットで) 再使用または再解釈できる利点があります。
各パイプライン ステージに、それぞれの場所のフォーマットを完全に規定する一意のビューがある限り、1 つのリソースを複数のパイプライン ステージにバインドすることができます。たとえば、フォーマット DXGI_FORMAT_R32G32B32A32_TYPELESS で作成されたリソースは、パイプラインの別の場所で DXGI_FORMAT_R32G32B32A32_FLOAT および DXGI_FORMAT_R32G32B32A32_UINT として同時に使用することが可能です。