[FFmpeg-devel] [PATCH v2 1/3] configure: Add wasm as a fake arch

Zhao Zhili quinkblack at foxmail.com
Wed Nov 20 14:44:59 EET 2024


From: Zhao Zhili <zhilizhao at tencent.com>

And add wasm simd128 flag, so we can add simd128 optimizations.
It can be enabled by put -msimd128 to extra cflags. There is
no runtime detection on simd128 support yet. I think that needs to
be done with JavaScript.
---
 Makefile                 |  3 ++-
 configure                | 16 +++++++++++++++
 ffbuild/arch.mak         |  2 ++
 libavutil/cpu.c          |  6 ++++++
 libavutil/cpu.h          |  3 +++
 libavutil/cpu_internal.h |  2 ++
 libavutil/tests/cpu.c    |  2 ++
 libavutil/wasm/Makefile  |  1 +
 libavutil/wasm/cpu.c     | 42 ++++++++++++++++++++++++++++++++++++++++
 9 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 libavutil/wasm/Makefile
 create mode 100644 libavutil/wasm/cpu.c

diff --git a/Makefile b/Makefile
index b350d7748f..e2250f6bc6 100644
--- a/Makefile
+++ b/Makefile
@@ -104,7 +104,8 @@ SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS               \
                ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS                \
                MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS         \
                MMI-OBJS LSX-OBJS LASX-OBJS RV-OBJS RVV-OBJS RVVB-OBJS    \
-               OBJS SLIBOBJS SHLIBOBJS STLIBOBJS HOSTOBJS TESTOBJS
+               OBJS SLIBOBJS SHLIBOBJS STLIBOBJS HOSTOBJS TESTOBJS       \
+               SIMD128-OBJS
 
 define RESET
 $(1) :=
diff --git a/configure b/configure
index 5dd7964fdf..f99ca9d9c9 100755
--- a/configure
+++ b/configure
@@ -480,6 +480,7 @@ Optimization options (experts only):
   --disable-lasx           disable Loongson LASX optimizations
   --disable-rvv            disable RISC-V Vector optimizations
   --disable-fast-unaligned consider unaligned accesses slow
+  --disable-simd128        disable WebAssembly simd128 optimizations
 
 Developer options (useful when working on FFmpeg itself):
   --disable-debug          disable debugging symbols
@@ -2149,6 +2150,7 @@ ARCH_LIST="
     sparc64
     tilegx
     tilepro
+    wasm
     x86
     x86_32
     x86_64
@@ -2189,6 +2191,10 @@ ARCH_EXT_LIST_LOONGSON="
     lasx
 "
 
+ARCH_EXT_LIST_WASM="
+    simd128
+"
+
 ARCH_EXT_LIST_X86_SIMD="
     aesni
     amd3dnow
@@ -2235,6 +2241,7 @@ ARCH_EXT_LIST="
     $ARCH_EXT_LIST_ARM
     $ARCH_EXT_LIST_PPC
     $ARCH_EXT_LIST_RISCV
+    $ARCH_EXT_LIST_WASM
     $ARCH_EXT_LIST_X86
     $ARCH_EXT_LIST_MIPS
     $ARCH_EXT_LIST_LOONGSON
@@ -2792,6 +2799,8 @@ mipsdsp_deps="mips"
 mipsdspr2_deps="mips"
 msa_deps="mipsfpu"
 
+simd128_deps="wasm"
+
 x86_64_select="i686"
 x86_64_suggest="fast_cmov"
 
@@ -5291,6 +5300,9 @@ case "$arch" in
     tilegx|tile-gx)
         arch="tilegx"
     ;;
+    wasm*)
+        arch="wasm"
+    ;;
     i[3-6]86*|i86pc|BePC|x86pc|x86_64|x86_32|amd64)
         arch="x86"
     ;;
@@ -6405,6 +6417,10 @@ elif enabled riscv; then
     enabled rv_zicbop && check_inline_asm rv_zicbop '".option arch, +zicbop\nprefetch.r 64(a0)"'
     enabled rv_zvbb && check_inline_asm rv_zvbb '".option arch, +zvbb\nvclz.v v0, v8"'
 
+elif enabled wasm; then
+
+    enabled simd128 && check_cc simd128 wasm_simd128.h  "v128_t v = wasm_v128_load(0);"
+
 elif enabled x86; then
 
     check_builtin rdtsc    intrin.h   "__rdtsc()"
diff --git a/ffbuild/arch.mak b/ffbuild/arch.mak
index af71aacfd2..197e30bb89 100644
--- a/ffbuild/arch.mak
+++ b/ffbuild/arch.mak
@@ -21,5 +21,7 @@ OBJS-$(HAVE_RV)      += $(RV-OBJS)      $(RV-OBJS-yes)
 OBJS-$(HAVE_RVV)     += $(RVV-OBJS)     $(RVV-OBJS-yes)
 OBJS-$(HAVE_RV_ZVBB) += $(RVVB-OBJS)    $(RVVB-OBJS-yes)
 
