Revert "Depsgraph: Link from material to object shading"
[blender.git] / intern / cycles / kernel / kernel_image_opencl.h
1 /*
2  * Copyright 2016 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
18 /* For OpenCL all images are packed in a single array, and we do manual lookup
19  * and interpolation. */
20
21 ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int offset)
22 {
23         const texture_type = kernel_tex_type(id);
24         /* Float4 */
25         if(texture_type == IMAGE_DATA_TYPE_FLOAT4) {
26                 return kernel_tex_fetch(__tex_image_float4_packed, offset);
27         }
28         /* Byte4 */
29         else if(texture_type == IMAGE_DATA_TYPE_BYTE4) {
30                 uchar4 r = kernel_tex_fetch(__tex_image_byte4_packed, offset);
31                 float f = 1.0f/255.0f;
32                 return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
33         }
34         /* Float */
35         else if(texture_type == IMAGE_DATA_TYPE_FLOAT) {
36                 float f = kernel_tex_fetch(__tex_image_float_packed, offset);
37                 return make_float4(f, f, f, 1.0f);
38         }
39         /* Byte */
40         else {
41                 uchar r = kernel_tex_fetch(__tex_image_byte_packed, offset);
42                 float f = r * (1.0f/255.0f);
43                 return make_float4(f, f, f, 1.0f);
44         }
45 }
46
47 ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
48 {
49         x %= width;
50         if(x < 0)
51                 x += width;
52         return x;
53 }
54
55 ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
56 {
57         return clamp(x, 0, width-1);
58 }
59
60 ccl_device_inline float svm_image_texture_frac(float x, int *ix)
61 {
62         int i = float_to_int(x) - ((x < 0.0f)? 1: 0);
63         *ix = i;
64         return x - (float)i;
65 }
66
67 ccl_device_inline uint kernel_decode_image_interpolation(uint4 info)
68 {
69         return (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR;
70 }
71
72 ccl_device_inline uint kernel_decode_image_extension(uint4 info)
73 {
74         if(info.w & (1 << 1)) {
75                 return EXTENSION_REPEAT;
76         }
77         else if(info.w & (1 << 2)) {
78                 return EXTENSION_EXTEND;
79         }
80         else {
81                 return EXTENSION_CLIP;
82         }
83 }
84
85 ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
86 {
87         uint4 info = kernel_tex_fetch(__tex_image_packed_info, id*2);
88         uint width = info.x;
89         uint height = info.y;
90         uint offset = info.z;
91         /* Decode image options. */
92         uint interpolation = kernel_decode_image_interpolation(info);
93         uint extension = kernel_decode_image_extension(info);
94         /* Actual sampling. */
95         float4 r;
96         int ix, iy, nix, niy;
97         if(interpolation == INTERPOLATION_CLOSEST) {
98                 svm_image_texture_frac(x*width, &ix);
99                 svm_image_texture_frac(y*height, &iy);
100
101                 if(extension == EXTENSION_REPEAT) {
102                         ix = svm_image_texture_wrap_periodic(ix, width);
103                         iy = svm_image_texture_wrap_periodic(iy, height);
104                 }
105                 else {
106                         if(extension == EXTENSION_CLIP) {
107                                 if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
108                                         return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
109                                 }
110                         }
111                         /* Fall through. */
112                         /* EXTENSION_EXTEND */
113                         ix = svm_image_texture_wrap_clamp(ix, width);
114                         iy = svm_image_texture_wrap_clamp(iy, height);
115                 }
116
117                 r = svm_image_texture_read(kg, id, offset + ix + iy*width);
118         }
119         else { /* INTERPOLATION_LINEAR */
120                 float tx = svm_image_texture_frac(x*width - 0.5f, &ix);
121                 float ty = svm_image_texture_frac(y*height - 0.5f, &iy);
122
123                 if(extension == EXTENSION_REPEAT) {
124                         ix = svm_image_texture_wrap_periodic(ix, width);
125                         iy = svm_image_texture_wrap_periodic(iy, height);
126
127                         nix = svm_image_texture_wrap_periodic(ix+1, width);
128                         niy = svm_image_texture_wrap_periodic(iy+1, height);
129                 }
130                 else {
131                         if(extension == EXTENSION_CLIP) {
132                                 if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
133                                         return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
134                                 }
135                         }
136                         nix = svm_image_texture_wrap_clamp(ix+1, width);
137                         niy = svm_image_texture_wrap_clamp(iy+1, height);
138                         ix = svm_image_texture_wrap_clamp(ix, width);
139                         iy = svm_image_texture_wrap_clamp(iy, height);
140                 }
141
142                 r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + iy*width);
143                 r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width);
144                 r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width);
145                 r += ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width);
146         }
147         return r;
148 }
149
150
151 ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z)
152 {
153         uint4 info = kernel_tex_fetch(__tex_image_packed_info, id*2);
154         uint width = info.x;
155         uint height = info.y;
156         uint offset = info.z;
157         uint depth = kernel_tex_fetch(__tex_image_packed_info, id*2+1).x;
158         /* Decode image options. */
159         uint interpolation = kernel_decode_image_interpolation(info);
160         uint extension = kernel_decode_image_extension(info);
161         /* Actual sampling. */
162         float4 r;
163         int ix, iy, iz, nix, niy, niz;
164         if(interpolation == INTERPOLATION_CLOSEST) {
165                 svm_image_texture_frac(x*width, &ix);
166                 svm_image_texture_frac(y*height, &iy);
167                 svm_image_texture_frac(z*depth, &iz);
168
169                 if(extension == EXTENSION_REPEAT) {
170                         ix = svm_image_texture_wrap_periodic(ix, width);
171                         iy = svm_image_texture_wrap_periodic(iy, height);
172                         iz = svm_image_texture_wrap_periodic(iz, depth);
173                 }
174                 else {
175                         if(extension == EXTENSION_CLIP) {
176                                 if(x < 0.0f || y < 0.0f || z < 0.0f ||
177                                    x > 1.0f || y > 1.0f || z > 1.0f)
178                                 {
179                                         return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
180                                 }
181                         }
182                         /* Fall through. */
183                         /* EXTENSION_EXTEND */
184                         ix = svm_image_texture_wrap_clamp(ix, width);
185                         iy = svm_image_texture_wrap_clamp(iy, height);
186                         iz = svm_image_texture_wrap_clamp(iz, depth);
187                 }
188                 r = svm_image_texture_read(kg, id, offset + ix + iy*width + iz*width*height);
189         }
190         else { /* INTERPOLATION_LINEAR */
191                 float tx = svm_image_texture_frac(x*(float)width - 0.5f, &ix);
192                 float ty = svm_image_texture_frac(y*(float)height - 0.5f, &iy);
193                 float tz = svm_image_texture_frac(z*(float)depth - 0.5f, &iz);
194
195                 if(extension == EXTENSION_REPEAT) {
196                         ix = svm_image_texture_wrap_periodic(ix, width);
197                         iy = svm_image_texture_wrap_periodic(iy, height);
198                         iz = svm_image_texture_wrap_periodic(iz, depth);
199
200                         nix = svm_image_texture_wrap_periodic(ix+1, width);
201                         niy = svm_image_texture_wrap_periodic(iy+1, height);
202                         niz = svm_image_texture_wrap_periodic(iz+1, depth);
203                 }
204                 else {
205                         if(extension == EXTENSION_CLIP) {
206                                 if(x < 0.0f || y < 0.0f || z < 0.0f ||
207                                    x > 1.0f || y > 1.0f || z > 1.0f)
208                                 {
209                                         return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
210                                 }
211                         }
212                         /* Fall through. */
213                         /*  EXTENSION_EXTEND */
214                         nix = svm_image_texture_wrap_clamp(ix+1, width);
215                         niy = svm_image_texture_wrap_clamp(iy+1, height);
216                         niz = svm_image_texture_wrap_clamp(iz+1, depth);
217
218                         ix = svm_image_texture_wrap_clamp(ix, width);
219                         iy = svm_image_texture_wrap_clamp(iy, height);
220                         iz = svm_image_texture_wrap_clamp(iz, depth);
221                 }
222
223                 r  = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + iy*width + iz*width*height);
224                 r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width + iz*width*height);
225                 r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width + iz*width*height);
226                 r += (1.0f - tz)*ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width + iz*width*height);
227
228                 r += tz*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + iy*width + niz*width*height);
229                 r += tz*(1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width + niz*width*height);
230                 r += tz*ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width + niz*width*height);
231                 r += tz*ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width + niz*width*height);
232         }
233         return r;
234 }