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