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 d7b7b49f92..8168fed6b8 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 @@ -2791,6 +2798,8 @@ mipsdsp_deps="mips" mipsdspr2_deps="mips" msa_deps="mipsfpu" +simd128_deps="wasm" + x86_64_select="i686" x86_64_suggest="fast_cmov" @@ -5293,6 +5302,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" ;; @@ -6403,6 +6415,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 + +#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 +} +