platform.h 14 KB

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