diff --git a/Engine/Utils/Perfs.hpp b/Engine/Utils/Perfs.hpp index 2436b59..937c070 100644 --- a/Engine/Utils/Perfs.hpp +++ b/Engine/Utils/Perfs.hpp @@ -1,6 +1,84 @@ #pragma once #include +#include + +#ifndef __cplusplus +#error This header requires C++ +#endif + +// +// CPU related functions +// +inline bool PerfsCPUSIMDReady(void) noexcept { +#if !defined(DISABLE_INTRINSICS) + int CPUInfo[4] = {-1}; + +#if defined(__GNUC__) + __cpuid(0, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); +#else + __cpuid(CPUInfo, 0); +#endif + +#ifdef __AVX2__ + if (CPUInfo[0] < 7) + return false; +#else + if (CPUInfo[0] < 1) + return false; +#endif + +#if defined(__GNUC__) + __cpuid(1, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); +#else + __cpuid(CPUInfo, 1); +#endif + +#if defined(__AVX2__) || defined(AVX2_INTRINSICS) + // The compiler can emit FMA3 instructions even without explicit intrinsics use + if ((CPUInfo[2] & 0x38081001) != 0x38081001) + return false; // No F16C/AVX/OSXSAVE/SSE4.1/FMA3/SSE3 support +#elif defined(FMA3_INTRINSICS) && defined(F16C_INTRINSICS) + if ((CPUInfo[2] & 0x38081001) != 0x38081001) + return false; // No F16C/AVX/OSXSAVE/SSE4.1/FMA3/SSE3 support +#elif defined(FMA3_INTRINSICS) + if ((CPUInfo[2] & 0x18081001) != 0x18081001) + return false; // No AVX/OSXSAVE/SSE4.1/FMA3/SSE3 support +#elif defined(F16C_INTRINSICS) + if ((CPUInfo[2] & 0x38080001) != 0x38080001) + return false; // No F16C/AVX/OSXSAVE/SSE4.1/SSE3 support +#elif defined(__AVX__) || defined(AVX_INTRINSICS) + if ((CPUInfo[2] & 0x18080001) != 0x18080001) + return false; // No AVX/OSXSAVE/SSE4.1/SSE3 support +#elif defined(SSE4_INTRINSICS) + if ((CPUInfo[2] & 0x80001) != 0x80001) + return false; // No SSE3/SSE4.1 support +#elif defined(SSE3_INTRINSICS) + if (!(CPUInfo[2] & 0x1)) + return false; // No SSE3 support +#endif + + // The x64 processor model requires SSE2 support, but no harm in checking + if ((CPUInfo[3] & 0x6000000) != 0x6000000) + return false; // No SSE2/SSE support + +#if defined(__AVX2__) || defined(AVX2_INTRINSICS) +#if defined(__GNUC__) + __cpuid_count(7, 0, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); +#else + __cpuidex(CPUInfo, 7, 0); +#endif + if (!(CPUInfo[1] & 0x20)) + return false; // No AVX2 support +#endif + return true; +#endif + return true; +} + +// +// RAM related functions +// const size_t PerfsGetVirtMem(void); const size_t PerfsGetPhysMem(void); diff --git a/conanfile.py b/conanfile.py index 4a3cff3..b8e1af8 100644 --- a/conanfile.py +++ b/conanfile.py @@ -34,7 +34,7 @@ class ProtoTank(ConanFile): self.options["sfml"].shared = True def requirements(self): - self.requires("sfml/2.6.1") + self.requires("sfml/[~2.6]") # def layout(self): # cmake_layout(self)