In the v2 release of C++ AMP through Visual Studio 2013, one of our main efforts were focused around extending the features of textures by supporting Texture Mipmaps.
Mipmaps are the sequence of images that accompany the main texture image. Each dimension in subsequent image is half of the previous one. For example:
64x64 -> 32x32 -> 16x16 -> 8x8 -> 4x4 -> 2x2 -> 1x1
A texture with mipmaps occupies 33% more space than a texture without mipmaps. The primary usage of mipmaps is to speed up processing time when a full texture image is not needed.
Creation of Texture with Mipmaps in C++ AMP
A texture with mipmaps can be adopted from DirectX or it can be created directly in C++ AMP.
Adopting DirectX Texture with Mipmaps
A DirectX texture with mipmaps can be adopted in C++ AMP with concurrency::graphics::direct3d::make_texture , just like the texture adoption done in the v1 release.
Let’s slightly modify the code snippet given in ‘Interop Example aka Show me the Code’ section of our earlier blog post about texture interop apis , to show creation of texture with mipmaps in Directx and then its adoption into amp code.
So, the texture<uint4, 2> created via make_texture call, holds mipmaps already available in the Direct3D texture object, i.e. 10x10, 5x5, 2x2.
Creation of Texture with Mipmaps directly
More new constructors are added to concurrency::graphics::texture which gives the ability to create a texture with all possible mipmaps or a subset of mipmaps.
- Value 0 for ‘_Mipmap_levels’, will cause constructor to generate full set of uninitialized mipmaps.
- Value greater than 0 for ‘_Mipmap_levels’, will generate specific amount of mimaps.
- In all other constructors that do not explicitly specify Mipmap levels, the texture construction will be similar to the construction of textures with value 1 for ‘_Mipmap_levels’
Let’s see few examples of constructions below :
Changes in the properties of Textures
The support for texture with Mipmaps affected the common properties of C++ Texture objects. A new property is added and the definition of one of the existing properties got changed. The below table summarizes the changes in the properties from v1.
|Property Name||Changes in V2|
|data_length||If the texture/texture_view object contains Mipmaps, then the data_length is sum of data lengths at each mipmap level|
This is the new property. It gives the number of Mipmap levels available in the texture/texture_view object.
For readonly texture views , this property can be queried even in AMP Kernel functions.
Writing to Texture Mipmap
Just like writing data to texture object using texture_view<T,R>, we also need to create a texture_view object to write data to a texture mipmap. The writable texture view constructed for texture object having a mipmap, represents only one mipmap level. So, we have to explicitly specify the mipmap level on which the writable view needs to be constructed.
Please note that the labels/names/indexing of mipmap levels start from 0. ‘0 mipmap level’ indicates the most detailed level.
Let’s see an example to how to write to a particular mipmap:
Note that the extent<N> of the texture_view object may not be equal to the extent of the source texture object. It changes accordingly to the shape of the mipmap on which the view is created.
Reading data from Texture Mipmap
To read data from texture mipmaps, we also need to create ready only texture views. Unlike the writable texture views, which allows to create view only one particular mipmap level, the read only texture views can be created for a particular range of mipmap levels.
Note that new read only views can be only created in CPU context only. In GPU context, it can only be copy constructed.
In addition to the new constructors, a new member function is added to read only texture views which help reading from the selected mipmap levels.
Let’s see an example of reading data from Mipmaps :
Sampling with Mipmaps
Our earlier blog posts about Sampling already gave the full details on how to do Sampling using Texture objects. Introduction of Texture Mipmaps extended the samping functionality to Mipmaps. The sample member function on texture<const T, N> will take additional argument which defines mipmap level on which to sample (also called level of detail).
The fractional values of _Level_of_detail are used to interpolate between two mipmap levels. The values <=0 will use the largest (zero’th) mipmap. Similarly the values greater than number of available mip levels will use the smallest (last) mipmap. For fractional values of _Level_of_detail, the value is interpolated using the values between the two mipmap levels based on the sampler settings.
Let’s see an example of how to sample using data from Mipmaps:
In this post, we learnt in detail about textures with Mipmaps. Stay tuned to know what C++ AMP offers you in Visual Studio 2013. As usual, I would love to read your comments below or in our MSDN forum.