Cycles: CUDA bicubic and tricubic texture interpolation support.
[blender-staging.git] / intern / cycles / kernel / kernels / cuda / kernel_cuda_image.h
1 /*
2  * Copyright 2017 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #if __CUDA_ARCH__ >= 300
18
19 /* Kepler */
20
21 /* w0, w1, w2, and w3 are the four cubic B-spline basis functions. */
22 ccl_device float cubic_w0(float a)
23 {
24         return (1.0f/6.0f)*(a*(a*(-a + 3.0f) - 3.0f) + 1.0f);
25 }
26
27 ccl_device float cubic_w1(float a)
28 {
29         return (1.0f/6.0f)*(a*a*(3.0f*a - 6.0f) + 4.0f);
30 }
31
32 ccl_device float cubic_w2(float a)
33 {
34         return (1.0f/6.0f)*(a*(a*(-3.0f*a + 3.0f) + 3.0f) + 1.0f);
35 }
36
37 ccl_device float cubic_w3(float a)
38 {
39         return (1.0f/6.0f)*(a*a*a);
40 }
41
42 /* g0 and g1 are the two amplitude functions. */
43 ccl_device float cubic_g0(float a)
44 {
45         return cubic_w0(a) + cubic_w1(a);
46 }
47
48 ccl_device float cubic_g1(float a)
49 {
50         return cubic_w2(a) + cubic_w3(a);
51 }
52
53 /* h0 and h1 are the two offset functions */
54 ccl_device float cubic_h0(float a)
55 {
56         /* Note +0.5 offset to compensate for CUDA linear filtering convention. */
57         return -1.0f + cubic_w1(a) / (cubic_w0(a) + cubic_w1(a)) + 0.5f;
58 }
59
60 ccl_device float cubic_h1(float a)
61 {
62         return 1.0f + cubic_w3(a) / (cubic_w2(a) + cubic_w3(a)) + 0.5f;
63 }
64
65 /* Fast bicubic texture lookup using 4 bilinear lookups, adapted from CUDA samples. */
66 template<typename T>
67 ccl_device T kernel_tex_image_interp_bicubic(const TextureInfo& info, CUtexObject tex, float x, float y)
68 {
69         x = (x * info.width) - 0.5f;
70         y = (y * info.height) - 0.5f;
71
72         float px = floor(x);
73         float py = floor(y);
74         float fx = x - px;
75         float fy = y - py;
76
77         float g0x = cubic_g0(fx);
78         float g1x = cubic_g1(fx);
79         float x0 = (px + cubic_h0(fx)) / info.width;
80         float x1 = (px + cubic_h1(fx)) / info.width;
81         float y0 = (py + cubic_h0(fy)) / info.height;
82         float y1 = (py + cubic_h1(fy)) / info.height;
83
84         return cubic_g0(fy) * (g0x * tex2D<T>(tex, x0, y0) +
85                                g1x * tex2D<T>(tex, x1, y0)) +
86                cubic_g1(fy) * (g0x * tex2D<T>(tex, x0, y1) +
87                                g1x * tex2D<T>(tex, x1, y1));
88 }
89
90 /* Fast tricubic texture lookup using 8 bilinear lookups. */
91 template<typename T>
92 ccl_device T kernel_tex_image_interp_bicubic_3d(const TextureInfo& info, CUtexObject tex, float x, float y, float z)
93 {
94         x = (x * info.width) - 0.5f;
95         y = (y * info.height) - 0.5f;
96         z = (z * info.depth) - 0.5f;
97
98         float px = floor(x);
99         float py = floor(y);
100         float pz = floor(z);
101         float fx = x - px;
102         float fy = y - py;
103         float fz = z - pz;
104
105         float g0x = cubic_g0(fx);
106         float g1x = cubic_g1(fx);
107         float g0y = cubic_g0(fy);
108         float g1y = cubic_g1(fy);
109         float g0z = cubic_g0(fz);
110         float g1z = cubic_g1(fz);
111
112         float x0 = (px + cubic_h0(fx)) / info.width;
113         float x1 = (px + cubic_h1(fx)) / info.width;
114         float y0 = (py + cubic_h0(fy)) / info.height;
115         float y1 = (py + cubic_h1(fy)) / info.height;
116         float z0 = (pz + cubic_h0(fz)) / info.depth;
117         float z1 = (pz + cubic_h1(fz)) / info.depth;
118
119         return g0z * (g0y * (g0x * tex3D<T>(tex, x0, y0, z0) +
120                              g1x * tex3D<T>(tex, x1, y0, z0)) +
121                       g1y * (g0x * tex3D<T>(tex, x0, y1, z0) +
122                              g1x * tex3D<T>(tex, x1, y1, z0))) +
123                g1z * (g0y * (g0x * tex3D<T>(tex, x0, y0, z1) +
124                              g1x * tex3D<T>(tex, x1, y0, z1)) +
125                       g1y * (g0x * tex3D<T>(tex, x0, y1, z1) +
126                              g1x * tex3D<T>(tex, x1, y1, z1)));
127 }
128
129 ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
130 {
131         const TextureInfo& info = kernel_tex_fetch(__texture_info, id);
132         CUtexObject tex = (CUtexObject)info.data;
133
134         /* float4, byte4 and half4 */
135         const int texture_type = kernel_tex_type(id);
136         if(texture_type == IMAGE_DATA_TYPE_FLOAT4 ||
137            texture_type == IMAGE_DATA_TYPE_BYTE4 ||
138            texture_type == IMAGE_DATA_TYPE_HALF4)
139         {
140                 if(info.interpolation == INTERPOLATION_CUBIC) {
141                         return kernel_tex_image_interp_bicubic<float4>(info, tex, x, y);
142                 }
143                 else {
144                         return tex2D<float4>(tex, x, y);
145                 }
146         }
147         /* float, byte and half */
148         else {
149                 float f;
150
151                 if(info.interpolation == INTERPOLATION_CUBIC) {
152                         f = kernel_tex_image_interp_bicubic<float>(info, tex, x, y);
153                 }
154                 else {
155                         f = tex2D<float>(tex, x, y);
156                 }
157
158                 return make_float4(f, f, f, 1.0f);
159         }
160 }
161
162 ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
163 {
164         const TextureInfo& info = kernel_tex_fetch(__texture_info, id);
165         CUtexObject tex = (CUtexObject)info.data;
166         uint interpolation = (interp == INTERPOLATION_NONE)? info.interpolation: interp;
167
168         const int texture_type = kernel_tex_type(id);
169         if(texture_type == IMAGE_DATA_TYPE_FLOAT4 ||
170            texture_type == IMAGE_DATA_TYPE_BYTE4 ||
171            texture_type == IMAGE_DATA_TYPE_HALF4)
172         {
173                 if(interpolation == INTERPOLATION_CUBIC) {
174                         return kernel_tex_image_interp_bicubic_3d<float4>(info, tex, x, y, z);
175                 }
176                 else {
177                         return tex3D<float4>(tex, x, y, z);
178                 }
179         }
180         else {
181                 float f;
182
183                 if(interpolation == INTERPOLATION_CUBIC) {
184                         f = kernel_tex_image_interp_bicubic_3d<float>(info, tex, x, y, z);
185                 }
186                 else {
187                         f = tex3D<float>(tex, x, y, z);
188                 }
189
190                 return make_float4(f, f, f, 1.0f);
191         }
192 }
193
194 #else
195
196 /* Fermi */
197
198 ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
199 {
200         float4 r;
201         switch(id) {
202                 case 0: r = tex2D(__tex_image_float4_000, x, y); break;
203                 case 8: r = tex2D(__tex_image_float4_008, x, y); break;
204                 case 16: r = tex2D(__tex_image_float4_016, x, y); break;
205                 case 24: r = tex2D(__tex_image_float4_024, x, y); break;
206                 case 32: r = tex2D(__tex_image_float4_032, x, y); break;
207                 case 1: r = tex2D(__tex_image_byte4_001, x, y); break;
208                 case 9: r = tex2D(__tex_image_byte4_009, x, y); break;
209                 case 17: r = tex2D(__tex_image_byte4_017, x, y); break;
210                 case 25: r = tex2D(__tex_image_byte4_025, x, y); break;
211                 case 33: r = tex2D(__tex_image_byte4_033, x, y); break;
212                 case 41: r = tex2D(__tex_image_byte4_041, x, y); break;
213                 case 49: r = tex2D(__tex_image_byte4_049, x, y); break;
214                 case 57: r = tex2D(__tex_image_byte4_057, x, y); break;
215                 case 65: r = tex2D(__tex_image_byte4_065, x, y); break;
216                 case 73: r = tex2D(__tex_image_byte4_073, x, y); break;
217                 case 81: r = tex2D(__tex_image_byte4_081, x, y); break;
218                 case 89: r = tex2D(__tex_image_byte4_089, x, y); break;
219                 case 97: r = tex2D(__tex_image_byte4_097, x, y); break;
220                 case 105: r = tex2D(__tex_image_byte4_105, x, y); break;
221                 case 113: r = tex2D(__tex_image_byte4_113, x, y); break;
222                 case 121: r = tex2D(__tex_image_byte4_121, x, y); break;
223                 case 129: r = tex2D(__tex_image_byte4_129, x, y); break;
224                 case 137: r = tex2D(__tex_image_byte4_137, x, y); break;
225                 case 145: r = tex2D(__tex_image_byte4_145, x, y); break;
226                 case 153: r = tex2D(__tex_image_byte4_153, x, y); break;
227                 case 161: r = tex2D(__tex_image_byte4_161, x, y); break;
228                 case 169: r = tex2D(__tex_image_byte4_169, x, y); break;
229                 case 177: r = tex2D(__tex_image_byte4_177, x, y); break;
230                 case 185: r = tex2D(__tex_image_byte4_185, x, y); break;
231                 case 193: r = tex2D(__tex_image_byte4_193, x, y); break;
232                 case 201: r = tex2D(__tex_image_byte4_201, x, y); break;
233                 case 209: r = tex2D(__tex_image_byte4_209, x, y); break;
234                 case 217: r = tex2D(__tex_image_byte4_217, x, y); break;
235                 case 225: r = tex2D(__tex_image_byte4_225, x, y); break;
236                 case 233: r = tex2D(__tex_image_byte4_233, x, y); break;
237                 case 241: r = tex2D(__tex_image_byte4_241, x, y); break;
238                 case 249: r = tex2D(__tex_image_byte4_249, x, y); break;
239                 case 257: r = tex2D(__tex_image_byte4_257, x, y); break;
240                 case 265: r = tex2D(__tex_image_byte4_265, x, y); break;
241                 case 273: r = tex2D(__tex_image_byte4_273, x, y); break;
242                 case 281: r = tex2D(__tex_image_byte4_281, x, y); break;
243                 case 289: r = tex2D(__tex_image_byte4_289, x, y); break;
244                 case 297: r = tex2D(__tex_image_byte4_297, x, y); break;
245                 case 305: r = tex2D(__tex_image_byte4_305, x, y); break;
246                 case 313: r = tex2D(__tex_image_byte4_313, x, y); break;
247                 case 321: r = tex2D(__tex_image_byte4_321, x, y); break;
248                 case 329: r = tex2D(__tex_image_byte4_329, x, y); break;
249                 case 337: r = tex2D(__tex_image_byte4_337, x, y); break;
250                 case 345: r = tex2D(__tex_image_byte4_345, x, y); break;
251                 case 353: r = tex2D(__tex_image_byte4_353, x, y); break;
252                 case 361: r = tex2D(__tex_image_byte4_361, x, y); break;
253                 case 369: r = tex2D(__tex_image_byte4_369, x, y); break;
254                 case 377: r = tex2D(__tex_image_byte4_377, x, y); break;
255                 case 385: r = tex2D(__tex_image_byte4_385, x, y); break;
256                 case 393: r = tex2D(__tex_image_byte4_393, x, y); break;
257                 case 401: r = tex2D(__tex_image_byte4_401, x, y); break;
258                 case 409: r = tex2D(__tex_image_byte4_409, x, y); break;
259                 case 417: r = tex2D(__tex_image_byte4_417, x, y); break;
260                 case 425: r = tex2D(__tex_image_byte4_425, x, y); break;
261                 case 433: r = tex2D(__tex_image_byte4_433, x, y); break;
262                 case 441: r = tex2D(__tex_image_byte4_441, x, y); break;
263                 case 449: r = tex2D(__tex_image_byte4_449, x, y); break;
264                 case 457: r = tex2D(__tex_image_byte4_457, x, y); break;
265                 case 465: r = tex2D(__tex_image_byte4_465, x, y); break;
266                 case 473: r = tex2D(__tex_image_byte4_473, x, y); break;
267                 case 481: r = tex2D(__tex_image_byte4_481, x, y); break;
268                 case 489: r = tex2D(__tex_image_byte4_489, x, y); break;
269                 case 497: r = tex2D(__tex_image_byte4_497, x, y); break;
270                 case 505: r = tex2D(__tex_image_byte4_505, x, y); break;
271                 case 513: r = tex2D(__tex_image_byte4_513, x, y); break;
272                 case 521: r = tex2D(__tex_image_byte4_521, x, y); break;
273                 case 529: r = tex2D(__tex_image_byte4_529, x, y); break;
274                 case 537: r = tex2D(__tex_image_byte4_537, x, y); break;
275                 case 545: r = tex2D(__tex_image_byte4_545, x, y); break;
276                 case 553: r = tex2D(__tex_image_byte4_553, x, y); break;
277                 case 561: r = tex2D(__tex_image_byte4_561, x, y); break;
278                 case 569: r = tex2D(__tex_image_byte4_569, x, y); break;
279                 case 577: r = tex2D(__tex_image_byte4_577, x, y); break;
280                 case 585: r = tex2D(__tex_image_byte4_585, x, y); break;
281                 case 593: r = tex2D(__tex_image_byte4_593, x, y); break;
282                 case 601: r = tex2D(__tex_image_byte4_601, x, y); break;
283                 case 609: r = tex2D(__tex_image_byte4_609, x, y); break;
284                 case 617: r = tex2D(__tex_image_byte4_617, x, y); break;
285                 case 625: r = tex2D(__tex_image_byte4_625, x, y); break;
286                 case 633: r = tex2D(__tex_image_byte4_633, x, y); break;
287                 case 641: r = tex2D(__tex_image_byte4_641, x, y); break;
288                 case 649: r = tex2D(__tex_image_byte4_649, x, y); break;
289                 case 657: r = tex2D(__tex_image_byte4_657, x, y); break;
290                 case 665: r = tex2D(__tex_image_byte4_665, x, y); break;
291                 default: r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
292         }
293         return r;
294 }
295
296 ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z)
297 {
298         float4 r;
299         switch(id) {
300                 case 0: r = tex3D(__tex_image_float4_3d_000, x, y, z); break;
301                 case 8: r = tex3D(__tex_image_float4_3d_008, x, y, z); break;
302                 case 16: r = tex3D(__tex_image_float4_3d_016, x, y, z); break;
303                 case 24: r = tex3D(__tex_image_float4_3d_024, x, y, z); break;
304                 case 32: r = tex3D(__tex_image_float4_3d_032, x, y, z); break;
305         }
306         return r;
307 }
308
309 #endif
310