platform.h 14 KB

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