When I introduced the concurrency::graphics namespace, I gave a light introduction on the texture type in C++ AMP explaining the motivation behind it. In this post and coming posts, I and my colleagues will dive deeper into the texture type and I will also assume you have read about the short vector types in C++ AMP.
So, let’s first understand some basics, then how to create a texture of ints, uints, floats and doubles without/with initialization, then some properties of texture class, then how to capture a texture object in the lambda passed to the parallel_for_each, and finally how to read from a texture object in restrict(amp) code.
As with short vector types, to start using texture, you need to do the following:
The concurrency::graphics::texture<T, N> template class represents a multi-dimensional container of texels of type T, of N dimensions, specified at compile time. Notice that texture<T, N> looks like concurrency::array<T, N>, but the texel type T can only be one of the following types:
- scalar types: int, uint, float, double, norm, and unorm,
- short vector types that have two or four components, e.g., uint_2 and float_4, etc. Among double based short vector types, only double_2 is allowed. Because a double is actually represented with two int’s in a texture, and a texel can only have up to four components.
Direct3D offers very few three-component DXGI_FORMAT’s, and textures of such formats have limited functionality. Since three-component texels are rarely used, in this release of C++ AMP, T cannot be a three-component short vector type.
Rank N can be 1, 2, or 3.
The construction of a texture is quite similar to the construction of a concurrency::array. It can be created without being initialized, for example,
The constructions above do not specify an accelerator_view, as a result, the default accelerator_view of the default accelerator will be used. Just like array, you can specify the accelerator_view where you’d like to create the texture. For example,
Unlike array, you cannot create a texture on a cpu_accelerator.
Specific to our implementation on top of Direct3D, there’re limits (in number of texels) on the size for each dimension of the texture. For each dimension, the inclusive limits are:
For example, if you create a texture that exceeds the limit:
You will get a runtime_exception with error code E_INVALIDARG, and a message:
Failed to create texture: the limit for each dimension is 16384.
You can also construct a texture and initialize it by providing two iterators that specify the range of the input data. For example,
In this way, we create a 2D texture of 16 x 32, and fill the texture with the content from the src vector.
On my machine, the output is:
Other properties of the texture class will be covered in a separate blog post.
Read from Texture
Again, same as array, you can read from a texture object via indexing by either supplying index<N> object to the  subscript operator, function () operator, or get method, or passing integer values to the function () operator. Below is an example of reading from texture:
Unlike array, texture’s subscript operator and function call operator do not return a reference, but return a value. That is, there is no pointer/reference to the interior of a texture. Also, this indicates that you cannot write to textures via the subscript  operator. We will explain how to write to textures in a future post.