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
{
#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
{
const char cpuBrand[48] = {0};
const char cpuVendor[32] = {0};
#if ZEUS_ARCH_X86_64 || ZEUS_ARCH_X86
const bool isIntel = false;
const bool SSE1 = false;
const bool SSE2 = false;
@ -42,6 +58,9 @@ struct CPUInfo
const bool SSE42 = false;
const bool SSE4a = 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
@ -49,6 +68,9 @@ struct CPUInfo
void detectCPU();
const CPUInfo& cpuFeatures();
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 CVector2f;
class CTransform;

View File

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