Currently I have a kernel that uses the following texture reference (a 3d texture of type unsigned char
):
texture<unsigned char, 3, cudaReadModeElementType> volumeTexture;
However, I need to be able to exchange the texture's type. I already templated the kernel so it is able to handle different types. But I was unable to exchange the texture's type or the texture itself while maintaining the old state (i.e. being able to handle unsigned char
and unsigned short
at the same time).
That's why I thought of using the texture object API. However, this API does not seem to support 3d textures. The available resource types are Linear
, Array
, MipMappedArray
and Pitch2D
. None of them seem to be designed for 3d textures. Does the texture object API really not support 3d textures at all?
Are there any workarounds? I could use a 2d texture where the slices are just stacked on top of each other. However, the necessary height for a 512³ entries volume (=512*512=262,144) exceeds the maximum texture2d height (65,536 on my device). So I would have to organize the slices both next to each other and on top of each other, which would result in pretty dirty address calculations which I would like to avoid.
Another way would be to copy the kernel code and exchange the texture reference. But that's not a very clean solution. Can the reference itself be templated somehow?
How about this?
Create two texture references:
texture<unsigned char, 3, cudaReadModeElementType> volumeTexture_char;
texture<unsigned short, 3, cudaReadModeElementType> volumeTexture_short;
Then, dynamically bind to the one you need in host code:
if (...) {
cudaBindTexture(0, volumeTexture_char, ...);
}
else {
cudaBindTexture(0, volumeTexture_short, ...);
}
Then, pass in a flag on which one to use in the kernel::
my_kernel<<...>>(use_short, ...);