diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index ba3e36903724..dd388e44252f 100644 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -3091,3 +3091,5 @@ set_config("MMX_FLAGS", ["-mmmx"]) set_config("SSE_FLAGS", ["-msse"]) set_config("SSE2_FLAGS", ["-msse2"]) set_config("SSSE3_FLAGS", ["-mssse3"]) +set_config("SSE4_2_FLAGS", ["-msse4.2"]) +set_config("FMA_FLAGS", ["-mfma"]) diff --git a/dom/media/webaudio/AudioNodeEngine.cpp b/dom/media/webaudio/AudioNodeEngine.cpp index ede0560e99e6..75f0edde97e9 100644 --- a/dom/media/webaudio/AudioNodeEngine.cpp +++ b/dom/media/webaudio/AudioNodeEngine.cpp @@ -15,6 +15,10 @@ # include "mozilla/SSE.h" # include "AudioNodeEngineGeneric.h" #endif +#if defined(USE_SSE42) && defined(USE_FMA3) +# include "mozilla/SSE.h" +# include "AudioNodeEngineGeneric.h" +#endif #include "AudioBlock.h" #include "Tracing.h" @@ -74,8 +78,16 @@ void AudioBufferAddWithScale(const float* aInput, float aScale, float* aOutput, #ifdef USE_SSE2 if (mozilla::supports_sse2()) { - Engine::AudioBufferAddWithScale(aInput, aScale, aOutput, - aSize); +# if defined(USE_SSE42) && defined(USE_FMA3) + if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) { + Engine>::AudioBufferAddWithScale( + aInput, aScale, aOutput, aSize); + } else +# endif + { + Engine::AudioBufferAddWithScale(aInput, aScale, aOutput, + aSize); + } return; } #endif @@ -134,7 +146,16 @@ void BufferComplexMultiply(const float* aInput, const float* aScale, #endif #ifdef USE_SSE2 if (mozilla::supports_sse()) { - Engine::BufferComplexMultiply(aInput, aScale, aOutput, aSize); +# if defined(USE_SSE42) && defined(USE_FMA3) + if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) { + Engine>::BufferComplexMultiply(aInput, aScale, + aOutput, aSize); + } else +# endif + { + Engine::BufferComplexMultiply(aInput, aScale, aOutput, + aSize); + } return; } #endif @@ -270,8 +291,16 @@ void AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE], #ifdef USE_SSE2 if (mozilla::supports_sse2()) { - Engine::AudioBlockPanStereoToStereo( - aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR); +# if defined(USE_SSE42) && defined(USE_FMA3) + if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) { + Engine>::AudioBlockPanStereoToStereo( + aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR); + } else +# endif + { + Engine::AudioBlockPanStereoToStereo( + aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR); + } return; } #endif @@ -308,8 +337,16 @@ void AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE], #ifdef USE_SSE2 if (mozilla::supports_sse2()) { - Engine::AudioBlockPanStereoToStereo( - aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR); +# if defined(USE_SSE42) && defined(USE_FMA3) + if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) { + Engine>::AudioBlockPanStereoToStereo( + aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR); + } else +# endif + { + Engine::AudioBlockPanStereoToStereo( + aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR); + } return; } #endif @@ -335,7 +372,15 @@ float AudioBufferSumOfSquares(const float* aInput, uint32_t aLength) { #ifdef USE_SSE2 if (mozilla::supports_sse()) { - return Engine::AudioBufferSumOfSquares(aInput, aLength); +# if defined(USE_SSE42) && defined(USE_FMA3) + if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) { + return Engine>::AudioBufferSumOfSquares( + aInput, aLength); + } else +# endif + { + return Engine::AudioBufferSumOfSquares(aInput, aLength); + } } #endif diff --git a/dom/media/webaudio/AudioNodeEngineSSE4_2_FMA3.cpp b/dom/media/webaudio/AudioNodeEngineSSE4_2_FMA3.cpp new file mode 100644 index 000000000000..53636f0193a0 --- /dev/null +++ b/dom/media/webaudio/AudioNodeEngineSSE4_2_FMA3.cpp @@ -0,0 +1,10 @@ +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* this source code form is subject to the terms of the mozilla public + * license, v. 2.0. if a copy of the mpl was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "AudioNodeEngineGeneric.h" + +namespace mozilla { +template struct Engine>; +} // namespace mozilla diff --git a/dom/media/webaudio/moz.build b/dom/media/webaudio/moz.build index 7148a56a086c..54805556ffd4 100644 --- a/dom/media/webaudio/moz.build +++ b/dom/media/webaudio/moz.build @@ -133,12 +133,17 @@ if CONFIG["CPU_ARCH"] == "aarch64" or CONFIG["BUILD_ARM_NEON"]: if CONFIG["BUILD_ARM_NEON"]: LOCAL_INCLUDES += ["/media/openmax_dl/dl/api/"] -# Are we targeting x86 or x64? If so, build SSE2 files. +# Are we targeting x86 or x64? If so, build SSEX files. if CONFIG["INTEL_ARCHITECTURE"]: - SOURCES += ["AudioNodeEngineSSE2.cpp"] + SOURCES += ["AudioNodeEngineSSE2.cpp", "AudioNodeEngineSSE4_2_FMA3.cpp"] DEFINES["USE_SSE2"] = True + DEFINES["USE_SSE4_2"] = True + DEFINES["USE_FMA3"] = True LOCAL_INCLUDES += ["/third_party/xsimd/include"] SOURCES["AudioNodeEngineSSE2.cpp"].flags += CONFIG["SSE2_FLAGS"] + SOURCES["AudioNodeEngineSSE4_2_FMA3.cpp"].flags += ( + CONFIG["SSE4_2_FLAGS"] + CONFIG["FMA_FLAGS"] + ) include("/ipc/chromium/chromium-config.mozbuild") diff --git a/mozglue/misc/SSE.cpp b/mozglue/misc/SSE.cpp index e15f666bc0c4..ca0b4c3c86de 100644 --- a/mozglue/misc/SSE.cpp +++ b/mozglue/misc/SSE.cpp @@ -147,6 +147,10 @@ bool sse4_1_enabled = has_cpuid_bits(1u, ecx, (1u << 19)); bool sse4_2_enabled = has_cpuid_bits(1u, ecx, (1u << 20)); # endif +# if !defined(MOZILLA_PRESUME_FMA3) +bool fma3_enabled = has_cpuid_bits(1u, ecx, (1u << 12)); +# endif + # if !defined(MOZILLA_PRESUME_AVX) || !defined(MOZILLA_PRESUME_AVX2) static bool has_avx() { # if defined(MOZILLA_PRESUME_AVX) diff --git a/mozglue/misc/SSE.h b/mozglue/misc/SSE.h index 29a312fc7ebd..0b87366a8043 100644 --- a/mozglue/misc/SSE.h +++ b/mozglue/misc/SSE.h @@ -215,6 +215,9 @@ extern bool MFBT_DATA sse4_1_enabled; # if !defined(MOZILLA_PRESUME_SSE4_2) extern bool MFBT_DATA sse4_2_enabled; # endif +# if !defined(MOZILLA_PRESUME_FMA3) +extern bool MFBT_DATA fma3_enabled; +# endif # if !defined(MOZILLA_PRESUME_AVX) extern bool MFBT_DATA avx_enabled; # endif @@ -317,6 +320,16 @@ inline bool supports_sse4_2() { return sse_private::sse4_2_enabled; } inline bool supports_sse4_2() { return false; } #endif +#if defined(MOZILLA_PRESUME_FMA3) +# define MOZILLA_MAY_SUPPORT_FMA3 1 +inline bool supports_fma3() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) +# define MOZILLA_MAY_SUPPORT_FMA3 1 +inline bool supports_fma3() { return sse_private::fma3_enabled; } +#else +inline bool supports_fma3() { return false; } +#endif + #if defined(MOZILLA_PRESUME_AVX) # define MOZILLA_MAY_SUPPORT_AVX 1 inline bool supports_avx() { return true; }