add BLI_strcpy_rlen, replace strcat, which was used in misleading way.
[blender.git] / intern / cycles / kernel / kernel_jitter.h
1 /*
2  * Copyright 2013, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 CCL_NAMESPACE_BEGIN
20
21 /* "Correlated Multi-Jittered Sampling"
22  * Andrew Kensler, Pixar Technical Memo 13-01, 2013 */
23
24 /* todo: find good value, suggested 64 gives pattern on cornell box ceiling */
25 #define CMJ_RANDOM_OFFSET_LIMIT 4096
26
27 __device_inline bool cmj_is_pow2(int i)
28 {
29         return (i & (i - 1)) == 0;
30 }
31
32 __device_inline int cmj_fast_mod_pow2(int a, int b)
33 {
34         return (a & (b - 1));
35 }
36
37 /* a must be > 0 and b must be > 1 */
38 __device_inline int cmj_fast_div_pow2(int a, int b)
39 {
40 #ifdef __KERNEL_SSE2__
41         return a >> __builtin_ctz(b);
42 #else
43         return a/b;
44 #endif
45 }
46
47 __device_inline uint cmj_w_mask(uint w)
48 {
49 #ifdef __KERNEL_SSE2__
50         return ((1 << (32 - __builtin_clz(w))) - 1);
51 #else
52         w |= w >> 1;
53         w |= w >> 2;
54         w |= w >> 4;
55         w |= w >> 8;
56         w |= w >> 16;
57
58         return w;
59 #endif
60 }
61
62 __device_inline uint cmj_permute(uint i, uint l, uint p)
63 {
64         uint w = l - 1;
65
66         if((l & w) == 0) {
67                 /* l is a power of two (fast) */
68                 i ^= p;
69                 i *= 0xe170893d;
70                 i ^= p >> 16;
71                 i ^= (i & w) >> 4;
72                 i ^= p >> 8;
73                 i *= 0x0929eb3f;
74                 i ^= p >> 23;
75                 i ^= (i & w) >> 1;
76                 i *= 1 | p >> 27;
77                 i *= 0x6935fa69;
78                 i ^= (i & w) >> 11;
79                 i *= 0x74dcb303;
80                 i ^= (i & w) >> 2;
81                 i *= 0x9e501cc3;
82                 i ^= (i & w) >> 2;
83                 i *= 0xc860a3df;
84                 i &= w;
85                 i ^= i >> 5;
86
87                 return (i + p) & w;
88         }
89         else {
90                 /* l is not a power of two (slow) */
91                 w = cmj_w_mask(w);
92
93                 do {
94                         i ^= p;
95                         i *= 0xe170893d;
96                         i ^= p >> 16;
97                         i ^= (i & w) >> 4;
98                         i ^= p >> 8;
99                         i *= 0x0929eb3f;
100                         i ^= p >> 23;
101                         i ^= (i & w) >> 1;
102                         i *= 1 | p >> 27;
103                         i *= 0x6935fa69;
104                         i ^= (i & w) >> 11;
105                         i *= 0x74dcb303;
106                         i ^= (i & w) >> 2;
107                         i *= 0x9e501cc3;
108                         i ^= (i & w) >> 2;
109                         i *= 0xc860a3df;
110                         i &= w;
111                         i ^= i >> 5;
112                 } while (i >= l);
113
114                 return (i + p) % l;
115         }
116 }
117
118 __device_inline uint cmj_hash(uint i, uint p)
119 {
120         i ^= p;
121         i ^= i >> 17;
122         i ^= i >> 10;
123         i *= 0xb36534e5;
124         i ^= i >> 12;
125         i ^= i >> 21;
126         i *= 0x93fc4795;
127         i ^= 0xdf6e307f;
128         i ^= i >> 17;
129         i *= 1 | p >> 18;
130
131         return i;
132 }
133
134 __device_inline float cmj_randfloat(uint i, uint p)
135 {
136         return cmj_hash(i, p) * (1.0f / 4294967808.0f);
137 }
138
139 #ifdef __CMJ__
140 __device_noinline float cmj_sample_1D(int s, int N, int p)
141 {
142         uint x = cmj_permute(s, N, p * 0x68bc21eb);
143         float jx = cmj_randfloat(s, p * 0x967a889b);
144
145         float invN = 1.0f/N;
146         return (x + jx)*invN;
147 }
148
149 __device_noinline void cmj_sample_2D(int s, int N, int p, float *fx, float *fy)
150 {
151         int m = float_to_int(sqrtf(N));
152         int n = (N + m - 1)/m;
153         float invN = 1.0f/N;
154         float invm = 1.0f/m;
155         float invn = 1.0f/n;
156
157         s = cmj_permute(s, N, p * 0x51633e2d);
158
159         int sdivm, smodm;
160
161         if(cmj_is_pow2(m)) {
162                 sdivm = cmj_fast_div_pow2(s, m);
163                 smodm = cmj_fast_mod_pow2(s, m);
164         }
165         else {
166                 sdivm = float_to_int(s * invm);
167                 smodm = s - sdivm*m;
168         }
169
170         uint sx = cmj_permute(smodm, m, p * 0x68bc21eb);
171         uint sy = cmj_permute(sdivm, n, p * 0x02e5be93);
172
173         float jx = cmj_randfloat(s, p * 0x967a889b);
174         float jy = cmj_randfloat(s, p * 0x368cc8b7);
175
176         *fx = (sx + (sy + jx)*invn)*invm;
177         *fy = (s + jy)*invN;
178 }
179 #endif
180
181 CCL_NAMESPACE_END
182