Merging r57518 through r57545 from trunk into soc-20133-depsgraph_mt
[blender-staging.git] / intern / cycles / util / util_types.h
1 /*
2  * Copyright 2011, 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 #ifndef __UTIL_TYPES_H__
20 #define __UTIL_TYPES_H__
21
22 #ifndef __KERNEL_OPENCL__
23
24 #include <stdlib.h>
25
26 #endif
27
28 /* Qualifiers for kernel code shared by CPU and GPU */
29
30 #ifndef __KERNEL_GPU__
31
32 #define __device static inline
33 #define __device_noinline static
34 #define __global
35 #define __local
36 #define __shared
37 #define __constant
38
39 #if defined(_WIN32) && !defined(FREE_WINDOWS)
40 #define __device_inline static __forceinline
41 #define __align(...) __declspec(align(__VA_ARGS__))
42 #define __may_alias
43 #else
44 #define __device_inline static inline __attribute__((always_inline))
45 #ifndef FREE_WINDOWS64
46 #define __forceinline inline __attribute__((always_inline))
47 #endif
48 #define __align(...) __attribute__((aligned(__VA_ARGS__)))
49 #define __may_alias __attribute__((__may_alias__))
50 #endif
51
52 #endif
53
54 /* Bitness */
55
56 #if defined(__ppc64__) || defined(__PPC64__) || defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
57 #define __KERNEL_64_BIT__
58 #endif
59
60 /* SIMD Types */
61
62 #ifndef __KERNEL_GPU__
63
64 /* not enabled, globally applying it just gives slowdown,
65  * but useful for testing. */
66 //#define __KERNEL_SSE__
67 #ifdef __KERNEL_SSE__
68
69 #include <xmmintrin.h> /* SSE 1 */
70 #include <emmintrin.h> /* SSE 2 */
71 #include <pmmintrin.h> /* SSE 3 */
72 #include <tmmintrin.h> /* SSE 3 */
73 #include <smmintrin.h> /* SSE 4 */
74
75 #ifndef __KERNEL_SSE2__
76 #define __KERNEL_SSE2__
77 #endif
78
79 #ifndef __KERNEL_SSE3__
80 #define __KERNEL_SSE3__
81 #endif
82
83 #ifndef __KERNEL_SSE4__
84 #define __KERNEL_SSE4__
85 #endif
86
87 #else
88
89 #if defined(__x86_64__) || defined(__KERNEL_SSE3__)
90
91 /* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
92  * Since we can't avoid including <windows.h>, better only include that */
93 #ifdef FREE_WINDOWS64
94 #include <windows.h>
95 #else
96 #include <xmmintrin.h> /* SSE 1 */
97 #include <emmintrin.h> /* SSE 2 */
98
99 #ifdef __KERNEL_SSE3__
100 #include <pmmintrin.h> /* SSE 3 */
101 #include <tmmintrin.h> /* SSE 3 */
102 #endif
103 #endif
104
105 #ifndef __KERNEL_SSE2__
106 #define __KERNEL_SSE2__
107 #endif
108
109 #endif
110
111 #endif
112
113 #ifndef _WIN32
114
115 #include <stdint.h>
116
117 #endif
118
119 #endif
120
121 CCL_NAMESPACE_BEGIN
122
123 /* Types
124  *
125  * Define simpler unsigned type names, and integer with defined number of bits.
126  * Also vector types, named to be compatible with OpenCL builtin types, while
127  * working for CUDA and C++ too. */
128
129 /* Shorter Unsigned Names */
130
131 #ifndef __KERNEL_OPENCL__
132
133 typedef unsigned char uchar;
134 typedef unsigned int uint;
135
136 #endif
137
138 #ifndef __KERNEL_GPU__
139
140 /* Fixed Bits Types */
141
142 #ifdef _WIN32
143
144 typedef signed char int8_t;
145 typedef unsigned char uint8_t;
146
147 typedef signed short int16_t;
148 typedef unsigned short uint16_t;
149
150 typedef signed int int32_t;
151 typedef unsigned int uint32_t;
152
153 typedef long long int64_t;
154 typedef unsigned long long uint64_t;
155
156 #ifdef __KERNEL_64_BIT__
157 typedef int64_t ssize_t;
158 #else
159 typedef int32_t ssize_t;
160 #endif
161
162 #endif
163
164 /* Generic Memory Pointer */
165
166 typedef uint64_t device_ptr;
167
168 /* Vector Types */
169
170 struct uchar2 {
171         uchar x, y;
172
173         __forceinline uchar operator[](int i) const { return *(&x + i); }
174         __forceinline uchar& operator[](int i) { return *(&x + i); }
175 };
176
177 struct uchar3 {
178         uchar x, y, z;
179
180         __forceinline uchar operator[](int i) const { return *(&x + i); }
181         __forceinline uchar& operator[](int i) { return *(&x + i); }
182 };
183
184 struct uchar4 {
185         uchar x, y, z, w;
186
187         __forceinline uchar operator[](int i) const { return *(&x + i); }
188         __forceinline uchar& operator[](int i) { return *(&x + i); }
189 };
190
191 struct int2 {
192         int x, y;
193
194         __forceinline int operator[](int i) const { return *(&x + i); }
195         __forceinline int& operator[](int i) { return *(&x + i); }
196 };
197
198 #ifdef __KERNEL_SSE__
199 struct __align(16) int3 {
200         union {
201                 __m128i m128;
202                 struct { int x, y, z, w; };
203         };
204
205         __forceinline int3() {}
206         __forceinline int3(const __m128i a) : m128(a) {}
207         __forceinline operator const __m128i&(void) const { return m128; }
208         __forceinline operator __m128i&(void) { return m128; }
209 #else
210 struct int3 {
211         int x, y, z, w;
212 #endif
213
214         __forceinline int operator[](int i) const { return *(&x + i); }
215         __forceinline int& operator[](int i) { return *(&x + i); }
216 };
217
218 #ifdef __KERNEL_SSE__
219 struct __align(16) int4 {
220         union {
221                 __m128i m128;
222                 struct { int x, y, z, w; };
223         };
224
225         __forceinline int4() {}
226         __forceinline int4(const __m128i a) : m128(a) {}
227         __forceinline operator const __m128i&(void) const { return m128; }
228         __forceinline operator __m128i&(void) { return m128; }
229 #else
230 struct int4 {
231         int x, y, z, w;
232 #endif
233
234         __forceinline int operator[](int i) const { return *(&x + i); }
235         __forceinline int& operator[](int i) { return *(&x + i); }
236 };
237
238 struct uint2 {
239         uint x, y;
240
241         __forceinline uint operator[](uint i) const { return *(&x + i); }
242         __forceinline uint& operator[](uint i) { return *(&x + i); }
243 };
244
245 struct uint3 {
246         uint x, y, z;
247
248         __forceinline uint operator[](uint i) const { return *(&x + i); }
249         __forceinline uint& operator[](uint i) { return *(&x + i); }
250 };
251
252 struct uint4 {
253         uint x, y, z, w;
254
255         __forceinline uint operator[](uint i) const { return *(&x + i); }
256         __forceinline uint& operator[](uint i) { return *(&x + i); }
257 };
258
259 struct float2 {
260         float x, y;
261
262         __forceinline float operator[](int i) const { return *(&x + i); }
263         __forceinline float& operator[](int i) { return *(&x + i); }
264 };
265
266 #ifdef __KERNEL_SSE__
267 struct __align(16) float3 {
268         union {
269                 __m128 m128;
270                 struct { float x, y, z, w; };
271         };
272
273         __forceinline float3() {}
274         __forceinline float3(const __m128 a) : m128(a) {}
275         __forceinline operator const __m128&(void) const { return m128; }
276         __forceinline operator __m128&(void) { return m128; }
277 #else
278 struct float3 {
279         float x, y, z, w;
280 #endif
281
282         __forceinline float operator[](int i) const { return *(&x + i); }
283         __forceinline float& operator[](int i) { return *(&x + i); }
284 };
285
286 #ifdef __KERNEL_SSE__
287 struct __align(16) float4 {
288         union {
289                 __m128 m128;
290                 struct { float x, y, z, w; };
291         };
292
293         __forceinline float4() {}
294         __forceinline float4(const __m128 a) : m128(a) {}
295         __forceinline operator const __m128&(void) const { return m128; }
296         __forceinline operator __m128&(void) { return m128; }
297 #else
298 struct float4 {
299         float x, y, z, w;
300 #endif
301
302         __forceinline float operator[](int i) const { return *(&x + i); }
303         __forceinline float& operator[](int i) { return *(&x + i); }
304 };
305
306 #endif
307
308 #ifndef __KERNEL_GPU__
309
310 /* Vector Type Constructors
311  * 
312  * OpenCL does not support C++ class, so we use these instead. */
313
314 __device_inline uchar2 make_uchar2(uchar x, uchar y)
315 {
316         uchar2 a = {x, y};
317         return a;
318 }
319
320 __device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z)
321 {
322         uchar3 a = {x, y, z};
323         return a;
324 }
325
326 __device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w)
327 {
328         uchar4 a = {x, y, z, w};
329         return a;
330 }
331
332 __device_inline int2 make_int2(int x, int y)
333 {
334         int2 a = {x, y};
335         return a;
336 }
337
338 __device_inline int3 make_int3(int x, int y, int z)
339 {
340 #ifdef __KERNEL_SSE__
341         int3 a;
342         a.m128 = _mm_set_epi32(0, z, y, x);
343 #else
344         int3 a = {x, y, z, 0};
345 #endif
346
347         return a;
348 }
349
350 __device_inline int4 make_int4(int x, int y, int z, int w)
351 {
352 #ifdef __KERNEL_SSE__
353         int4 a;
354         a.m128 = _mm_set_epi32(w, z, y, x);
355 #else
356         int4 a = {x, y, z, w};
357 #endif
358
359         return a;
360 }
361
362 __device_inline uint2 make_uint2(uint x, uint y)
363 {
364         uint2 a = {x, y};
365         return a;
366 }
367
368 __device_inline uint3 make_uint3(uint x, uint y, uint z)
369 {
370         uint3 a = {x, y, z};
371         return a;
372 }
373
374 __device_inline uint4 make_uint4(uint x, uint y, uint z, uint w)
375 {
376         uint4 a = {x, y, z, w};
377         return a;
378 }
379
380 __device_inline float2 make_float2(float x, float y)
381 {
382         float2 a = {x, y};
383         return a;
384 }
385
386 __device_inline float3 make_float3(float x, float y, float z)
387 {
388 #ifdef __KERNEL_SSE__
389         float3 a;
390         a.m128 = _mm_set_ps(0.0f, z, y, x);
391 #else
392         float3 a = {x, y, z, 0.0f};
393 #endif
394
395         return a;
396 }
397
398 __device_inline float4 make_float4(float x, float y, float z, float w)
399 {
400 #ifdef __KERNEL_SSE__
401         float4 a;
402         a.m128 = _mm_set_ps(w, z, y, x);
403 #else
404         float4 a = {x, y, z, w};
405 #endif
406
407         return a;
408 }
409
410 __device_inline int align_up(int offset, int alignment)
411 {
412         return (offset + alignment - 1) & ~(alignment - 1);
413 }
414
415 __device_inline int3 make_int3(int i)
416 {
417 #ifdef __KERNEL_SSE__
418         int3 a;
419         a.m128 = _mm_set1_epi32(i);
420 #else
421         int3 a = {i, i, i, i};
422 #endif
423
424         return a;
425 }
426
427 __device_inline int4 make_int4(int i)
428 {
429 #ifdef __KERNEL_SSE__
430         int4 a;
431         a.m128 = _mm_set1_epi32(i);
432 #else
433         int4 a = {i, i, i, i};
434 #endif
435
436         return a;
437 }
438
439 __device_inline float3 make_float3(float f)
440 {
441 #ifdef __KERNEL_SSE__
442         float3 a;
443         a.m128 = _mm_set1_ps(f);
444 #else
445         float3 a = {f, f, f, f};
446 #endif
447
448         return a;
449 }
450
451 __device_inline float4 make_float4(float f)
452 {
453 #ifdef __KERNEL_SSE__
454         float4 a;
455         a.m128 = _mm_set1_ps(f);
456 #else
457         float4 a = {f, f, f, f};
458 #endif
459
460         return a;
461 }
462
463 __device_inline float4 make_float4(const int4& i)
464 {
465 #ifdef __KERNEL_SSE__
466         float4 a;
467         a.m128 = _mm_cvtepi32_ps(i.m128);
468 #else
469         float4 a = {(float)i.x, (float)i.y, (float)i.z, (float)i.w};
470 #endif
471
472         return a;
473 }
474
475 __device_inline int4 make_int4(const float3& f)
476 {
477 #ifdef __KERNEL_SSE__
478         int4 a;
479         a.m128 = _mm_cvtps_epi32(f.m128);
480 #else
481         int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w};
482 #endif
483
484         return a;
485 }
486
487 #endif
488
489 #ifdef __KERNEL_SSE3__
490
491 /* SSE shuffle utility functions */
492
493 __device_inline const __m128 shuffle8(const __m128& a, const __m128i& shuf)
494 {
495         return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
496 }
497
498 template<size_t i0, size_t i1, size_t i2, size_t i3> __device_inline const __m128 shuffle(const __m128& a, const __m128& b)
499 {
500         return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
501 }
502
503 template<size_t i0, size_t i1, size_t i2, size_t i3> __device_inline const __m128 shuffle(const __m128& b)
504 {
505         return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
506 }
507 #endif
508
509 #if defined(__KERNEL_SSE2__) && defined(_MSC_VER)
510
511 /* count zeros from start or end of integer bits */
512
513 __device_inline uint32_t __builtin_ctz(uint32_t i)
514 {
515         unsigned long r = 0;
516         _BitScanForward(&r, i);
517         return (uint32_t)r;
518 }
519
520 __device_inline uint32_t __builtin_clz(uint32_t i)
521 {
522         unsigned long r = 0;
523         _BitScanReverse(&r, i);
524         return (uint32_t)r;
525 }
526
527 #endif
528
529 CCL_NAMESPACE_END
530
531 #endif /* __UTIL_TYPES_H__ */
532