ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / svm / svm_noise.h
1 /*
2  * Adapted from Open Shading Language with this license:
3  *
4  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5  * All Rights Reserved.
6  *
7  * Modifications Copyright 2011, Blender Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  * * Redistributions of source code must retain the above copyright
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in the
16  *   documentation and/or other materials provided with the distribution.
17  * * Neither the name of Sony Pictures Imageworks nor the names of its
18  *   contributors may be used to endorse or promote products derived from
19  *   this software without specific prior written permission.
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 CCL_NAMESPACE_BEGIN
34
35 #ifdef __KERNEL_SSE2__
36 ccl_device_inline ssei quick_floor_sse(const ssef &x)
37 {
38   ssei b = truncatei(x);
39   ssei isneg = cast((x < ssef(0.0f)).m128);
40   return b + isneg;  // unsaturated add 0xffffffff is the same as subtract -1
41 }
42 #endif
43
44 ccl_device uint hash(uint kx, uint ky, uint kz)
45 {
46   // define some handy macros
47 #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
48 #define final(a, b, c) \
49   { \
50     c ^= b; \
51     c -= rot(b, 14); \
52     a ^= c; \
53     a -= rot(c, 11); \
54     b ^= a; \
55     b -= rot(a, 25); \
56     c ^= b; \
57     c -= rot(b, 16); \
58     a ^= c; \
59     a -= rot(c, 4); \
60     b ^= a; \
61     b -= rot(a, 14); \
62     c ^= b; \
63     c -= rot(b, 24); \
64   }
65   // now hash the data!
66   uint a, b, c, len = 3;
67   a = b = c = 0xdeadbeef + (len << 2) + 13;
68
69   c += kz;
70   b += ky;
71   a += kx;
72   final(a, b, c);
73
74   return c;
75   // macros not needed anymore
76 #undef rot
77 #undef final
78 }
79
80 #ifdef __KERNEL_SSE2__
81 ccl_device_inline ssei hash_sse(const ssei &kx, const ssei &ky, const ssei &kz)
82 {
83 #  define rot(x, k) (((x) << (k)) | (srl(x, 32 - (k))))
84 #  define xor_rot(a, b, c) \
85     do { \
86       a = a ^ b; \
87       a = a - rot(b, c); \
88     } while (0)
89
90   uint len = 3;
91   ssei magic = ssei(0xdeadbeef + (len << 2) + 13);
92   ssei a = magic + kx;
93   ssei b = magic + ky;
94   ssei c = magic + kz;
95
96   xor_rot(c, b, 14);
97   xor_rot(a, c, 11);
98   xor_rot(b, a, 25);
99   xor_rot(c, b, 16);
100   xor_rot(a, c, 4);
101   xor_rot(b, a, 14);
102   xor_rot(c, b, 24);
103
104   return c;
105 #  undef rot
106 #  undef xor_rot
107 }
108 #endif
109
110 #if 0  // unused
111 ccl_device int imod(int a, int b)
112 {
113   a %= b;
114   return a < 0 ? a + b : a;
115 }
116
117 ccl_device uint phash(int kx, int ky, int kz, int3 p)
118 {
119   return hash(imod(kx, p.x), imod(ky, p.y), imod(kz, p.z));
120 }
121 #endif
122
123 #ifndef __KERNEL_SSE2__
124 ccl_device float floorfrac(float x, int *i)
125 {
126   *i = quick_floor_to_int(x);
127   return x - *i;
128 }
129 #else
130 ccl_device_inline ssef floorfrac_sse(const ssef &x, ssei *i)
131 {
132   *i = quick_floor_sse(x);
133   return x - ssef(*i);
134 }
135 #endif
136
137 #ifndef __KERNEL_SSE2__
138 ccl_device float fade(float t)
139 {
140   return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
141 }
142 #else
143 ccl_device_inline ssef fade_sse(const ssef *t)
144 {
145   ssef a = madd(*t, ssef(6.0f), ssef(-15.0f));
146   ssef b = madd(*t, a, ssef(10.0f));
147   return ((*t) * (*t)) * ((*t) * b);
148 }
149 #endif
150
151 #ifndef __KERNEL_SSE2__
152 ccl_device float nerp(float t, float a, float b)
153 {
154   return (1.0f - t) * a + t * b;
155 }
156 #else
157 ccl_device_inline ssef nerp_sse(const ssef &t, const ssef &a, const ssef &b)
158 {
159   ssef x1 = (ssef(1.0f) - t) * a;
160   return madd(t, b, x1);
161 }
162 #endif
163
164 #ifndef __KERNEL_SSE2__
165 ccl_device float grad(int hash, float x, float y, float z)
166 {
167   // use vectors pointing to the edges of the cube
168   int h = hash & 15;
169   float u = h < 8 ? x : y;
170   float vt = ((h == 12) | (h == 14)) ? x : z;
171   float v = h < 4 ? y : vt;
172   return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
173 }
174 #else
175 ccl_device_inline ssef grad_sse(const ssei &hash, const ssef &x, const ssef &y, const ssef &z)
176 {
177   ssei c1 = ssei(1);
178   ssei c2 = ssei(2);
179
180   ssei h = hash & ssei(15);  // h = hash & 15
181
182   sseb case_ux = h < ssei(8);  // 0xffffffff if h < 8 else 0
183
184   ssef u = select(case_ux, x, y);  // u = h<8 ? x : y
185
186   sseb case_vy = h < ssei(4);  // 0xffffffff if h < 4 else 0
187
188   sseb case_h12 = h == ssei(12);  // 0xffffffff if h == 12 else 0
189   sseb case_h14 = h == ssei(14);  // 0xffffffff if h == 14 else 0
190
191   sseb case_vx = case_h12 | case_h14;  // 0xffffffff if h == 12 or h == 14 else 0
192
193   ssef v = select(case_vy, y, select(case_vx, x, z));  // v = h<4 ? y : h == 12 || h == 14 ? x : z
194
195   ssei case_uneg = (h & c1) << 31;        // 1<<31 if h&1 else 0
196   ssef case_uneg_mask = cast(case_uneg);  // -0.0 if h&1 else +0.0
197   ssef ru = u ^ case_uneg_mask;           // -u if h&1 else u (copy float sign)
198
199   ssei case_vneg = (h & c2) << 30;        // 2<<30 if h&2 else 0
200   ssef case_vneg_mask = cast(case_vneg);  // -0.0 if h&2 else +0.0
201   ssef rv = v ^ case_vneg_mask;           // -v if h&2 else v (copy float sign)
202
203   ssef r = ru + rv;  // ((h&1) ? -u : u) + ((h&2) ? -v : v)
204   return r;
205 }
206 #endif
207
208 #ifndef __KERNEL_SSE2__
209 ccl_device float scale3(float result)
210 {
211   return 0.9820f * result;
212 }
213 #else
214 ccl_device_inline ssef scale3_sse(const ssef &result)
215 {
216   return ssef(0.9820f) * result;
217 }
218 #endif
219
220 #ifndef __KERNEL_SSE2__
221 ccl_device_noinline float perlin(float x, float y, float z)
222 {
223   int X;
224   float fx = floorfrac(x, &X);
225   int Y;
226   float fy = floorfrac(y, &Y);
227   int Z;
228   float fz = floorfrac(z, &Z);
229
230   float u = fade(fx);
231   float v = fade(fy);
232   float w = fade(fz);
233
234   float result;
235
236   result = nerp(
237       w,
238       nerp(v,
239            nerp(u, grad(hash(X, Y, Z), fx, fy, fz), grad(hash(X + 1, Y, Z), fx - 1.0f, fy, fz)),
240            nerp(u,
241                 grad(hash(X, Y + 1, Z), fx, fy - 1.0f, fz),
242                 grad(hash(X + 1, Y + 1, Z), fx - 1.0f, fy - 1.0f, fz))),
243       nerp(v,
244            nerp(u,
245                 grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0f),
246                 grad(hash(X + 1, Y, Z + 1), fx - 1.0f, fy, fz - 1.0f)),
247            nerp(u,
248                 grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0f, fz - 1.0f),
249                 grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0f, fy - 1.0f, fz - 1.0f))));
250   float r = scale3(result);
251
252   /* can happen for big coordinates, things even out to 0.0 then anyway */
253   return (isfinite(r)) ? r : 0.0f;
254 }
255 #else
256 ccl_device_noinline float perlin(float x, float y, float z)
257 {
258   ssef xyz = ssef(x, y, z, 0.0f);
259   ssei XYZ;
260
261   ssef fxyz = floorfrac_sse(xyz, &XYZ);
262
263   ssef uvw = fade_sse(&fxyz);
264   ssef u = shuffle<0>(uvw), v = shuffle<1>(uvw), w = shuffle<2>(uvw);
265
266   ssei XYZ_ofc = XYZ + ssei(1);
267   ssei vdy = shuffle<1, 1, 1, 1>(XYZ, XYZ_ofc);                       // +0, +0, +1, +1
268   ssei vdz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ_ofc));  // +0, +1, +0, +1
269
270   ssei h1 = hash_sse(shuffle<0>(XYZ), vdy, vdz);      // hash directions 000, 001, 010, 011
271   ssei h2 = hash_sse(shuffle<0>(XYZ_ofc), vdy, vdz);  // hash directions 100, 101, 110, 111
272
273   ssef fxyz_ofc = fxyz - ssef(1.0f);
274   ssef vfy = shuffle<1, 1, 1, 1>(fxyz, fxyz_ofc);
275   ssef vfz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz_ofc));
276
277   ssef g1 = grad_sse(h1, shuffle<0>(fxyz), vfy, vfz);
278   ssef g2 = grad_sse(h2, shuffle<0>(fxyz_ofc), vfy, vfz);
279   ssef n1 = nerp_sse(u, g1, g2);
280
281   ssef n1_half = shuffle<2, 3, 2, 3>(n1);  // extract 2 floats to a separate vector
282   ssef n2 = nerp_sse(
283       v, n1, n1_half);  // process nerp([a, b, _, _], [c, d, _, _]) -> [a', b', _, _]
284
285   ssef n2_second = shuffle<1>(n2);  // extract b to a separate vector
286   ssef result = nerp_sse(
287       w, n2, n2_second);  // process nerp([a', _, _, _], [b', _, _, _]) -> [a'', _, _, _]
288
289   ssef r = scale3_sse(result);
290
291   ssef infmask = cast(ssei(0x7f800000));
292   ssef rinfmask = ((r & infmask) == infmask).m128;  // 0xffffffff if r is inf/-inf/nan else 0
293   ssef rfinite = andnot(rinfmask, r);               // 0 if r is inf/-inf/nan else r
294   return extract<0>(rfinite);
295 }
296 #endif
297
298 /* perlin noise in range 0..1 */
299 ccl_device float noise(float3 p)
300 {
301   float r = perlin(p.x, p.y, p.z);
302   return 0.5f * r + 0.5f;
303 }
304
305 /* perlin noise in range -1..1 */
306 ccl_device float snoise(float3 p)
307 {
308   return perlin(p.x, p.y, p.z);
309 }
310
311 /* cell noise */
312 ccl_device float cellnoise(float3 p)
313 {
314   int3 ip = quick_floor_to_int3(p);
315   return bits_to_01(hash(ip.x, ip.y, ip.z));
316 }
317
318 ccl_device float3 cellnoise3(float3 p)
319 {
320   int3 ip = quick_floor_to_int3(p);
321 #ifndef __KERNEL_SSE__
322   float r = bits_to_01(hash(ip.x, ip.y, ip.z));
323   float g = bits_to_01(hash(ip.y, ip.x, ip.z));
324   float b = bits_to_01(hash(ip.y, ip.z, ip.x));
325   return make_float3(r, g, b);
326 #else
327   ssei ip_yxz = shuffle<1, 0, 2, 3>(ssei(ip.m128));
328   ssei ip_xyy = shuffle<0, 1, 1, 3>(ssei(ip.m128));
329   ssei ip_zzx = shuffle<2, 2, 0, 3>(ssei(ip.m128));
330   ssei bits = hash_sse(ip_xyy, ip_yxz, ip_zzx);
331   return float3(uint32_to_float(bits) * ssef(1.0f / (float)0xFFFFFFFF));
332 #endif
333 }
334
335 CCL_NAMESPACE_END