diff options
author | Eric Anholt <[email protected]> | 2017-04-13 11:43:30 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2017-05-02 13:35:23 -0700 |
commit | 463b7d0332c59d7115642c9922915d097535b4d9 (patch) | |
tree | 97664a34bd2538a43c6f9e7abc4995df1adc1052 /src/gallium/auxiliary | |
parent | 3c730639740f9b1243e95d06e6608cb54649be9a (diff) |
gallium: Enable ARM NEON CPU detection.
I wrote this code with reference to pixman, though I've only decided to
cover Linux (what I'm testing) and Android (seems obvious enough). Linux
has getauxval() as a cleaner interface to the /proc entry, but it's more
glibc-specific and I didn't want to add detection for that.
This will be used to enable NEON at runtime on ARMv6 builds of vc4.
v2: Actually initialize the temp vars in the Android path (noticed by
daniels)
v3: Actually pull in the cpufeatures library (change by robher).
Use O_CLOEXEC. Break out of the loop when we find our feature.
v4: Drop VFP code, which was confused about what it was detecting and not
actually used yet.
Reviewed-by: Grazvydas Ignotas <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/Android.mk | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_cpu_detect.c | 43 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_cpu_detect.h | 1 |
3 files changed, 46 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/Android.mk b/src/gallium/auxiliary/Android.mk index e8628e43744..4f6f71bbf6a 100644 --- a/src/gallium/auxiliary/Android.mk +++ b/src/gallium/auxiliary/Android.mk @@ -48,6 +48,8 @@ endif LOCAL_MODULE := libmesa_gallium LOCAL_STATIC_LIBRARIES += libmesa_nir +LOCAL_WHOLE_STATIC_LIBRARIES += cpufeatures + # generate sources LOCAL_MODULE_CLASS := STATIC_LIBRARIES intermediates := $(call local-generated-sources-dir) diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c index 845fc6b34d5..76115bf8d55 100644 --- a/src/gallium/auxiliary/util/u_cpu_detect.c +++ b/src/gallium/auxiliary/util/u_cpu_detect.c @@ -59,12 +59,18 @@ #if defined(PIPE_OS_LINUX) #include <signal.h> +#include <fcntl.h> +#include <elf.h> #endif #ifdef PIPE_OS_UNIX #include <unistd.h> #endif +#if defined(PIPE_OS_ANDROID) +#include <cpu-features.h> +#endif + #if defined(PIPE_OS_WINDOWS) #include <windows.h> #if defined(PIPE_CC_MSVC) @@ -294,6 +300,38 @@ PIPE_ALIGN_STACK static inline boolean sse2_has_daz(void) #endif /* X86 or X86_64 */ +#if defined(PIPE_ARCH_ARM) +static void +check_os_arm_support(void) +{ +#if defined(PIPE_OS_ANDROID) + AndroidCpuFamily cpu_family = android_getCpuFamily(); + uint64_t cpu_features = android_getCpuFeatures(); + + if (cpu_family == ANDROID_CPU_FAMILY_ARM) { + if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) + util_cpu_caps.has_neon = 1; + } +#elif defined(PIPE_OS_LINUX) + Elf32_auxv_t aux; + int fd; + + fd = open("/proc/self/auxv", O_RDONLY | O_CLOEXEC); + if (fd >= 0) { + while (read(fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) { + if (aux.a_type == AT_HWCAP) { + uint32_t hwcap = aux.a_un.a_val; + + util_cpu_caps.has_neon = (hwcap >> 12) & 1; + break; + } + } + close (fd); + } +#endif /* PIPE_OS_LINUX */ +} +#endif /* PIPE_ARCH_ARM */ + void util_cpu_detect(void) { @@ -443,6 +481,10 @@ util_cpu_detect(void) } #endif /* PIPE_ARCH_X86 || PIPE_ARCH_X86_64 */ +#if defined(PIPE_ARCH_ARM) + check_os_arm_support(); +#endif + #if defined(PIPE_ARCH_PPC) check_os_altivec_support(); #endif /* PIPE_ARCH_PPC */ @@ -471,6 +513,7 @@ util_cpu_detect(void) debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); debug_printf("util_cpu_caps.has_xop = %u\n", util_cpu_caps.has_xop); debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); + debug_printf("util_cpu_caps.has_neon = %u\n", util_cpu_caps.has_neon); debug_printf("util_cpu_caps.has_daz = %u\n", util_cpu_caps.has_daz); debug_printf("util_cpu_caps.has_avx512f = %u\n", util_cpu_caps.has_avx512f); debug_printf("util_cpu_caps.has_avx512dq = %u\n", util_cpu_caps.has_avx512dq); diff --git a/src/gallium/auxiliary/util/u_cpu_detect.h b/src/gallium/auxiliary/util/u_cpu_detect.h index 3bd7294f075..4a34ac4d9a6 100644 --- a/src/gallium/auxiliary/util/u_cpu_detect.h +++ b/src/gallium/auxiliary/util/u_cpu_detect.h @@ -72,6 +72,7 @@ struct util_cpu_caps { unsigned has_xop:1; unsigned has_altivec:1; unsigned has_daz:1; + unsigned has_neon:1; unsigned has_avx512f:1; unsigned has_avx512dq:1; |