btCpuFeatureUtility.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #ifndef BT_CPU_UTILITY_H
  2. #define BT_CPU_UTILITY_H
  3. #include "LinearMath/btScalar.h"
  4. #include <string.h> //memset
  5. #ifdef USE_SIMD
  6. #include <emmintrin.h>
  7. #ifdef BT_ALLOW_SSE4
  8. #include <intrin.h>
  9. #endif //BT_ALLOW_SSE4
  10. #endif //USE_SIMD
  11. #if defined BT_USE_NEON
  12. #define ARM_NEON_GCC_COMPATIBILITY 1
  13. #include <arm_neon.h>
  14. #include <sys/types.h>
  15. #include <sys/sysctl.h> //for sysctlbyname
  16. #endif //BT_USE_NEON
  17. ///Rudimentary btCpuFeatureUtility for CPU features: only report the features that Bullet actually uses (SSE4/FMA3, NEON_HPFP)
  18. ///We assume SSE2 in case BT_USE_SSE2 is defined in LinearMath/btScalar.h
  19. class btCpuFeatureUtility
  20. {
  21. public:
  22. enum btCpuFeature
  23. {
  24. CPU_FEATURE_FMA3 = 1,
  25. CPU_FEATURE_SSE4_1 = 2,
  26. CPU_FEATURE_NEON_HPFP = 4
  27. };
  28. static int getCpuFeatures()
  29. {
  30. static int capabilities = 0;
  31. static bool testedCapabilities = false;
  32. if (0 != testedCapabilities)
  33. {
  34. return capabilities;
  35. }
  36. #ifdef BT_USE_NEON
  37. {
  38. uint32_t hasFeature = 0;
  39. size_t featureSize = sizeof(hasFeature);
  40. int err = sysctlbyname("hw.optional.neon_hpfp", &hasFeature, &featureSize, NULL, 0);
  41. if (0 == err && hasFeature)
  42. capabilities |= CPU_FEATURE_NEON_HPFP;
  43. }
  44. #endif //BT_USE_NEON
  45. #ifdef BT_ALLOW_SSE4
  46. {
  47. int cpuInfo[4];
  48. memset(cpuInfo, 0, sizeof(cpuInfo));
  49. unsigned long long sseExt = 0;
  50. __cpuid(cpuInfo, 1);
  51. bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false;
  52. bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false;
  53. if (osUsesXSAVE_XRSTORE && cpuAVXSuport)
  54. {
  55. sseExt = _xgetbv(0);
  56. }
  57. const int OSXSAVEFlag = (1UL << 27);
  58. const int AVXFlag = ((1UL << 28) | OSXSAVEFlag);
  59. const int FMAFlag = ((1UL << 12) | AVXFlag | OSXSAVEFlag);
  60. if ((cpuInfo[2] & FMAFlag) == FMAFlag && (sseExt & 6) == 6)
  61. {
  62. capabilities |= btCpuFeatureUtility::CPU_FEATURE_FMA3;
  63. }
  64. const int SSE41Flag = (1 << 19);
  65. if (cpuInfo[2] & SSE41Flag)
  66. {
  67. capabilities |= btCpuFeatureUtility::CPU_FEATURE_SSE4_1;
  68. }
  69. }
  70. #endif //BT_ALLOW_SSE4
  71. testedCapabilities = true;
  72. return capabilities;
  73. }
  74. };
  75. #endif //BT_CPU_UTILITY_H