グラフィックス (C++ AMP)
C++ AMP は GPUs のテクスチャのサポートにアクセスするために使用できる Concurrency::graphics の名前空間に複数の API が含まれます。共通する例を次に示します。
計算のデータのコンテナーとして [テクスチャ] のクラスを使用し、GPU のハードウェアのテクスチャ キャッシュとレイアウト 空間的な局所性を 開発できます。空間的な場所は互いの近くに物理的に存在するデータ要素のプロパティです。
ランタイムは、計算シェーダーの有効な相互運用性を提供します。ピクセル、頂点シェーダーと、tesselation の枠の多くは、C++ AMP の計算で使用できるテクスチャを使用または作成します。
C++ AMP のグラフィックス API は、サブピクセル Word によって詰められるバッファーにアクセスするための別の方法を提供します。8 ビットまたは 16 ビットのスカラーで構成される texels (テクスチャの要素) を表す書式を持つテクスチャは、このような構成される、パックされたデータ ストレージにアクセスできます。
[!メモ]
C++ AMP API は、サンプリング テクスチャのフィルター処理機能を提供されません。C++ AMP の相互運用機能を使用し、DirectCompute と HLSL にコードを作成する必要があります。
標準と unorm の型
norm と unorm の型は float の値の範囲を制限するスカラー型です。; これで認識されるように 固定で停止します。これらの型は他のスカラー型から明示的に作成することができます。キャストでは、値は最初にキャスト float。次に、固定解除にられている標準 [- 1.0… 1.0] または unorm で許可されるそれぞれの領域に、[0.0… 1.0] です。キャストから、+、- 1 を返します。NaN からキャスト未定義です。標準は unorm から暗黙的に作成し、データ損失はありません。浮動への暗黙の変換演算子はこれらの型で定義されます。二項演算子は、これらの型および float や int などの他の組み込みのスカラー型との中で定義されています: +、-、*、/、==、! =、>、<、>=、<=。複合代入演算子もサポートされます: +=、- =、*=、/=。単項否定演算子は、標準型の場合 (-) が定義されます。
短いベクターのライブラリ
短いベクターのライブラリは HLSL で定義され、texels を定義するために一般的に使用される ベクターの型 機能の一部を提供します。短いベクターは、同じ型の 1 ~ 4 の値を保持するデータ構造です。サポートされている型には double、float、int、norm、uintと unormです。型名は次の表に示します。名前にアンダースコア () がない種類ごとに、対応する typedef があります。アンダースコアを含む型は Concurrency::graphics 名前空間にあります。アンダースコアがない型は Concurrency::graphics::direct3d 名前空間 に __int8 と同じ名前付き __int16のような基本型から明確に区別できるようになります。
長さ 2 |
長さ 3 |
長さ 4 |
|
---|---|---|---|
double |
double_2 double2 |
double_3 double3 |
double_4 double4 |
float |
float_2 float2 |
float_3 float3 |
float_4 float4 |
int |
int_2 int2 |
int_3 int3 |
int_4 int4 |
標準 |
norm_2 norm2 |
norm_3 norm3 |
norm_4 norm4 |
uint |
uint_2 uint2 |
uint_3 uint3 |
uint_4 uint4 |
unorm |
unorm_2 unorm2 |
unorm_3 unorm3 |
unorm_4 unorm4 |
演算子
演算子が 2 台の短いベクター中で定義されている場合、短いベクターとスカラー中で定義されます。また、これらの 1 つが満たされている必要があります:
スカラー型は短いベクターの要素型と同じである必要があります。
スカラー型は、ベクターの要素型に 1 個のユーザー定義の変換だけ使用して暗黙的に変換できます。
操作は短いベクターの各コンポーネントとスカラー的にコンポーネント間の変換です。有効な演算子です:を次に示します。
演算子の型 |
有効な型 |
---|---|
二項演算子 |
すべての型で有効: +、-、*、/、 整数型で有効: % の ^、|、&、<<、>> 2 個のベクターは同じサイズである必要があります。結果は同じサイズのベクターです。 |
関係演算子 |
すべての型で有効: ==! = |
複合代入演算子 |
すべての型で有効: +=、- =、*=、/= 整数型で有効: の ^=、%= |=、&=、<<=、>>= |
インクリメントとデクリメント演算子 |
すべての型で有効: ++、-- プレフィックスと後置の両方が有効です。 |
ビットごとの NOT 演算子 (|) |
整数型で有効です。 |
単項演算子 |
すべての型で有効 unorm と uintを除外します。 |
Swizzling の式
短いベクターのライブラリは短いベクターのコンポーネントにアクセスするに vector_type.identifier アクセサーの構成要素をサポートします。identifierは swizzling 式と呼ばれるベクター コンポーネントを指定します。式は左辺値または右辺値のいずれかです。識別子の文字は、可能性があります: x、y、z と w; または、" g a、b、「.X」と 「r」の平均ゼロ TH のコンポーネント、「y」と 「g」の平均最初のコンポーネントなど。(「x」と 「r」が同じ識別子で使用できない通知します。) したがって、rgba 「」および 「」 xyzw 同じ結果を返します。「x」と 「y」のようなコンポーネントのアクセサーはスカラー値型です。単項複数アクセサーは短いベクターの型です。たとえば fourInts という名前で、値 2、4、6、および 8 がある int_4 ベクターを作成する場合、fourInts.y は整数 4 および fourInts.rg を返します。値 2 および 4. である int_2 オブジェクトを返します。
テクスチャのクラス
多くの GPUs にピクセルと texels をフェッチ、イメージ、およびテクスチャを表示するために最適化されたキャッシュとハードウェアがあります。texel のオブジェクトのコンテナー クラスである テクスチャ<T,N> のクラスは、これらの GPUs のテクスチャの機能を公開します。texel は次のとおりです:
int、uint、float、double、norm、または unorm のスカラー。
2 個または 4 個の要素を持つベクター短い。許可されない唯一の例外は double_4です。
texture のオブジェクトは、1、2、または 3. の順位を持つことができます。texture のオブジェクトは parallel_for_eachへの呼び出しでラムダの参照によってのみキャプチャできます。テクスチャは、Direct3D テクスチャのオブジェクトとして GPU に格納されます。Direct3d のテクスチャおよび texels に関する詳細については、Direct3D 11 のテクスチャの概要" " を参照してください。
使用する texel の型は、グラフィックス プログラミングで使用される多数のテクスチャの形式の 1 桁になることがあります。たとえば、RGBA の形式は、R G 12、A および B のスカラーの要素に対して 8 ビットを持つ各 32 ビットを使用できます。グラフィックス カードのテクスチャのハードウェアは、書式指定に基づいて、個々の要素にアクセスできます。たとえば、RGBA の書式を使用すると、テクスチャのハードウェアは、32 ビットの各 8 ビット フォームに要素を配置できます。C++ AMP では、ビット転移を使用しないで自動的にコードのスカラー個々の要素にアクセスできるように texel のスカラー要素ごとのビットを設定できます。
テクスチャのオブジェクトのインスタンス化
初期化せずにテクスチャのオブジェクトを宣言できます。次のコード例は、複数のテクスチャ オブジェクトを宣言します。
#include <amp.h>
#include <amp_graphics.h>
using namespace concurrency;
using namespace concurrency::graphics;
void declareTextures() {
// Create a 16-texel texture of int.
texture<int, 1> intTexture1(16);
texture<int, 1> intTexture2(extent<1>(16));
// Create a 16 x 32 texture of float_2.
texture<float_2, 2> floatTexture1(16, 32);
texture<float_2, 2> floatTexture2(extent<2>(16, 32));
// Create a 2 x 4 x 8 texture of uint_4.
texture<uint_4, 3> uintTexture1(2, 4, 8);
texture<uint_4, 3> uintTexture2(extent<3>(2, 4, 8));
}
また texture のオブジェクトを宣言および初期化するには、コンストラクターを使用できます。次のコード例に float_4 のオブジェクトのベクターの texture のオブジェクトをインスタンス化します。スカラー ビットごとの要素は既定値に設定されます。それらがスカラー要素ごとに既定のビットがないため norm と unormの norm、unorm、または短いベクターを持つ、コンストラクターを使用できません。
#include <amp.h>
#include <amp_graphics.h>
#include <vector>
using namespace concurrency;
using namespace concurrency::graphics;
void initializeTexture() {
std::vector<int_4> texels;
for (int i = 0; i < 768 * 1024; i++) {
int_4 i4(i, i, i, i);
texels.push_back(i4);
}
texture<int_4, 2> aTexture(768, 1024, texels.begin(), texels.end());
}
また、バイトのデータ ソースのデータ ソース、サイズ、およびのビットごとスカラー要素へのポインターを受け取るコンストラクター オーバーロードを使用して texture のオブジェクトを宣言および初期化できます。
void createTextureWithBPC() {
// Create the source data.
float source[1024 * 2];
for (int i = 0; i < 1024 * 2; i++) {
source[i] = (float)i;
}
// Initialize the texture by using the size of source in bytes
// and bits per scalar element.
texture<float_2, 1> floatTexture(1024, source, (unsigned int)sizeof(source), 32U);
}
これらの例のテクスチャは、既定のアクセラレータの既定のビューに作成されます。accelerator_view のオブジェクトを指定するには、コンストラクターの他のオーバーロードを使用できます。CPU のアクセラレータのテクスチャのオブジェクトを作成できます。
次の表に示すように texture のオブジェクトの各次元のサイズに制限があります。ランタイム エラーが限界を超えている場合に生成されます。
テクスチャ |
サイズの制限 |
---|---|
テクスチャ<T,1> |
16384 |
テクスチャ<T,2> |
16384 |
テクスチャ<T,2> |
2048 |
テクスチャのオブジェクトから読み取ること
texture のオブジェクトから texture::operator[] 演算子、texture::operator() 演算子、または texture::get メソッドを使用して読み込むことができます。texture::operator[] 演算子 と texture::operator() 演算子 は、値ではなく参照を返します。したがって、texture に texture::operator[] 演算子を使用してオブジェクトを作成することはできません。
void readTexture() {
std::vector<int_2> src;
for (int i = 0; i < 16 *32; i++) {
int_2 i2(i, i);
src.push_back(i2);
}
std::vector<int_2> dst(16 * 32);
array_view<int_2, 2> arr(16, 32, dst);
arr.discard_data();
const texture<int_2, 2> tex9(16, 32, src.begin(), src.end());
parallel_for_each(tex9.extent, [=, &tex9] (index<2> idx) restrict(amp) {
// Use the subscript operator.
arr[idx].x += tex9[idx].x;
// Use the function () operator.
arr[idx].x += tex9(idx).x;
// Use the get method.
arr[idx].y += tex9.get(idx).y;
// Use the function () operator.
arr[idx].y += tex9(idx[0], idx[1]).y;
});
arr.synchronize();
}
次のコード例は、短い実行ベクターにテクスチャのチャネルを格納する方法と、に短いベクターのプロパティとして個々のスカラー要素にアクセスします。
void UseBitsPerScalarElement() {
// Create the image data.
// Each unsigned int (32-bit) represents four 8-bit scalar elements(r,g,b,a values).
const int image_height = 16;
const int image_width = 16;
std::vector<unsigned int> image(image_height * image_width);
extent<2> image_extent(image_height, image_width);
// By using uint_4 and 8 bits per channel, each 8-bit channel in the data source is
// stored in one 32-bit component of a uint_4.
texture<uint_4, 2> image_texture(image_extent, image.data(), image_extent.size() * 4U, 8U);
// Use can access the RGBA values of the source data by using swizzling expressions of the uint_4.
parallel_for_each(image_extent,
[&image_texture](index<2> idx) restrict(amp)
{
// 4 bytes are automatically extracted when reading.
uint_4 color = image_texture[idx];
unsigned int r = color.r;
unsigned int g = color.g;
unsigned int b = color.b;
unsigned int a = color.a;
});
}
次の表は、並べ替えのベクターの型のチャネルあたりの有効なビットを示します。
テクスチャのデータ型 |
スカラー要素ごとに有効なビット |
---|---|
int、int_2、int_4 uint、uint_2、uint_4 |
8, 16, 32 |
浮動 float_2、float_4 |
16, 32 |
Double、double_2 |
64 |
標準、norm_2、norm_4 unorm、unorm_2 の unorm、4 |
8, 16 |
オブジェクトを織る書き込み
texture にオブジェクトを書き込むに texture::set のメソッドを使用します。テクスチャのオブジェクトを読み取り専用または読み取り/書き込みにすることができます。読みやすく、書き込みができるテクスチャのオブジェクトには、次の条件が満たされている必要があります:
T に 1 個のスカラー コンポーネントだけです。(短いベクターは使用できません)。
T が double、norm、または unormではありません。
texture::bits_per_scalar_element のプロパティは 32 です。
3 はすべて true である、texture のオブジェクトは読み取り専用です。最初の 2 種類の要件は、コンパイル時にチェックされます。コンパイル エラーが発生するのは readonly にテクスチャを作成するためのオブジェクト コードが生成されます。texture::bits_per_scalar_element の要件は実行時に検出され、読み取り専用 texture にオブジェクトを作成しようとすると、ランタイムは unsupported_feature の例外を生成します。
テクスチャを次のコード例の書き込み値を追加します。
void writeTexture() {
texture<int, 1> tex1(16);
parallel_for_each(tex1.extent, [&tex1] (index<1> idx) restrict(amp) {
tex1.set(idx, 0);
});
}
オブジェクトを使用して writeonly_texture_view
writeonly_texture_view のクラスは、テクスチャのオブジェクトの概要を writeonly 提供します。writeonly_texture_view のオブジェクトは、ラムダの式の値によってキャプチャされる必要があります。次のコード例では、2 のコンポーネント (int_2) である texture のオブジェクトへの書き込みに writeonly_texture_view のオブジェクトを使用します。
void write2ComponentTexture() {
texture<int_2, 1> tex4(16);
writeonly_texture_view<int_2, 1> wo_tv4(tex4);
parallel_for_each(extent<1>(16), [=] (index<1> idx) restrict(amp) {
wo_tv4.set(idx, int_2(1, 1));
});
}
テクスチャのオブジェクトをコピーします
テクスチャの使用はオブジェクトの間を次のコード例に示すように [コピー] の関数または copy_async 関数を使用して、コピーできます。
void copyHostArrayToTexture() {
// Copy from source array to texture object by using the copy function.
float floatSource[1024 * 2];
for (int i = 0; i < 1024 * 2; i++) {
floatSource[i] = (float)i;
}
texture<float_2, 1> floatTexture(1024);
copy(floatSource, (unsigned int)sizeof(floatSource), floatTexture);
// Copy from source array to texture object by using the copy function.
char charSource[16 * 16];
for (int i = 0; i < 16 * 16; i++) {
charSource[i] = (char)i;
}
texture<int, 2> charTexture(16, 16, 8U);
copy(charSource, (unsigned int)sizeof(charSource), charTexture);
// Copy from texture object to source array by using the copy function.
copy(charTexture, charSource, (unsigned int)sizeof(charSource));
}
また、1 種類のテクスチャから別の要素に texture::copy_to のメソッドを使用してコピーできます。2 個のテクスチャは異なる accelerator_views です。writeonly_texture_view にオブジェクトをコピーすると、データは texture の基になるオブジェクトにコピーされます。スカラー要素と範囲ごとのビットはコピー元とコピー先の texture のオブジェクトで同じにする必要があります。これらの条件が満たされない場合、ランタイムは例外をスローします。
相互運用性
texture<T,1> と ID3D11Texture1D のインターフェイス、texture<T,2> と ID3D11Texture2D のインターフェイス、texture<T,3> 間の C++ AMP のランタイム サポートの相互運用性、および ID3D11Texture3D のインターフェイス。get_texture のメソッドは texture のオブジェクトを受け取り、IUnknown のインターフェイスを返します。make_texture のメソッドは IUnknown のインターフェイスと accelerator_view のオブジェクトを受け取り、texture のオブジェクトを返します。