diff options
-rw-r--r-- | Alc/ALc.c | 1 | ||||
-rw-r--r-- | Alc/helpers.c | 55 | ||||
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 11 | ||||
-rw-r--r-- | config.h.in | 3 |
5 files changed, 71 insertions, 0 deletions
@@ -790,6 +790,7 @@ static void alc_initconfig(void) ReadALConfig(); + FillCPUCaps(); InitHrtf(); #ifdef _WIN32 diff --git a/Alc/helpers.c b/Alc/helpers.c index 009e83d2..6051573e 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -27,6 +27,9 @@ #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif +#ifdef HAVE_CPUID_H +#include <cpuid.h> +#endif #if defined(HAVE_GUIDDEF_H) || defined(HAVE_INITGUID_H) #define INITGUID @@ -57,6 +60,58 @@ DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, #include "alMain.h" +ALuint CPUCapFlags = 0; + + +void FillCPUCaps(void) +{ +#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) +/* FIXME: We really should get this for all available CPUs in case different + * CPUs have different caps (is that possible on one machine?). */ +#ifdef HAVE_CPUID_H + union { + unsigned int regs[4]; + char str[sizeof(unsigned int[4])]; + } cpuinf[3]; + + if(!__get_cpuid(0, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3])) + ERR("Failed to get CPUID\n"); + else + { + TRACE("Vendor ID: \"%.4s%.4s%.4s\"\n", cpuinf[0].str+4, cpuinf[0].str+12, cpuinf[0].str+8); + if(__get_cpuid(0x80000002, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]) && + __get_cpuid(0x80000003, &cpuinf[1].regs[0], &cpuinf[1].regs[1], &cpuinf[1].regs[2], &cpuinf[1].regs[3]) && + __get_cpuid(0x80000004, &cpuinf[2].regs[0], &cpuinf[2].regs[1], &cpuinf[2].regs[2], &cpuinf[2].regs[3])) + TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str); + + if(!__get_cpuid(1, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3])) + ERR("Failed to get CPU features\n"); + else + { +#ifdef bit_MMX + if((cpuinf[0].regs[3]&bit_MMX)) + CPUCapFlags |= CPU_CAP_MMX; +#endif +#ifdef bit_SSE + if((cpuinf[0].regs[3]&bit_SSE)) + CPUCapFlags |= CPU_CAP_SSE; +#endif + } + } +#endif +#endif +#ifdef HAVE_ARM_NEON_H + /* Assume Neon support if compiled with it */ + CPUCapFlags |= CPU_CAP_NEON; +#endif + + TRACE("Got caps:%s%s%s%s\n", ((CPUCapFlags&CPU_CAP_MMX)?" MMX":""), + ((CPUCapFlags&CPU_CAP_SSE)?" SSE":""), + ((CPUCapFlags&CPU_CAP_NEON)?" Neon":""), + ((!CPUCapFlags)?" (none)":"")); +} + + #ifdef _WIN32 void pthread_once(pthread_once_t *once, void (*callback)(void)) { diff --git a/CMakeLists.txt b/CMakeLists.txt index 2262e87c..96dd4347 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -226,6 +226,7 @@ IF(NOT HAVE_GUIDDEF_H) CHECK_INCLUDE_FILE(initguid.h HAVE_INITGUID_H) ENDIF() CHECK_INCLUDE_FILE(arm_neon.h HAVE_ARM_NEON_H) +CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H) # Some systems need libm for some of the following math functions to work CHECK_LIBRARY_EXISTS(m pow "" HAVE_LIBM) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 296461c0..1f73ad72 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -762,6 +762,17 @@ extern enum LogLevel LogLevel; extern ALint RTPrioLevel; + +extern ALuint CPUCapFlags; +enum { + CPU_CAP_MMX = 1<<0, + CPU_CAP_SSE = 1<<1, + CPU_CAP_NEON = 1<<3, +}; + +void FillCPUCaps(void); + + /** * Starts a try block. Must not be nested within another try block within the * same function. diff --git a/config.h.in b/config.h.in index 54bc9672..82b6c334 100644 --- a/config.h.in +++ b/config.h.in @@ -107,6 +107,9 @@ /* Define if we have arm_neon.h */ #cmakedefine HAVE_ARM_NEON_H +/* Define if we have cpuid.h */ +#cmakedefine HAVE_CPUID_H + /* Define if we have guiddef.h */ #cmakedefine HAVE_GUIDDEF_H |