1 // Copyright 2009-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #define _CRT_SECURE_NO_WARNINGS
7 
8 #include <cstddef>
9 #include <cassert>
10 #include <cstdlib>
11 #include <cstdio>
12 #include <memory>
13 #include <stdexcept>
14 #include <iostream>
15 #include <iomanip>
16 #include <fstream>
17 #include <string>
18 #include <cstring>
19 #include <stdint.h>
20 #include <functional>
21 
22 ////////////////////////////////////////////////////////////////////////////////
23 /// detect platform
24 ////////////////////////////////////////////////////////////////////////////////
25 
26 /* detect 32 or 64 Intel platform */
27 #if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
28 #define __X86_64__
29 #define __X86_ASM__
30 #elif defined(__i386__) || defined(_M_IX86)
31 #define __X86_ASM__
32 #endif
33 
34 /* detect 64 bit platform */
35 #if defined(__X86_64__) || defined(__aarch64__)
36 #define __64BIT__
37 #endif
38 
39 /* detect Linux platform */
40 #if defined(linux) || defined(__linux__) || defined(__LINUX__)
41 #  if !defined(__LINUX__)
42 #     define __LINUX__
43 #  endif
44 #  if !defined(__UNIX__)
45 #     define __UNIX__
46 #  endif
47 #endif
48 
49 /* detect DragonFly platform */
50 #if defined(__DragonFly__) || defined(__DRAGONFLY__)
51 #  if !defined(__DRAGONFLY__)
52 #     define __DRAGONFLY__
53 #  endif
54 #  if !defined(__UNIX__)
55 #     define __UNIX__
56 #  endif
57 #endif
58 
59 /* detect FreeBSD platform */
60 #if defined(__FreeBSD__) || defined(__FREEBSD__)
61 #  if !defined(__FREEBSD__)
62 #     define __FREEBSD__
63 #  endif
64 #  if !defined(__UNIX__)
65 #     define __UNIX__
66 #  endif
67 #endif
68 
69 /* detect Windows 95/98/NT/2000/XP/Vista/7/8/10 platform */
70 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(__CYGWIN__)
71 #  if !defined(__WIN32__)
72 #     define __WIN32__
73 #  endif
74 #endif
75 
76 /* detect Cygwin platform */
77 #if defined(__CYGWIN__)
78 #  if !defined(__UNIX__)
79 #     define __UNIX__
80 #  endif
81 #endif
82 
83 /* detect MAC OS X platform */
84 #if defined(__APPLE__) || defined(MACOSX) || defined(__MACOSX__)
85 #  if !defined(__MACOSX__)
86 #     define __MACOSX__
87 #  endif
88 #  if !defined(__UNIX__)
89 #     define __UNIX__
90 #  endif
91 #endif
92 
93 /* try to detect other Unix systems */
94 #if defined(__unix__) || defined (unix) || defined(__unix) || defined(_unix)
95 #  if !defined(__UNIX__)
96 #     define __UNIX__
97 #  endif
98 #endif
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Macros
102 ////////////////////////////////////////////////////////////////////////////////
103 
104 #ifdef __WIN32__
105 #define dll_export __declspec(dllexport)
106 #define dll_import __declspec(dllimport)
107 #else
108 #define dll_export __attribute__ ((visibility ("default")))
109 #define dll_import
110 #endif
111 
112 #ifdef __WIN32__
113 #if !defined(__noinline)
114 #define __noinline             __declspec(noinline)
115 #endif
116 //#define __forceinline        __forceinline
117 //#define __restrict           __restrict
118 #if defined(__INTEL_COMPILER)
119 #define __restrict__           __restrict
120 #else
121 #define __restrict__           //__restrict // causes issues with MSVC
122 #endif
123 #if !defined(__thread)
124 #define __thread               __declspec(thread)
125 #endif
126 #if !defined(__aligned)
127 #define __aligned(...)           __declspec(align(__VA_ARGS__))
128 #endif
129 //#define __FUNCTION__           __FUNCTION__
130 #define debugbreak()           __debugbreak()
131 
132 #else
133 #if !defined(__noinline)
134 #define __noinline             __attribute__((noinline))
135 #endif
136 #if !defined(__forceinline)
137 #define __forceinline          inline __attribute__((always_inline))
138 #endif
139 //#define __restrict             __restrict
140 //#define __thread               __thread
141 #if !defined(__aligned)
142 #define __aligned(...)           __attribute__((aligned(__VA_ARGS__)))
143 #endif
144 #if !defined(__FUNCTION__)
145 #define __FUNCTION__           __PRETTY_FUNCTION__
146 #endif
147 #define debugbreak()           asm ("int $3")
148 #endif
149 
150 #if defined(__clang__) || defined(__GNUC__)
151   #define MAYBE_UNUSED __attribute__((unused))
152 #else
153   #define MAYBE_UNUSED
154 #endif
155 
156 #if defined(_MSC_VER) && (_MSC_VER < 1900) // before VS2015 deleted functions are not supported properly
157   #define DELETED
158 #else
159   #define DELETED  = delete
160 #endif
161 
162 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
163 #define   likely(expr) (expr)
164 #define unlikely(expr) (expr)
165 #else
166 #define   likely(expr) __builtin_expect((bool)(expr),true )
167 #define unlikely(expr) __builtin_expect((bool)(expr),false)
168 #endif
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// Error handling and debugging
172 ////////////////////////////////////////////////////////////////////////////////
173 
174 /* debug printing macros */
175 #define STRING(x) #x
176 #define TOSTRING(x) STRING(x)
177 #define PING embree_cout << __FILE__ << " (" << __LINE__ << "): " << __FUNCTION__ << embree_endl
178 #define PRINT(x) embree_cout << STRING(x) << " = " << (x) << embree_endl
179 #define PRINT2(x,y) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << embree_endl
180 #define PRINT3(x,y,z) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << embree_endl
181 #define PRINT4(x,y,z,w) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << embree_endl
182 
183 #if defined(DEBUG) // only report file and line in debug mode
184   #define THROW_RUNTIME_ERROR(str) \
185     throw std::runtime_error(std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str));
186 #else
187   #define THROW_RUNTIME_ERROR(str) \
188     throw std::runtime_error(str);
189 #endif
190 
191 #define FATAL(x)   THROW_RUNTIME_ERROR(x)
192 #define WARNING(x) { std::cerr << "Warning: " << x << embree_endl << std::flush; }
193 
194 #define NOT_IMPLEMENTED FATAL(std::string(__FUNCTION__) + " not implemented")
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Basic types
198 ////////////////////////////////////////////////////////////////////////////////
199 
200 /* default floating-point type */
201 namespace embree {
202   typedef float real;
203 }
204 
205 /* windows does not have ssize_t */
206 #if defined(__WIN32__)
207 #if defined(__64BIT__)
208 typedef int64_t ssize_t;
209 #else
210 typedef int32_t ssize_t;
211 #endif
212 #endif
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 /// Basic utility functions
216 ////////////////////////////////////////////////////////////////////////////////
217 
toString(long long value)218 __forceinline std::string toString(long long value) {
219   return std::to_string(value);
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// Disable some compiler warnings
224 ////////////////////////////////////////////////////////////////////////////////
225 
226 #if defined(__INTEL_COMPILER)
227 //#pragma warning(disable:265 ) // floating-point operation result is out of range
228 //#pragma warning(disable:383 ) // value copied to temporary, reference to temporary used
229 //#pragma warning(disable:869 ) // parameter was never referenced
230 //#pragma warning(disable:981 ) // operands are evaluated in unspecified order
231 //#pragma warning(disable:1418) // external function definition with no prior declaration
232 //#pragma warning(disable:1419) // external declaration in primary source file
233 //#pragma warning(disable:1572) // floating-point equality and inequality comparisons are unreliable
234 //#pragma warning(disable:94  ) // the size of an array must be greater than zero
235 //#pragma warning(disable:1599) // declaration hides parameter
236 //#pragma warning(disable:424 ) // extra ";" ignored
237 #pragma warning(disable:2196) // routine is both "inline" and "noinline"
238 //#pragma warning(disable:177 ) // label was declared but never referenced
239 //#pragma warning(disable:114 ) // function was referenced but not defined
240 //#pragma warning(disable:819 ) // template nesting depth does not match the previous declaration of function
241 #pragma warning(disable:15335)  // was not vectorized: vectorization possible but seems inefficient
242 #endif
243 
244 #if defined(_MSC_VER)
245 //#pragma warning(disable:4200) // nonstandard extension used : zero-sized array in struct/union
246 #pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning)
247 //#pragma warning(disable:4267) // '=' : conversion from 'size_t' to 'unsigned long', possible loss of data
248 #pragma warning(disable:4244) // 'argument' : conversion from 'ssize_t' to 'unsigned int', possible loss of data
249 //#pragma warning(disable:4355) // 'this' : used in base member initializer list
250 //#pragma warning(disable:391 ) // '<=' : signed / unsigned mismatch
251 //#pragma warning(disable:4018) // '<' : signed / unsigned mismatch
252 //#pragma warning(disable:4305) // 'initializing' : truncation from 'double' to 'float'
253 //#pragma warning(disable:4068) // unknown pragma
254 //#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned
255 //#pragma warning(disable:4838) // conversion from 'unsigned int' to 'const int' requires a narrowing conversion)
256 //#pragma warning(disable:4227) // anachronism used : qualifiers on reference are ignored
257 #pragma warning(disable:4503) // decorated name length exceeded, name was truncated
258 #pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
259 #pragma warning(disable:4258) // definition from the for loop is ignored; the definition from the enclosing scope is used
260 
261 #  if _MSC_VER < 1910 // prior to Visual studio 2017 (V141)
262 #    pragma warning(disable:4101) // warning C4101: 'x': unreferenced local variable // a compiler bug issues wrong warnings
263 #    pragma warning(disable:4789) // buffer '' of size 8 bytes will be overrun; 32 bytes will be written starting at offset 0
264 #  endif
265 
266 #endif
267 
268 #if defined(__clang__) && !defined(__INTEL_COMPILER)
269 //#pragma clang diagnostic ignored "-Wunknown-pragmas"
270 //#pragma clang diagnostic ignored "-Wunused-variable"
271 //#pragma clang diagnostic ignored "-Wreorder"
272 //#pragma clang diagnostic ignored "-Wmicrosoft"
273 //#pragma clang diagnostic ignored "-Wunused-private-field"
274 //#pragma clang diagnostic ignored "-Wunused-local-typedef"
275 //#pragma clang diagnostic ignored "-Wunused-function"
276 //#pragma clang diagnostic ignored "-Wnarrowing"
277 //#pragma clang diagnostic ignored "-Wc++11-narrowing"
278 //#pragma clang diagnostic ignored "-Wdeprecated-register"
279 //#pragma clang diagnostic ignored "-Wdeprecated-declarations"
280 #endif
281 
282 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
283 #pragma GCC diagnostic ignored "-Wpragmas"
284 //#pragma GCC diagnostic ignored "-Wnarrowing"
285 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
286 //#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
287 //#pragma GCC diagnostic ignored "-Warray-bounds"
288 #pragma GCC diagnostic ignored "-Wattributes"
289 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
290 #pragma GCC diagnostic ignored "-Wsign-compare"
291 #pragma GCC diagnostic ignored "-Wparentheses"
292 #endif
293 
294 #if defined(__clang__) && defined(__WIN32__)
295 #pragma clang diagnostic ignored "-Wunused-parameter"
296 #pragma clang diagnostic ignored "-Wmicrosoft-cast"
297 #pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
298 #pragma clang diagnostic ignored "-Wmicrosoft-include"
299 #pragma clang diagnostic ignored "-Wunused-function"
300 #pragma clang diagnostic ignored "-Wunknown-pragmas"
301 #endif
302 
303 /* disabling deprecated warning, please use only where use of deprecated Embree API functions is desired */
304 #if defined(__WIN32__) && defined(__INTEL_COMPILER)
305 #define DISABLE_DEPRECATED_WARNING __pragma(warning (disable: 1478)) // warning: function was declared deprecated
306 #define ENABLE_DEPRECATED_WARNING  __pragma(warning (enable:  1478)) // warning: function was declared deprecated
307 #elif defined(__INTEL_COMPILER)
308 #define DISABLE_DEPRECATED_WARNING _Pragma("warning (disable: 1478)") // warning: function was declared deprecated
309 #define ENABLE_DEPRECATED_WARNING  _Pragma("warning (enable : 1478)") // warning: function was declared deprecated
310 #elif defined(__clang__)
311 #define DISABLE_DEPRECATED_WARNING _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") // warning: xxx is deprecated
312 #define ENABLE_DEPRECATED_WARNING  _Pragma("clang diagnostic warning \"-Wdeprecated-declarations\"") // warning: xxx is deprecated
313 #elif defined(__GNUC__)
314 #define DISABLE_DEPRECATED_WARNING _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") // warning: xxx is deprecated
315 #define ENABLE_DEPRECATED_WARNING  _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"") // warning: xxx is deprecated
316 #elif defined(_MSC_VER)
317 #define DISABLE_DEPRECATED_WARNING __pragma(warning (disable: 4996)) // warning: function was declared deprecated
318 #define ENABLE_DEPRECATED_WARNING  __pragma(warning (enable : 4996)) // warning: function was declared deprecated
319 #endif
320 
321 /* embree output stream */
322 #define embree_ostream std::ostream&
323 #define embree_cout std::cout
324 #define embree_cout_uniform std::cout
325 #define embree_endl std::endl
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Some macros for static profiling
329 ////////////////////////////////////////////////////////////////////////////////
330 
331 #if defined (__GNUC__)
332 #define IACA_SSC_MARK( MARK_ID )						\
333 __asm__ __volatile__ (									\
334 					  "\n\t  movl $"#MARK_ID", %%ebx"	\
335 					  "\n\t  .byte 0x64, 0x67, 0x90"	\
336 					  : : : "memory" );
337 
338 #define IACA_UD_BYTES __asm__ __volatile__ ("\n\t .byte 0x0F, 0x0B");
339 
340 #else
341 #define IACA_UD_BYTES {__asm _emit 0x0F \
342 	__asm _emit 0x0B}
343 
344 #define IACA_SSC_MARK(x) {__asm  mov ebx, x\
345 	__asm  _emit 0x64 \
346 	__asm  _emit 0x67 \
347 	__asm  _emit 0x90 }
348 
349 #define IACA_VC64_START __writegsbyte(111, 111);
350 #define IACA_VC64_END   __writegsbyte(222, 222);
351 
352 #endif
353 
354 #define IACA_START {IACA_UD_BYTES \
355 					IACA_SSC_MARK(111)}
356 #define IACA_END {IACA_SSC_MARK(222) \
357 					IACA_UD_BYTES}
358 
359 namespace embree
360 {
361   template<typename Closure>
362     struct OnScopeExitHelper
363   {
OnScopeExitHelperOnScopeExitHelper364     OnScopeExitHelper (const Closure f) : active(true), f(f) {}
~OnScopeExitHelperOnScopeExitHelper365     ~OnScopeExitHelper() { if (active) f(); }
deactivateOnScopeExitHelper366     void deactivate() { active = false; }
367     bool active;
368     const Closure f;
369   };
370 
371   template <typename Closure>
OnScopeExit(const Closure f)372     OnScopeExitHelper<Closure> OnScopeExit(const Closure f) {
373     return OnScopeExitHelper<Closure>(f);
374   }
375 
376 #define STRING_JOIN2(arg1, arg2) DO_STRING_JOIN2(arg1, arg2)
377 #define DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2
378 #define ON_SCOPE_EXIT(code)                                             \
379   auto STRING_JOIN2(on_scope_exit_, __LINE__) = OnScopeExit([&](){code;})
380 
381   template<typename Ty>
make_unique(Ty * ptr)382     std::unique_ptr<Ty> make_unique(Ty* ptr) {
383     return std::unique_ptr<Ty>(ptr);
384   }
385 
386 }
387