+OBJS-$(HAVE_SIMD128) += $(SIMD128-OBJS) $(SIMD128-OBJS-yes)
+
 OBJS-$(HAVE_MMX)     += $(MMX-OBJS)     $(MMX-OBJS-yes)
 OBJS-$(HAVE_X86ASM)  += $(X86ASM-OBJS)  $(X86ASM-OBJS-yes)
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index f1184192be..6a6ec31eff 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -68,6 +68,8 @@ static int get_cpu_flags(void)
     return ff_get_cpu_flags_ppc();
 #elif ARCH_RISCV
     return ff_get_cpu_flags_riscv();
+#elif ARCH_WASM
+    return ff_get_cpu_flags_wasm();
 #elif ARCH_X86
     return ff_get_cpu_flags_x86();
 #elif ARCH_LOONGARCH
@@ -200,6 +202,8 @@ int av_parse_cpu_caps(unsigned *flags, const char *s)
         { "zbb",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVB_BASIC },   .unit = "flags" },
         { "zvbb",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RV_ZVBB },   .unit = "flags" },
         { "misaligned", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RV_MISALIGNED },   .unit = "flags" },
+#elif ARCH_WASM
+        { "simd128",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SIMD128  },    .unit = "flags" },
 #endif
         { NULL },
     };
@@ -283,6 +287,8 @@ size_t av_cpu_max_align(void)
     return ff_get_cpu_max_align_arm();
 #elif ARCH_PPC
     return ff_get_cpu_max_align_ppc();
+#elif ARCH_WASM
+    return ff_get_cpu_max_align_wasm();
 #elif ARCH_X86
     return ff_get_cpu_max_align_x86();
 #elif ARCH_LOONGARCH
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 6b6e50f07a..5ef5da58eb 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -101,6 +101,9 @@
 #define AV_CPU_FLAG_RV_MISALIGNED (1 <<10) ///< Fast misaligned accesses
 #define AV_CPU_FLAG_RVB          (1 <<11) ///< B (bit manipulations)
 
+// WASM extensions
+#define AV_CPU_FLAG_SIMD128      (1 << 0)
+
 /**
  * Return the flags which specify extensions supported by the CPU.
  * The returned value is affected by av_force_cpu_flags() if that was used
diff --git a/libavutil/cpu_internal.h b/libavutil/cpu_internal.h
index 585a115c49..8dca62334a 100644
--- a/libavutil/cpu_internal.h
+++ b/libavutil/cpu_internal.h
@@ -49,6 +49,7 @@ int ff_get_cpu_flags_aarch64(void);
 int ff_get_cpu_flags_arm(void);
 int ff_get_cpu_flags_ppc(void);
 int ff_get_cpu_flags_riscv(void);
+int ff_get_cpu_flags_wasm(void);
 int ff_get_cpu_flags_x86(void);
 int ff_get_cpu_flags_loongarch(void);
 
@@ -56,6 +57,7 @@ size_t ff_get_cpu_max_align_mips(void);
 size_t ff_get_cpu_max_align_aarch64(void);
 size_t ff_get_cpu_max_align_arm(void);
 size_t ff_get_cpu_max_align_ppc(void);
+size_t ff_get_cpu_max_align_wasm(void);
 size_t ff_get_cpu_max_align_x86(void);
 size_t ff_get_cpu_max_align_loongarch(void);
 
diff --git a/libavutil/tests/cpu.c b/libavutil/tests/cpu.c
index 1eb3055ff0..fd2e32901d 100644
--- a/libavutil/tests/cpu.c
+++ b/libavutil/tests/cpu.c
@@ -104,6 +104,8 @@ static const struct {
     { AV_CPU_FLAG_RVV_F64,   "zve64d"     },
     { AV_CPU_FLAG_RV_ZVBB,   "zvbb"       },
     { AV_CPU_FLAG_RV_MISALIGNED, "misaligned" },
+#elif ARCH_WASM
+    { AV_CPU_FLAG_SIMD128,   "simd128"    },
 #endif
     { 0 }
 };
diff --git a/libavutil/wasm/Makefile b/libavutil/wasm/Makefile
new file mode 100644
index 0000000000..4ba2450cc8
--- /dev/null
+++ b/libavutil/wasm/Makefile
@@ -0,0 +1 @@
+OBJS += wasm/cpu.o
diff --git a/libavutil/wasm/cpu.c b/libavutil/wasm/cpu.c
new file mode 100644
index 0000000000..a8e990dd29
--- /dev/null
+++ b/libavutil/wasm/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024 Zhao Zhili
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/cpu_internal.h"
+
+int ff_get_cpu_flags_wasm(void)
+{
+    int flags = 0;
+#if HAVE_SIMD128
+    flags |= AV_CPU_FLAG_SIMD128;
+#endif
+    return flags;
+}
+
+size_t ff_get_cpu_max_align_wasm(void)
+{
+#if HAVE_SIMD128
+    return 16;
+#else
+    return 8;
+#endif
+}
+
-- 
2.46.0



More information about the ffmpeg-devel mailing list