Writing to a texture object
Unlike concurrency::array, which assumes continuous storage and offers pointer semantics for its interior, texture does not. As a result, we cannot provide the write operation via the subscript  operator (since  operator returns a const value), so we introduced the set member method for the purpose of assigning value to a texel:
Note that, like the  operator, the set method is annotated with restrict(amp), thus can only be used in amp restricted code. Here is an example:
Read, and/or write
A texture object is not always both readable and writable. In Direct3D, only a few DXGI_FORMATs support both read and write. Mostly, a texture used in a kernel (corresponding to a parallel_for_each launch in C++ AMP) can either be read-only or write-only, but not both.
In C++ AMP, inside a parallel_for_each, you can perform both read and write to a texture object of type texture<T, N> only if the following three rules are all satisfied:
- T has only one scalar element, and
- T is not double, norm, or unorm, and
- texture is constructed with bits_per_scalar_element of value 32.
Otherwise, only read is allowed and write is disallowed, the texture object is effectively read-only.
Violations of rule 1 and 2 are checked and reported at compilation time via static assertion in the set method for the texture class. Therefore, when the restrictions are violated, the set method cannot be called, thus write is disallowed. For example, if you have code like:
You will get a compilation error for the write as:
error C2338: Invalid value_type for set method.
For reporting violations of rule 3, we rely on runtime exceptions. Because the bits_per_scalar_element is not information known at compile-time, the violation is detected at runtime. For example,
That code can be compiled successfully. However, when it executes, an unsupported_feature exception will be thrown. The exception error message is:
unsupported_feature: Both read and write are detected on a texture with bits-per-scalar-element not equal to 32.
Note that the runtime detection is lenient, as it fires only if you perform both read and write on such a texture object.
Write to a writeonly_texture_view object
Now, you are probably asking “how can I write into a texture<T, N> object if the write is disallowed due to one of the aforementioned rules?”. The answer is that you have to do this using the writeonly_texture_view class, which creates a view of a texture object and provides the write-only accesses to it.
You can construct a writeonly_texture_view object from a texture object. Then you can call the set member method (which has no static assertion to check T) to perform the write. For example,
The above code can be compiled without error. Just like array_view, a writeonly_texture_view (e.g. “wo_tv4”) is a view or wrapper of the texture container (e.g. “tex4”), and it does not hold the data/storage. Please also note that when authoring the lambda, a writeonly_texture_view object needs to be captured by value, just like array_view. You can also construct writeonly_texture_view<T, N> inside restrict(amp) code, as long as the source texture object allows both read and write (satisfying rule 1 ~ 3).
The construction and use of “wo_tv5” is fine. The creation of “wo_tv6” triggers a static assertion because the T of “tex6” is int_2, which has more than one scalar element (violating rule 1):
error C2338: Invalid value_type for the constructor.
In this post, I have covered how to write to texture objects. One topic that I have not discussed yet is how to copy the content of a texture object (the results of the writes) back to the host memory. In a future blog post, we will talk about texture copying. Stay tuned! As always, your feedback is welcome below or in our MSDN Forum.