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 */
206namespace embree {
207 typedef float real;
208}
209
210/* windows does not have ssize_t */
211#if defined(__WIN32__)
212#if defined(__64BIT__)
213typedef int64_t ssize_t;
214#else
215typedef 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
365namespace 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