FFmpeg
cpu.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/cpu.h"
20 #include "libavutil/cpu_internal.h"
21 #include "config.h"
22 
23 #if (defined(__linux__) || defined(__ANDROID__)) && HAVE_GETAUXVAL && HAVE_ASM_HWCAP_H
24 #include <stdint.h>
25 #include <asm/hwcap.h>
26 #include <sys/auxv.h>
27 
28 #define get_cpu_feature_reg(reg, val) \
29  __asm__("mrs %0, " #reg : "=r" (val))
30 
31 static int detect_flags(void)
32 {
33  int flags = 0;
34  unsigned long hwcap;
35 
36  hwcap = getauxval(AT_HWCAP);
37 
38 #if defined(HWCAP_CPUID)
39  // We can check for DOTPROD and I8MM using HWCAP_ASIMDDP and
40  // HWCAP2_I8MM too, avoiding to read the CPUID registers (which triggers
41  // a trap, handled by the kernel). However the HWCAP_* defines for these
42  // extensions are added much later than HWCAP_CPUID, so the userland
43  // headers might lack support for them even if the binary later is run
44  // on hardware that does support it (and where the kernel might support
45  // HWCAP_CPUID).
46  // See https://www.kernel.org/doc/html/latest/arm64/cpu-feature-registers.html
47  if (hwcap & HWCAP_CPUID) {
48  uint64_t tmp;
49 
50  get_cpu_feature_reg(ID_AA64ISAR0_EL1, tmp);
51  if (((tmp >> 44) & 0xf) == 0x1)
53  get_cpu_feature_reg(ID_AA64ISAR1_EL1, tmp);
54  if (((tmp >> 52) & 0xf) == 0x1)
56  }
57 #else
58  (void)hwcap;
59 #endif
60 
61  return flags;
62 }
63 
64 #elif defined(__APPLE__) && HAVE_SYSCTLBYNAME
65 #include <sys/sysctl.h>
66 
67 static int detect_flags(void)
68 {
69  uint32_t value = 0;
70  size_t size;
71  int flags = 0;
72 
73  size = sizeof(value);
74  if (!sysctlbyname("hw.optional.arm.FEAT_DotProd", &value, &size, NULL, 0)) {
75  if (value)
77  }
78  size = sizeof(value);
79  if (!sysctlbyname("hw.optional.arm.FEAT_I8MM", &value, &size, NULL, 0)) {
80  if (value)
82  }
83  return flags;
84 }
85 
86 #elif defined(_WIN32)
87 #include <windows.h>
88 
89 static int detect_flags(void)
90 {
91  int flags = 0;
92 #ifdef PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE
93  if (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE))
95 #endif
96  return flags;
97 }
98 #else
99 
100 static int detect_flags(void)
101 {
102  return 0;
103 }
104 
105 #endif
106 
108 {
109  int flags = AV_CPU_FLAG_ARMV8 * HAVE_ARMV8 |
110  AV_CPU_FLAG_NEON * HAVE_NEON |
111  AV_CPU_FLAG_VFP * HAVE_VFP;
112 
113 #ifdef __ARM_FEATURE_DOTPROD
115 #endif
116 #ifdef __ARM_FEATURE_MATMUL_INT8
118 #endif
119 
120  flags |= detect_flags();
121 
122  return flags;
123 }
124 
126 {
127  int flags = av_get_cpu_flags();
128 
129  if (flags & AV_CPU_FLAG_NEON)
130  return 16;
131 
132  return 8;
133 }
AV_CPU_FLAG_VFP
#define AV_CPU_FLAG_VFP
Definition: cpu.h:67
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
AV_CPU_FLAG_DOTPROD
#define AV_CPU_FLAG_DOTPROD
Definition: cpu.h:72
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:103
cpu_internal.h
ff_get_cpu_max_align_aarch64
size_t ff_get_cpu_max_align_aarch64(void)
Definition: cpu.c:125
NULL
#define NULL
Definition: coverity.c:32
ff_get_cpu_flags_aarch64
int ff_get_cpu_flags_aarch64(void)
Definition: cpu.c:107
detect_flags
static int detect_flags(void)
Definition: cpu.c:100
AV_CPU_FLAG_I8MM
#define AV_CPU_FLAG_I8MM
Definition: cpu.h:73
cpu.h
AV_CPU_FLAG_NEON
#define AV_CPU_FLAG_NEON
Definition: cpu.h:69
size
int size
Definition: twinvq_data.h:10344
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:664
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
AV_CPU_FLAG_ARMV8
#define AV_CPU_FLAG_ARMV8
Definition: cpu.h:70
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561