summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/Android.mk2
-rw-r--r--src/gallium/auxiliary/util/u_cpu_detect.c43
-rw-r--r--src/gallium/auxiliary/util/u_cpu_detect.h1
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;