Support for detecting AVX and AVX2 ISA

This commit is contained in:
Jack Andersen 2017-12-26 14:47:31 -10:00
parent f0df551237
commit 439da78fa6
2 changed files with 55 additions and 3 deletions

View File

@ -29,10 +29,26 @@
namespace zeus namespace zeus
{ {
#if MSVC
#if defined(_M_X86)
#define ZEUS_ARCH_X86 1
#elif defined(_M_X86_64)
#define ZEUS_ARCH_X86_64 1
#endif
#else
#if defined(__i386__)
#define ZEUS_ARCH_X86 1
#elif defined(__x86_64__)
#define ZEUS_ARCH_X86_64 1
#endif
#endif
struct CPUInfo struct CPUInfo
{ {
const char cpuBrand[48] = {0}; const char cpuBrand[48] = {0};
const char cpuVendor[32] = {0}; const char cpuVendor[32] = {0};
#if ZEUS_ARCH_X86_64 || ZEUS_ARCH_X86
const bool isIntel = false; const bool isIntel = false;
const bool SSE1 = false; const bool SSE1 = false;
const bool SSE2 = false; const bool SSE2 = false;
@ -42,6 +58,9 @@ struct CPUInfo
const bool SSE42 = false; const bool SSE42 = false;
const bool SSE4a = false; const bool SSE4a = false;
const bool AESNI = false; const bool AESNI = false;
const bool AVX = false;
const bool AVX2 = false;
#endif
}; };
/** /**
* Detects CPU capabilities and returns true if SSE4.1 or SSE4.2 is available * Detects CPU capabilities and returns true if SSE4.1 or SSE4.2 is available
@ -49,6 +68,9 @@ struct CPUInfo
void detectCPU(); void detectCPU();
const CPUInfo& cpuFeatures(); const CPUInfo& cpuFeatures();
std::pair<bool, const CPUInfo&> validateCPU(); std::pair<bool, const CPUInfo&> validateCPU();
void getCpuInfo(int eax, int regs[4]);
void getCpuInfoEx(int eax, int ecx, int regs[4]);
class CVector3f; class CVector3f;
class CVector2f; class CVector2f;
class CTransform; class CTransform;

View File

@ -15,13 +15,24 @@ static bool isCPUInit = false;
static CPUInfo g_cpuFeatures = {}; static CPUInfo g_cpuFeatures = {};
static CPUInfo g_missingFeatures = {}; static CPUInfo g_missingFeatures = {};
void getCpuInfo(int level, int regs[4]) void getCpuInfo(int eax, int regs[4])
{ {
#if !GEKKO #if !GEKKO
#if _WIN32 #if _WIN32
__cpuid(regs, level); __cpuid(regs, eax);
#else #else
__cpuid(level, regs[0], regs[1], regs[2], regs[3]); __cpuid(eax, regs[0], regs[1], regs[2], regs[3]);
#endif
#endif
}
void getCpuInfoEx(int eax, int ecx, int regs[4])
{
#if !GEKKO
#if _WIN32
__cpuidex(regs, eax, ecx);
#else
__cpuid_count(eax, ecx, regs[0], regs[1], regs[2], regs[3]);
#endif #endif
#endif #endif
} }
@ -62,6 +73,11 @@ void detectCPU()
memset((bool*)&g_cpuFeatures.SSSE3, ((regs[2] & 0x00000200) != 0), 1); memset((bool*)&g_cpuFeatures.SSSE3, ((regs[2] & 0x00000200) != 0), 1);
memset((bool*)&g_cpuFeatures.SSE41, ((regs[2] & 0x00080000) != 0), 1); memset((bool*)&g_cpuFeatures.SSE41, ((regs[2] & 0x00080000) != 0), 1);
memset((bool*)&g_cpuFeatures.SSE42, ((regs[2] & 0x00100000) != 0), 1); memset((bool*)&g_cpuFeatures.SSE42, ((regs[2] & 0x00100000) != 0), 1);
memset((bool*)&g_cpuFeatures.AVX, ((regs[2] & 0x10000000) != 0), 1);
getCpuInfoEx(7, 0, regs);
memset((bool*)&g_cpuFeatures.AVX2, ((regs[1] & 0x00000020) != 0), 1);
isCPUInit = true; isCPUInit = true;
#endif #endif
@ -74,6 +90,20 @@ std::pair<bool, const CPUInfo&> validateCPU()
detectCPU(); detectCPU();
bool ret = true; bool ret = true;
#if __AVX2__
if (!g_cpuFeatures.AVX2)
{
*(bool*) &g_missingFeatures.AVX2 = true;
ret = false;
}
#endif
#if __AVX__
if (!g_cpuFeatures.AVX)
{
*(bool*) &g_missingFeatures.AVX = true;
ret = false;
}
#endif
#if __SSE4A__ #if __SSE4A__
if (!g_cpuFeatures.SSE4a) if (!g_cpuFeatures.SSE4a)
{ {