Overview of the texture view design in C++ AMP

In order to enhance C++ AMP texture support with more features such as sampling and mipmap levels, we redesigned the C++ AMP texture view APIs in Visual Studio 2013. In this blog post, I will give you an overview of the changes we made in the design of texture views compared to Visual Studio 2012 and the rationale behind our design. Hopefully it will help to enable you to pick the appropriate texture types for your needs.

Texture APIs in Visual Studio 2012

Due to the current hardware limitation, reading and writing the same texture resource in the same kernel is only supported for very limited cases: 1-component texture type with 32-bit non-norm formats. For all other cases, either read access or write access, but not both, can be performed on the same texture within the same kernel.

In C++ AMP of Visual Studio 2012, the main texture usages we focused on, were to take advantage of texture’s hardware caches optimized for spatial locality and to support sub-word packing. We wanted to enable C++ AMP users to use the texture type just like the array type, which has the ability to be read from and written to within the same kernel. Therefore, we decided to let the texture<T,N> type serve the 1 component read/write scenario, and other read-only usages and introduced a new type writeonly_texture_view<T,N> to handle write-only usages.

The following table summarizes the texture API design of C++ AMP in Visual Studio 2012:

type

#Components

Lambda capture

Read

Write

texture<T, N>

1

ref

Yes

Yes

1

const ref

Yes

No

2, 4

ref, const ref

Yes

No

writeonly_texture_view<T, N>

1, 2, 4

value

No

Yes

 

Texture APIs in Visual Studio 2013

In Visual Studio 2013, we wanted to expose more hardware accelerated operations available for textures, such as sampling and mipmap level support. However, we encountered some design issues when trying to enhance the existing texture APIs with these new functionalities:

  • Texture sampling and reading a range of mipmap levels are only supported on texture sources that are guaranteed to be read-only. However, with the existing texture APIs, we cannot determine at the compile time if a one component texture object is read-only or not. Note that a const reference to a texture object cannot guarantee that it’s a read-only texture resource since it’s possible to capture a non-const reference to a texture object and then convert it to a const reference which is very common in C++ due to const reference function parameters.
  • The underlying platform supports binding a sub-range of mipmap levels of a texture for read, which is more efficient than binding the whole texture object. Neither the texture type nor the writeonly_texture_view type could represent such a read-only sub-range concept.
  • In order to write into a texture with multiple mipmap levels, a writable texture resource must be bound to the specific mipmap level that is being written to. The texture type represents the whole texture object including all mipmap levels, thus, is not suitable to represent a specific mipmap level. The writeonly_texture_view type, on the other hand, cannot represent the case that a writable texture resource is bound to a specific mipmap level of a texture whose value type supports both read and write in the same kernel.

To address these issues, in Visual Studio 2013, we introduced two new texture view types: texture_view<const T, N> and texture_view<T, N> to represent read-only texture views and read/write texture views respectively, which are consistent to the array_view’s design. In order to be backward compatible, we kept texture and writeonly_texture_view APIs as they are in Visual Studio 2012, but we are deprecating writeonly_texture_view since its functionality is now a subset of texture_view<T, N>.

The following table summarizes the new C++ AMP texture API design in Visual Studio 2013:

type

#Comp

Lambda capture

Read

Write

sampling

MipLevel access

texture<T, N>

1

ref

Yes

Yes

No (1)

level 0

1

const ref

Yes

No (3)

No (1)

level 0

2, 4

ref,

const ref

Yes

No (2)

No (1)

level 0

writeonly_texture_view<T, N>

(deprecated)

1, 2, 4

value

No (1)

Yes

No (1)

level 0

texture_view<const T, N>

1,2,4

value

Yes

No (1)

Yes

The range is defined upon construction; each level is dynamically indexable

texture_view<T, N>

1

value

Yes

Yes

No (1)

a specific level defined upon construction

2, 4

value

No (2)

Yes

No (1)

a specific level defined upon construction

The number in the parenthesis after “No” indicates how the specific operation is disallowed:

1 -- No member function is defined for the operation;

2 -- Static assertion is triggered for cases that are statically known unsupported for the operation;

3 -- The member function for the operation is non-const, and thus not accessible by the const reference assuming the constness is not casted away; the results would be undefined if constness is casted away;

Note that currently texture_view does not have the automatic data management and movement functionality as array_view provides. A texture_view can only be accessed on the accelerator_view where the underlying texture resides. But this functionality may be added in the future release.

This concludes the overview of the C++ AMP texture view design in Visual Studio 2013. We will have separate blog posts diving into details of texture sampling and mipmap support. So stay tuned. As usual, we’d love to hear your feedbacks, comments and questions below or on our MSDN Forum.