375 Commits

Author SHA1 Message Date
Frank Barchard
63e54f7374 [libyuv] Add NEON implementations for all remaining C row functions
Implement 32-bit and 64-bit Arm NEON versions (in row_neon.cc and
row_neon64.cc) for the 12 remaining row functions that previously fell
back to C on Arm:
- AR30ToAB30Row_NEON (and AR30ToAB30Row_Any_NEON)
- AR30ToABGRRow_NEON (and AR30ToABGRRow_Any_NEON)
- AR30ToARGBRow_NEON (and AR30ToARGBRow_Any_NEON)
- ARGBAffineRow_NEON
- ARGBColorTableRow_NEON
- ARGBCopyAlphaRow_NEON (and ARGBCopyAlphaRow_Any_NEON)
- ARGBLumaColorTableRow_NEON
- ARGBPolynomialRow_NEON (and ARGBPolynomialRow_Any_NEON)
- ARGBUnattenuateRow_NEON (and ARGBUnattenuateRow_Any_NEON)
- CopyRow_16_NEON (and CopyRow_16_Any_NEON)
- MirrorRow_16_NEON (and MirrorRow_16_Any_NEON)
- RGBColorTableRow_NEON

Add HAS_*_NEON macros, prototypes, _Any wrappers, NEON dispatches in
convert.cc, convert_argb.cc, and planar_functions.cc, and enable unit
tests in planar_test.cc. Arm row function SIMD coverage is now 164/164
(100%).

ARM64 (Apple M6) Benchmark (1280 width, 10000 iterations):
----------------------------------------------------------------
Function                 Before C (ms) After NEON (ms)  Improvement
----------------------------------------------------------------
AR30ToAB30Row                    1.20           0.70        1.72x
AR30ToABGRRow                    1.88           1.03        1.83x
AR30ToARGBRow                    1.88           0.87        2.17x
ARGBAffineRow                    7.96           2.31        3.44x
ARGBColorTableRow                8.17           7.43        1.10x
ARGBCopyAlphaRow                 1.37           0.53        2.58x
ARGBLumaColorTableRow            8.18           5.24        1.56x
ARGBPolynomialRow                8.73           7.55        1.16x
ARGBUnattenuateRow               6.00           2.05        2.93x
CopyRow_16                       0.18           0.18        1.00x
MirrorRow_16                     0.34           0.20        1.73x
RGBColorTableRow                 6.15           5.58        1.10x
----------------------------------------------------------------

Maximum SIMD ISA supported per C row function:
----------------------------------------------------------------
C Row Function              arm32   arm64    x86        riscv
----------------------------------------------------------------
AB64ToARGBRow_C             NEON    NEON     AVX2       RVV
ABGRToAR30Row_C             -       NEON     AVX512BW   -
AR30ToAB30Row_C             NEON    NEON     AVX512BW   -
AR30ToABGRRow_C             NEON    NEON     AVX512BW   -
AR30ToARGBRow_C             NEON    NEON     AVX512BW   -
AR64ShuffleRow_C            NEON    NEON     AVX512BW   RVV
AR64ToAB64Row_C             NEON    NEON     AVX512BW   RVV
AR64ToARGBRow_C             NEON    NEON     AVX2       RVV
ARGB1555ToARGBRow_C         NEON    SVE2     AVX2       -
ARGB1555ToUVMatrixRow_C     NEON    NEON     AVX2       -
ARGB1555ToUVRow_C           NEON    NEON     -          -
ARGB1555ToYMatrixRow_C      NEON    NEON     AVX2       -
ARGB1555ToYRow_C            NEON    NEON     -          -
ARGB4444ToARGBRow_C         NEON    NEON     AVX2       -
ARGB4444ToUVMatrixRow_C     NEON    NEON     AVX2       -
ARGB4444ToUVRow_C           NEON    NEON     -          -
ARGB4444ToYMatrixRow_C      NEON    NEON     AVX2       -
ARGB4444ToYRow_C            NEON    NEON     -          -
ARGBAddRow_C                NEON    NEON     AVX2       -
ARGBAffineRow_C             NEON    NEON     SSE2       -
ARGBAlphaBlendRow_C         NEON    SME      AVX512BW   RVV
ARGBAttenuateRow_C          NEON    NEON     AVX512BW   RVV
ARGBBlendRow_C              NEON    NEON     AVX512BW   RVV
ARGBColorMatrixRow_C        NEON    I8MM     SSSE3      -
ARGBColorTableRow_C         NEON    NEON     X86        -
ARGBCopyAlphaRow_C          NEON    NEON     AVX2       -
ARGBCopyYToAlphaRow_C       NEON    NEON     AVX512BW   RVV
ARGBExtractAlphaRow_C       NEON    NEON     AVX512BW   RVV
ARGBGrayRow_C               NEON    DOTPROD  AVX512VNNI -
ARGBLumaColorTableRow_C     NEON    NEON     SSSE3      -
ARGBMirrorRow_C             NEON    NEON     AVX512BW   RVV
ARGBMultiplyRow_C           NEON    SME      AVX512BW   RVV
ARGBOrRow_C                 NEON    SME      AVX512BW   RVV
ARGBPolynomialRow_C         NEON    NEON     AVX2       -
ARGBQuantizeRow_C           NEON    NEON     SSE2       -
ARGBSepiaRow_C              NEON    DOTPROD  SSSE3      -
ARGBSetRow_C                NEON    NEON     X86        RVV
ARGBShadeRow_C              NEON    NEON     SSE2       -
ARGBShuffleRow_C            NEON    NEON     AVX512BW   RVV
ARGBSubtractRow_C           NEON    NEON     AVX2       -
ARGBToAB64Row_C             NEON    NEON     AVX2       RVV
ARGBToABGRRow_C             NEON    NEON     AVX512BW   RVV
ARGBToAR30Row_C             -       NEON     AVX512BW   -
ARGBToAR64Row_C             NEON    NEON     AVX2       RVV
ARGBToARGB1555Row_C         NEON    NEON     AVX2       -
ARGBToARGB4444Row_C         NEON    NEON     AVX2       -
ARGBToBGRARow_C             NEON    NEON     AVX512BW   RVV
ARGBToRAWRow_C              NEON    SVE2     AVX512BW   RVV
ARGBToRGB24Row_C            NEON    SVE2     AVX512BW   RVV
ARGBToRGB565DitherRow_C     NEON    SVE2     AVX2       -
ARGBToRGB565Row_C           NEON    SVE2     AVX2       -
ARGBToRGBARow_C             NEON    NEON     AVX512BW   RVV
ARGBToUV444MatrixRow_C      NEON    I8MM     AVX512VNNI RVV
ARGBToUVMatrixRow_C         NEON    SME      AVX512VNNI RVV
ARGBToYMatrixRow_C          NEON    SME      AVX512VNNI RVV
ARGBUnattenuateRow_C        NEON    NEON     AVX2       -
AYUVToUVRow_C               NEON    SVE2     AVX512VBMI -
AYUVToVURow_C               NEON    SVE2     AVX512VBMI -
AYUVToYRow_C                NEON    NEON     AVX512VBMI -
BlendPlaneRow_C             NEON    NEON     AVX512BW   RVV
ByteToFloatRow_C            NEON    NEON     -          -
ComputeCumulativeSumRow_C   -       NEON     AVX2       -
Convert16To8Row_C           NEON    SME      AVX512BW   RVV
Convert8To16Row_C           NEON    SME      AVX512BW   RVV
Convert8To8Row_C            NEON    SME      AVX2       -
CopyRow_C                   NEON    SME      AVX512BW   RVV
CopyRow_16_C                NEON    NEON     -          -
CumulativeSumToAverageRow_C -       NEON     AVX2       -
DetileRow_C                 NEON    NEON     SSE2       -
DetileRow_16_C              NEON    NEON     AVX        -
DetileSplitUVRow_C          NEON    NEON     SSSE3      -
DivideRow_16_C              NEON    SVE2     AVX2       -
GaussRow_C                  NEON    NEON     -          -
GaussRow_F32_C              -       NEON     -          -
HalfFloatRow_C              NEON    SVE2     AVX2       -
HalfMergeUVRow_C            NEON    SVE2     AVX512BW   -
HalfRow_16To8_C             NEON    SME      AVX512BW   RVV
HalfWidthRow_16To8_C        NEON    SME      AVX512BW   RVV
I210AlphaToARGBRow_C        -       SME      AVX2       -
I210ToAR30Row_C             -       SME      AVX2       -
I210ToARGBRow_C             -       SME      AVX2       -
I212ToAR30Row_C             -       SME      AVX2       -
I212ToARGBRow_C             -       SME      AVX2       -
I400ToARGBRow_C             NEON    SME      AVX512BW   RVV
I410AlphaToARGBRow_C        -       SME      AVX2       -
I410ToAR30Row_C             -       SME      AVX2       -
I410ToARGBRow_C             -       SME      AVX2       -
I422AlphaToARGBRow_C        NEON    SME      AVX512BW   RVV
I422ToAR30Row_C             -       SME      AVX512BW   RVV
I422ToARGB1555Row_C         NEON    SME      AVX2       -
I422ToARGB4444Row_C         NEON    SME      AVX2       -
I422ToARGBRow_C             NEON    SME      AVX512BW   RVV
I422ToRGB24Row_C            NEON    SME      AVX512VBMI RVV
I422ToRGB565Row_C           NEON    SME      AVX2       -
I422ToRGBARow_C             NEON    SME      AVX2       RVV
I422ToUYVYRow_C             NEON    NEON     AVX2       -
I422ToYUY2Row_C             NEON    NEON     AVX2       -
I444AlphaToARGBRow_C        NEON    SME      AVX2       RVV
I444ToARGBRow_C             NEON    SME      AVX2       RVV
I444ToRGB24Row_C            NEON    SME      AVX2       RVV
InterpolateRow_C            NEON    SME      AVX512BW   RVV
InterpolateRow_16_C         NEON    SME      AVX512BW   -
J400ToARGBRow_C             NEON    NEON     AVX512BW   RVV
MergeAR64Row_C              NEON    NEON     AVX2       -
MergeARGB16To8Row_C         NEON    NEON     AVX2       -
MergeARGBRow_C              NEON    NEON     AVX2       RVV
MergeRGBRow_C               NEON    NEON     AVX512VBMI RVV
MergeUVRow_C                NEON    SME      AVX512BW   RVV
MergeUVRow_16_C             NEON    SME      AVX2       -
MergeXR30Row_C              NEON    NEON     AVX512BW   -
MergeXR64Row_C              NEON    NEON     AVX2       -
MergeXRGB16To8Row_C         NEON    NEON     AVX2       -
MergeXRGBRow_C              NEON    NEON     AVX2       RVV
MirrorRow_C                 NEON    NEON     AVX512BW   -
MirrorRow_16_C              NEON    NEON     AVX512BW   -
MirrorSplitUVRow_C          NEON    NEON     AVX512BW   -
MirrorUVRow_C               NEON    NEON     AVX512BW   RVV
MultiplyRow_16_C            NEON    SME      AVX512BW   RVV
NV12ToARGBRow_C             NEON    SME      AVX512BW   RVV
NV12ToRGB24Row_C            NEON    SME      AVX512VBMI RVV
NV12ToRGB565Row_C           NEON    NEON     AVX2       -
NV21ToARGBRow_C             NEON    SME      AVX512BW   RVV
NV21ToRGB24Row_C            NEON    SME      AVX512VBMI RVV
NV21ToYUV24Row_C            NEON    NEON     AVX2       -
P210ToAR30Row_C             -       SME      AVX2       -
P210ToARGBRow_C             -       SME      AVX2       -
P410ToAR30Row_C             -       SME      AVX2       -
P410ToARGBRow_C             -       SME      AVX2       -
RAWToARGBRow_C              NEON    SVE2     AVX512BW   RVV
RAWToRGB24Row_C             NEON    SVE2     AVX512VBMI RVV
RAWToRGBARow_C              NEON    SVE2     AVX512VBMI RVV
RGB24MirrorRow_C            NEON    NEON     AVX512VBMI -
RGB24ToARGBRow_C            NEON    SVE2     AVX512BW   RVV
RGB565ToARGBRow_C           NEON    NEON     AVX2       -
RGB565ToUVMatrixRow_C       NEON    NEON     AVX2       -
RGB565ToUVRow_C             NEON    NEON     -          -
RGB565ToYMatrixRow_C        NEON    NEON     AVX2       -
RGB565ToYRow_C              NEON    NEON     -          -
RGBAToARGBRow_C             NEON    NEON     AVX512BW   RVV
RGBColorTableRow_C          NEON    NEON     X86        -
RGBToUV444MatrixRow_C       NEON    NEON     AVX512BW   RVV
RGBToUVMatrixRow_C          NEON    NEON     AVX512BW   RVV
RGBToYMatrixRow_C           NEON    DOTPROD  AVX512BW   RVV
SetRow_C                    NEON    NEON     ERMS       -
SobelRow_C                  NEON    NEON     SSE2       -
SobelToPlaneRow_C           NEON    NEON     SSE2       -
SobelXRow_C                 NEON    NEON     SSE2       -
SobelXYRow_C                NEON    NEON     SSE2       -
SobelYRow_C                 NEON    NEON     SSE2       -
SplitARGBRow_C              NEON    NEON     AVX2       RVV
SplitRGBRow_C               NEON    NEON     AVX2       RVV
SplitUVRow_C                NEON    SVE2     AVX512BW   RVV
SplitUVRow_16_C             NEON    NEON     AVX2       -
SplitXRGBRow_C              NEON    NEON     AVX2       RVV
SwapUVRow_C                 NEON    NEON     AVX512BW   RVV
UYVYToARGBRow_C             NEON    SME      AVX2       -
UYVYToUV422Row_C            NEON    NEON     AVX2       -
UYVYToUVRow_C               NEON    SVE2     AVX2       -
UYVYToYRow_C                NEON    SVE2     AVX2       -
YUY2ToARGBRow_C             NEON    SME      AVX2       -
YUY2ToNVUVRow_C             NEON    NEON     AVX2       -
YUY2ToUV422Row_C            NEON    NEON     AVX2       -
YUY2ToUVRow_C               NEON    SVE2     AVX2       -
YUY2ToYRow_C                NEON    SVE2     AVX2       -
----------------------------------------------------------------
SIMD (164/164 100%)         146 89% 164 100% 154 94%    64 39%
----------------------------------------------------------------

Test: libyuv_unittest --gtest_filter=*AR30*:*Affine*:*ColorTable*:*CopyAlpha*:*Polynomial*:*Unattenuate*:*MirrorPlane_16*
Bug: None
Change-Id: Ib8b68beb77b47de6b996d41fd080397c61539ffb
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8666404
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-10-27 16:51:21 -07:00
Frank Barchard
205022c08c [libyuv] Add AVX-512 VNNI row functions for ARGB to YUV and Gray
Add AVX-512 VNNI (VPDPBUSD / _mm512_dpbusd_epi32) row kernels for 64-bit
x86 targets alongside existing AVX-512BW implementations in both
row_gcc.cc (inline assembly) and row_win.cc (C++ intrinsics):

- ARGBToYMatrixRow_AVX512VNNI and ARGBToYMatrixRow_Any_AVX512VNNI:
  Pre-computes the 32-bit signed-pixel bias once per row and replaces
  vpmaddubsw + vpmaddwd + vpaddw with a single vpdpbusd per 16 pixels.
- ARGBToUV444MatrixRow_AVX512VNNI and
  ARGBToUV444MatrixRow_Any_AVX512VNNI: Loads 64 ARGB pixels once instead
  of twice and computes 32-bit U and V dot products directly via
  vpdpbusd with signed UV matrix coefficients.
- ARGBToUVMatrixRow_AVX512VNNI: Computes 2x2 box-filtered ARGB to U and
  V conversion using vpdpbusd with k-masked tail handling for arbitrary
  widths.
- ARGBGrayRow_AVX512VNNI: Computes BT.601 grayscale luminance using a
  single vpdpbusd per 16 pixels, broadcasts Y to RGB via vpshufb, and
  preserves alpha via vpternlogd with k-masked tail handling.
- Wire runtime dispatch via TestCpuFlag(kCpuHasAVX512VNNI) across
  convert.cc, convert_from_argb.cc, and planar_functions.cc.

Add AVX512VNNIVBMI variants of the Y, UV444 and UV kernels. These use
both AVX-512 VNNI (vpdpbusd) and AVX-512 VBMI (vpermt2b) and are only
selected when the CPU has both features; there are no VBMI versions
without VNNI. The AVX512VNNI kernels remain for CPUs with VNNI but no
VBMI (Cascade Lake, Cooper Lake).

- The 32-bit sums are always in [0, 65535], so Y, U and V are byte 1 of
  each int32. Two vpermt2b gather 64 results from 4 accumulators,
  replacing vpackusdw/vpackssdw + vpsrlw + vpackuswb + vpermd.
- U and V accumulators start at ~kAddUV so they hold ~(kAddUV - dot).
  The inverse is folded into the vpternlogd that merges the two
  256-bit halves. kAddUV is loaded from ArgbConstants rather than
  hard coded as 0x8000.
- Y folds the source loads into vpxorq.
- row_win.cc hides the vpermt2b indices from clang, which otherwise
  constant folds them into a longer vpshufb + vpor + vpermd sequence.

Performance (1280x720, 5000 iterations, AVX512BW -> AVX512VNNI):
uArch / Benchmark            AVX512BW  AVX512VNNI  Speedup
---------------------------  --------  ----------  -------
Intel Ice Lake ARGBToI420      941 ms      862 ms   +9.2%
Intel Ice Lake ARGBToI422     1059 ms      947 ms  +11.8%
Intel Ice Lake ARGBToI444     1140 ms     1038 ms   +9.8%
Intel Ice Lake ARGBGray        357 ms      273 ms  +30.8%
Intel Sapphire Rapids GrayTo   317 ms      218 ms  +45.4%
Intel Emerald Rapids GrayTo    310 ms      213 ms  +45.5%
Intel Granite Rapids GrayTo    349 ms      241 ms  +44.8%
AMD Zen 4 ARGBToI420           648 ms      517 ms  +25.3%
AMD Zen 4 ARGBToI444           695 ms      526 ms  +32.1%
AMD Zen 4 ARGBGray             403 ms      227 ms  +77.5%
AMD Zen 5 ARGBToI422           460 ms      403 ms  +14.1%
AMD Zen 5 ARGBToI444           382 ms      321 ms  +19.0%

Performance (row_gcc, AVX512VNNI -> AVX512VNNIVBMI):
uArch / Benchmark             AVX512VNNI  VNNIVBMI  Speedup
----------------------------  ----------  --------  -------
AMD Zen 6 ARGBToI420 1280x720     327 ms    284 ms   +15.1%
AMD Zen 6 ARGBToI422 1280x720     372 ms    330 ms   +12.7%
AMD Zen 6 ARGBToI444 1280x720     357 ms    334 ms    +6.9%
AMD Zen 6 ARGBToI400 256x24        94 ms     76 ms   +23.7%
AMD Zen 5 ARGBToI422 1280x720     406 ms    350 ms   +16.0%
AMD Zen 5 ARGBToI444 1280x720     330 ms    301 ms    +9.6%
AMD Zen 5 ARGBToI400 256x24       100 ms     90 ms   +11.1%
AMD Zen 4 ARGBToI420 1280x720     631 ms    540 ms   +16.9%
AMD Zen 4 ARGBToI422 1280x720     993 ms    825 ms   +20.4%
AMD Zen 4 ARGBToI400 256x24       245 ms    218 ms   +12.4%
Intel GNR ARGBToI422 256x24       654 ms    616 ms    +6.2%
Intel SPR ARGBToI422 256x24       653 ms    613 ms    +6.5%
Intel GNR, EMR, SPR and Ice Lake are within +/-3% at 1280x720.

R=rrwinterton@gmail.com

Bug: none
Test: out/Release/libyuv_unittest --gtest_filter=*ARGBToI4*:*ARGBGray*
Test: LIBYUV_DISABLE_AVX512VBMI=1 out/Release/libyuv_unittest
Test: sde64 -gnr / -clx with is_msan=true (row_win.cc)
Change-Id: Ia7a37b39dd2948fe4055a8a7694dd1ff8ac3e55c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8647811
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-26 14:07:50 -07:00
Frank Barchard
38e21134f7 [libyuv] Add ARGBOr and ARGBAlphaBlend with multi-platform SIMD
Add two new planar/row compositing functions for 32-bit ARGB/BGRA
scanlines:

- ARGBOr / ARGBOrRow_*: Applies a bitwise OR with a 32-bit ARGB mask
  to every pixel (e.g., 0xFF000000 to force opaque alpha for BGRx to
  BGRA conversion). Implemented for C, SSE2, AVX2, AVX-512BW, NEON
  (32/64-bit), SVE2, SME, RVV, WASMSIMD, LSX, LASX, HVX, and Windows
  intrinsics (row_win.cc).
- ARGBAlphaBlend / ARGBAlphaBlendRow_*: Implements straight-alpha
  (unattenuated) Porter-Duff source-over blending matching PDFium's
  CompositeRowBgra2Bgra:
    dst_a = back_a + src_a - (back_a * src_a) / 255
    ratio = (src_a * 255) / dst_a
    dst_c = (back_c * (255 - ratio) + src_c * ratio) / 255
  Implemented with bit-exact division by 255 across all 65,536
  (back_a, src_a) pairs for C, SSSE3, AVX2, AVX-512BW, NEON
  (32/64-bit), SVE2, SME, RVV, WASMSIMD, LSX, LASX, HVX, and Windows
  intrinsics (row_win.cc).

ARGBOr Performance (2048x64 BGRx->BGRA scanlines, us per call):
uArch                     Before  Highway   libyuv  vs Hwy
------------------------  ------  -------  -------  ------
Qualcomm Hexagon v81 HVX  259.63   260.97    15.78  16.54x
SiFive X280 (RVV)        1107.57    72.49    50.70   1.43x
SiFive X390 (RVV)        1108.82    70.42    52.26   1.35x

ARGBAlphaBlend Performance (2048x64 BGRA scanlines, us per call):
uArch                     Before  Highway   libyuv  vs Hwy
------------------------  ------  -------  -------  ------
Intel Lion Cove (AVX2)    429.79   141.97    41.89   3.39x
Intel Cougar Cove (AVX2)  516.83   181.98    51.33   3.55x
Intel Golden Cove (AVX2)  560.31   206.28    67.08   3.08x
AMD Zen 3 (AVX2)         1025.73   251.09    98.99   2.54x
Wasm SIMD128 (V8)        1014.14   964.83   385.80   2.50x
Apple M6 Super (NEON)     221.90   118.42    46.35   2.55x
Apple M5 Super (NEON)     241.90   130.07    49.60   2.62x
ARM C1-Ultra (SME2)       384.63   112.52    63.62   1.77x
Qualcomm Oryon V3-L (SME) 388.13   154.87    87.65   1.77x
Qualcomm Oryon-L (NEON)   318.28   149.36    57.23   2.61x
ARM Cortex-X4 (SVE2)      675.47   213.56   102.53   2.08x
ARM Cortex-A720 (NEON)    795.85   586.55   235.81   2.49x
ARM Cortex-A520 (NEON)   2360.95  2122.99   787.65   2.70x
ARM Cortex-A35 (ARMv7)   4907.31  5895.04  1474.51   4.00x
SiFive X280 (RVV)        4145.06  1096.42   596.82   1.84x
SiFive X390 (RVV)        4144.57  1084.93   597.62   1.82x
Qualcomm Hexagon v81 HVX 4912.03  5786.25   952.19   6.08x
Coral V4 RVV (1024 px)   50276 c  48992 c   4299 c  11.40x

R=wtc@google.com

Bug: none
Change-Id: If661239826a033e89d4b5c1adc0bfdf048a7a726
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8647895
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-26 11:24:16 -07:00
Frank Barchard
f249eaa72f [libyuv] Fix top 20 bugs and performance issues
1. Fix multi-bit TestCpuFlag(A | B) checks in AYUVToNV12, AYUVToNV21,
   RAWToRGBA, NV12ToRGB24Matrix, NV21ToRGB24Matrix, MergeRGBPlane, and
   MergeXR30Plane to compare == (A | B) so AVX-512 VBMI/BW kernels are
   not dispatched when AVX512VBMI or AVX512VL is absent.
2. Fix 2-byte SVE2 heap buffer overflow on odd widths in
   I422ToARGB1555Row_SVE_SC and I422ToARGB4444Row_SVE_SC using
   trn1/trn2 + st2b under .b predicates.
3. Fix ARGBPolynomialRow_SSE2 to use packssdw before packuswb, and add
   missing vzeroupper to SplitRGBRow_AVX2.
4. Fix CalcFrameSsim to return 0.0 instead of 0.0 / 0 (NaN) when
   width <= 8 || height <= 8 so I420Ssim stays finite on small frames.
5. Fix negative-height vertical inversion in ConvertFromI420,
   SplitARGBPlane (when dst_a is NULL), I422Rotate, I010Rotate, and
   I210Rotate.
6. Fix horizontal flip (negative x/dx) in ScaleFilterCols_NEON (signed
   sbfx #16, #16 offset extraction) and ScaleAddCols1_16_C (shift
   x >>= 16 before indexing src_ptr).
7. Fix ConvertToARGB odd crop_x chroma alignment in NV12/NV21, src_u
   offset in I420/YV12/J420/H420/U420, and FOURCC_U422 calling
   U422ToARGB instead of H422ToARGB.
8. Remove dead 14-instruction block in ScaleRowUp2_Bilinear_16_SSE2.
9. Fix UVScale_16 for src_width == 1 (P010ToP410/P210ToP410), enable
   and fix column order in TransposeWx4_32_SVE2, fix ByteToFloatRow
   NEON Any BPP (3 -> 4), fix AB64ToARGBRow_Any_*, ScaleColsUp2_SSE2,
   ScaleUVRowDown2Box_SME, and UYVYToARGBRow_SME macro guards, fix SVE2
   loop tail branches (b.lt/b.ge), and remove duplicate HAS_* macros.
10. Fix ConvertFP16ToFP32Column_NEON loop condition and unsigned b.lo
    underflow on widths < 8 or not multiples of 8.
11. Fix UYVYToNV12 IS_ALIGNED(awidth, ...) checks and WASM SIMD
    IS_ALIGNED(width, 16) checks in I420ToRGB24Matrix /
    I422ToRGB24Matrix.
12. Wire SplitUVRow_SVE2, SplitUVRow_LSX, and SplitUVRow_LASX in
    NV24ToARGB.
13. Fix MJpegDecoder heap buffer overflows in LoadFrame (reallocate
    databuf_[i] when scanlines_size changes), DecodeToBuffers, and
    DecodeToCallback (clamp scanlines_to_copy to lines_left and align
    skip to max_v_samp_factor).
14. Replace width & (vl - 1) tail calculations with post-loop remainder
    across 18 SVE2 functions in row_sve.h for non-power-of-2 SVE VL,
    and remove duplicate label 2: in UYVYToARGBRow_SVE_SC.
15. Handle width & 15 tail pixels in DetileToYUY2_C and validate
    IS_POWEROFTWO(tile_height) in DetileSplitUVPlane and DetileToYUY2.
16. Avoid signed 32-bit overflow in DivideRow_16_C and C16TO8, fix
    ClampFloatToZero_SSE2 pointer increment (lea 0x4) and loop counter
    (sub $0x1), and initialize xmm3 in ARGBCopyYToAlphaRow_SSE2.
17. Check max leaf 7 subleaf and max extended CPUID leaf in GetCpuFlags
    before querying subleaf 7:1 and extended leaf 0x80000021.
18. Free plane_u on error in I422ToNV21, and fix 4x/2x scratch row
    over-allocation in ScaleARGBBilinearDown and ScaleUVBilinearDown.
19. Add ARGBSetRow_RVV and ARGBShuffleRow_RVV in row_rvv.cc.
20. Fix NEON mask (15 -> 7) in ScaleUVRowUp2_Linear_Any_NEON /
    _16_Any_NEON, use SIMD InterpolateRow + SplitUVRow in NV16ToI420,
    wire SSSE3/SSE2 in ARGBToI400Matrix / ARGBToYUY2Matrix /
    ARGBToUYVYMatrix and RGB24Mirror, and split HalfFloatRow multiply
    into (src * scale) * 2^-112 to avoid 50x Intel denormal stalls.

Bug: b/574714081
Test: libyuv_unittest
Change-Id: Iec3ae5c58d52bee3ef13cf9b765ac84b733aa576
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8601931
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-10-19 16:46:40 -07:00
Frank Barchard
2404f9730e [libyuv] Rewrite LoongArch LSX/LASX kernels in compact inline asm
Reduce loop unrolling across LoongArch LSX (128-bit) and LASX (256-bit)
compare, row, rotate, and scale kernels to match SSE2/SSSE3 and AVX2
(1-2 vectors per iteration), rewrite intrinsics/macro implementations
into GCC/Clang inline assembly, update all _Any wrapper masks and
IS_ALIGNED dispatch checks, and port all remaining LSX Convert (+19) and
Rotate (+2) kernels to LASX for full parity:

ISA              | Compare | Convert | Rotate  | Scale
-----------------|---------|---------|---------|--------
MIPS/Loong (Any) |    1    |    68   |    4    |   20
  LSX            |    1    |    68   |    4    |   20
  LASX           |    1    |    68   |    4    |    0

Removes 1,935 macro/helper lines from loongson_intrinsics.h (-99.3%) and
reduces total LoongArch compiled .text size by 9,799 bytes (-25.1%
overall, -37.4% row_lsx.cc, -52.3% scale_lsx.cc, -31.2% rotate_lsx.cc,
-4.9% row_lasx.cc while adding +25 LASX functions):

File               | Before   | After    | Change
-------------------|----------|----------|--------
scale_lsx.cc.o     | 6,055 B  | 2,888 B  | -52.3%
row_lsx.cc.o       | 17,252 B | 10,792 B | -37.4%
rotate_lsx.cc.o    | 1,488 B  | 1,024 B  | -31.2%
row_lasx.cc.o      | 13,740 B | 13,072 B |  -4.9%
rotate_lasx.cc.o   |   544 B  | 1,504 B  | +176.5%
TOTAL .text        | 39,079 B | 29,280 B | -25.1%

R=wtc@google.com, yuanhecai@loongson.cn

Test: qemu-loongarch64 -cpu la464 libyuv_unittest (LASX and LIBYUV_DISABLE_LASX=1)
Change-Id: I11c1143ad2aad0399f10b2c3fc9bc4c02c740c59
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8564659
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-16 17:25:23 -07:00
Frank Barchard
63b56324de [libyuv] Replace AVX-512 _Any wrappers with k-mask tail handling
Replace stack-buffer memcpy _Any wrappers with native AVX-512 k-mask
tail handling across 8 AVX-512 row kernels (unlocking composite
RGBToUVMatrixRow_AVX512BW as well) and remove IS_ALIGNED dispatch
constraints:
- MirrorSplitUVRow_AVX512BW: Masked 16-bit load (vmovdqu16 %{k1%}%{z%}),
  dynamic reverse index (vpsubw + vpermw via kMirrorUVPermute_AVX512),
  and vpmovwb %{k1%} U/V stores; unlocks unaligned SplitRotateUV180.
- ARGBToUVMatrixRow_AVX512BW: Fix MASK=63 vs 32-pixel loop bug;
  zero-load tail dwords per row, duplicate odd final pixel via knotw +
  vpshufd, and store masked U/V bytes.
- I422ToARGBRow_AVX512BW & I422ToAR30Row_AVX512BW: Add masked Y/U/V
  loads (READYUV422_MASK_AVX512BW) and masked ARGB/AR30 stores.
- CopyRow_AVX512BW: Add 64-byte full vector step + bzhi masked tail.
- BlendPlaneRow_AVX512BW, ARGBShuffleRow_AVX512BW, RGBToARGBRow_AVX512BW
  (RAWToARGBRow_AVX512BW / RGB24ToARGBRow_AVX512BW): Masked loads and
  stores in both row_gcc.cc inline assembly and row_win.cc intrinsics.

Reduces x86-64 binary .text size by 2,592 bytes with 0 bytes added to
.rodata.

Performance on Intel Sapphire Rapids (1275x1650, 1000 iterations):
Function (Test)          | Before  | After   | Speedup
-------------------------|---------|---------|--------
NV12Rotate180_Opt        | 429 ms  | 260 ms  | 1.65x
RGB24ToI420_Opt          | 615 ms  | 531 ms  | 1.16x
I420ToAR30_Opt           | 425 ms  | 383 ms  | 1.11x
ARGBToI420_Opt           | 427 ms  | 411 ms  | 1.04x
I420ToARGB_Opt           | 423 ms  | 411 ms  | 1.03x
RGB24ToARGB_Opt          | 493 ms  | 490 ms  | 1.01x
ARGBToBGRA_Opt           | 544 ms  | 542 ms  | 1.00x
CopyPlane_Opt            | 246 ms  | 245 ms  | 1.00x
BlendPlane_Opt           | 259 ms  | 258 ms  | 1.00x
RAWToARGB_Opt            | 486 ms  | 486 ms  | 1.00x

R=rrwinterton@gmail.com

Test: LIBYUV_WIDTH=1275 LIBYUV_HEIGHT=1650 LIBYUV_REPEAT=1000 out/Release/libyuv_unittest
Change-Id: Ib5e5ae52076352649108b20f8df2b12d81860fb1
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8563977
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-12 15:33:19 -07:00
Frank Barchard
16af162cf9 [libyuv] Optimize RotatePlane_16 SIMD and compact 32-bit transposes
Implement SIMD 16-bit plane rotation (TransposePlane_16,
RotatePlane90_16, RotatePlane180_16, RotatePlane270_16) used by
I010Rotate, I210Rotate, and I410Rotate, keeping tile sizes compact
with full-register writes and zero cross-lane shuffles:
- AVX2: 8x16 tile in ymm0..ymm15 with _Any tail (low-end x86 SIMD)
- AVX-512BW: 8x32 tile in zmm0..zmm15 with k1/k2 right/bottom masks
- NEON (ARM64/ARM32): 8x16 tile in v0..v23 / q0..q11 with _Any tail
- SME: 8xVL tile using ZA16 horizontal/vertical array slices
- RVV: 8xVL tile using widening unpacks with hardware vl tail
- WASM SIMD: 8x8 tile in v128 with _Any tail

Also update 32-bit ARGBRotate x86 transposes to compact vertical
in-lane tiles with full-register writes and zero cross-lane shuffles:
- TransposeWxH_32_AVX2: 4x8 tile in ymm0..ymm7 with vpmaskmovd tails
- TransposeWxH_32_AVX512BW: 4x16 tile in zmm0..zmm7 with k1/k2 tails

Add RotatePlane16_SplitMergeUV_Opt and RotatePlane16_SplitMergeUV_Odd
unit tests comparing 16-bit rotation against SplitUVPlane +
RotatePlane + MergeUVPlane across 0/90/180/270 degrees.

Performance on 1275x1650 (1000 iterations, before -> after):
CPU                     90 degree               180 degree
Coral RVV (Verilator)   7306 -> 1415c (5.16x)   2274 -> 719c (3.16x)
AMD Rome (Zen 2)        821 -> 215ms (3.82x)    259 -> 181ms (1.44x)
AMD Genoa (Zen 4)       483 -> 129ms (3.73x)    149 -> 111ms (1.34x)
AMD Turin (Zen 5)       321 -> 101ms (3.18x)    109 -> 78ms (1.40x)
AMD Milan (Zen 3)       505 -> 189ms (2.67x)    199 -> 118ms (1.69x)
Intel Skylake-X         1076 -> 447ms (2.41x)   353 -> 317ms (1.11x)
WASM SIMD (d8)          415 -> 203ms (2.04x)    370 -> 106ms (3.49x)
Intel Emerald Rapids    735 -> 422ms (1.74x)    238 -> 233ms (1.02x)
Intel Haswell           1120 -> 648ms (1.73x)   438 -> 393ms (1.11x)
Intel Ice Lake          774 -> 474ms (1.63x)    279 -> 290ms (0.96x)
ARM Neoverse-N1         864 -> 544ms (1.59x)    404 -> 266ms (1.52x)
Ampere Siryn            862 -> 576ms (1.50x)    568 -> 329ms (1.72x)
Google Axion (Maple)    554 -> 379ms (1.46x)    199 -> 142ms (1.41x)
Intel Sapphire Rapids   1126 -> 772ms (1.46x)   301 -> 288ms (1.04x)
Intel Granite Rapids    730 -> 565ms (1.29x)    280 -> 280ms (1.00x)
NVIDIA Grace            462 -> 365ms (1.26x)    192 -> 126ms (1.52x)
ARM Cortex-A53          28290 -> 24386ms (1.16x) 7178 -> 5075ms (1.41x)
Google Axion 2 (Tamar)  523 -> 453ms (1.15x)    217 -> 112ms (1.93x)

Test: libyuv_unittest --gtest_filter=*Rotate*
Bug: b/42280942
Change-Id: I91ba6cac22185b5d294fcb98344fdb8a23cc94ff
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8545294
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-10-12 10:57:34 -07:00
Frank Barchard
eeb06a6451 [libyuv] Optimize ARGBRotate for Intel SSE2, AVX2, and AVX-512
Optimize 32-bit ARGBRotate (0, 90, 180, 270) across Intel x86/x64
architectures (SSE2, AVX2, AVX512BW), with matching kernels for ARM
(NEON, SVE2, SME), WASM, LoongArch (LSX, LASX), and RISC-V (RVV):

- Replace column-by-column ScaleARGBRowDownEven gather loops in
  ARGBTranspose (90/270) with full-plane horizontal tile transposes:
  - AVX512BW (TransposeWxH_32_AVX512BW / TransposeNx4_32_AVX512BW):
    Transpose 16x16 blocks across zmm0..zmm31 using 4-stage
    vpunpckldq/hdq, vpunpcklqdq/hqdq, and vshufi32x4 butterflies with
    k-masked right and bottom tails, eliminating Any wrappers and scalar
    C edge fallbacks.
  - AVX2 (TransposeWxH_32_AVX2 / TransposeNx4_32_AVX2):
    Transpose 8x8 blocks across ymm0..ymm15 using vpunpck* and
    vperm2i128 with vpmaskmovd masked tails.
  - SSE2 (Transpose4x4_32_SSE2 / Transpose4x4_32_Any_SSE2):
    Transpose 4x4 blocks in xmm registers.
- Implement ARGBRotate180 directly via ARGBMirror with negative height,
  avoiding intermediate row buffer allocations and extra copies.
- Implement ARGBRotate0 via ARGBCopy.

Speedup vs Before (1275x1650, US Letter 150 DPI, 1000 iterations):
CPU                  | 0 deg   | 90 deg  | 180 deg | 270 deg
---------------------|---------|---------|---------|--------
Intel Ice Lake       | 1.02x   | 1.34x   | 1.18x   | 1.33x
Intel Skylake-X      | 1.02x   | 1.20x   | 1.07x   | 1.13x
Intel Emerald Rapids | 1.01x   | 1.07x   | 1.00x   | 1.07x
Intel AVX-512 vs C   | 1.00x   | 2.67x   | 2.41x   | 2.63x

R=rrwinterton@gmail.com

Bug: b/42280915
Test: LIBYUV_WIDTH=1275 LIBYUV_HEIGHT=1650 LIBYUV_REPEAT=1000 ./out/Release/libyuv_unittest --gtest_filter=*ARGBRotate*
Change-Id: Ib308a225c17e46eab083a9da4033598fcf0c303c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8538986
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-08 16:20:46 -07:00
Frank Barchard
1ddb18fb6b [libyuv] AVX512, NEON, WASM and RVV alpha copy and mirror rows
1275x1650 (US Letter 150 DPI, 1000 iterations) speedup:

CPU            ARGBExtractAlpha ARGBCopyYToAlpha ARGBMirror RGB24Mirror
-----------------------------------------------------------------------
Intel Granite Rapids      1.00x            1.00x      1.00x       1.04x
Intel Emerald Rapids      1.01x            0.97x      1.03x       1.07x
Intel Sapphire Rapids     0.97x            1.01x      1.08x       1.26x
Intel Ice Lake            0.99x            1.02x      0.97x       1.08x
Intel Skylake-X           1.04x            1.03x      1.01x          NA
Intel Haswell                NA               NA         NA          NA
AMD Turin (Zen 5)         1.01x            1.10x      1.25x       1.31x
AMD Genoa (Zen 4)         0.97x            1.04x      1.09x       1.42x
AMD Milan (Zen 3)            NA               NA         NA          NA
AMD Rome (Zen 2)             NA               NA         NA          NA
NVIDIA Grace (V2)         1.57x            2.51x         NA          NA
Google Axion 2            1.12x            3.17x         NA          NA
Ampere Siryn              1.06x            1.70x         NA          NA
ARM Neoverse-N1           1.49x            2.01x         NA          NA
Google Axion (Maple)      1.47x            2.03x         NA          NA
ARM Cortex-A53            1.06x            1.69x         NA          NA

Add AVX512BW ARGBExtractAlphaRow, ARGBCopyYToAlphaRow and
ARGBMirrorRow, and AVX512VBMI RGB24MirrorRow, in row_gcc.cc and as
intrinsics in row_win.cc. They are x64 only. The remainder is done
with a k-mask (bzhi) zero-masked load and a masked store, so they
handle any width without an Any wrapper and never access memory
outside the row.

RGB24MirrorRow_AVX512VBMI loads and stores 3 full zmm vectors per
64 pixels using 3 vpermi2b. The one output byte that comes from the
third input vector is merged with a masked vpbroadcastb. The 1 to 63
pixel tail rebases the same tables by 192 - 3 * r; indices >= 128 are
taken from the third vector with vpmovb2m and a masked vpermb.

Add ARGBCopyYToAlphaRow_NEON for Arm 32 bit (vld4 + vst4) and
AArch64 (zip + sli), and rewrite AArch64 ARGBExtractAlphaRow_NEON
with ldp + uzp2. Both prefetch source and destination, which is
2.5x faster on Neoverse-N1 and 1.2x to 1.5x faster on Cortex-A53
for 1280x720. Add WASM SIMD ARGBExtractAlphaRow and
ARGBCopyYToAlphaRow, using a swizzle table for CopyYToAlpha. Rework
the RVV versions to use unit stride loads with vnsrl and vzext.vf4.


R=rrwinterton@gmail.com

Bug: None
Change-Id: I436f27d70a3db0a2b176c91eb789a9491133cfcb
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8523531
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-10-07 12:44:53 -07:00
Frank Barchard
98697ab033 [libyuv] Add WASM SIMD128 compare, rotate, scale and row functions
d8 geomean speedup vs C compiled with -O2 -msimd128:
File            AMD Zen 3  ARM Neoverse-V2
row_wasm.cc         5.67x            3.24x
scale_wasm.cc       5.47x            3.17x
compare_wasm.cc     4.58x            5.77x
rotate_wasm.cc      6.83x            6.03x

Bug: None
Change-Id: Ia06c805dc4029f94842c40e7301b2933beb8c1e5
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8524106
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-06 19:05:05 -07:00
Frank Barchard
eb8eda9c79 [libyuv] Add WASM SIMD128 and Relaxed SIMD for RAWToRGB24Row
Implement RAWToRGB24Row_WASMSIMD and RAWToRGB24Row_Any_WASMSIMD in
source/row_wasm.cc for RGB24ToRAW and RAWToRGB24 conversions:
- Process 16 pixels (48 bytes) per loop iteration using three 128-bit
  loads, three byte-wise shuffles, and four 2-way blends.
- Use wasm_i8x16_relaxed_swizzle when __wasm_relaxed_simd__ is enabled
  (compiling to a single vpshufb on x86 without bounds-checking
  overhead) and fall back to wasm_i8x16_swizzle for baseline SIMD128.
- Add kCpuHasWASM (0x100) and kCpuHasWASMSIMD (0x101) CPU feature
  flags and enable -msimd128 in BUILD.bazel, BUILD.gn, and
  CMakeLists.txt for WebAssembly targets.

Performance (RAWToRGB24_Opt, 1280x720, V8 d8):
CPU                     WASM C  SIMD128  Relaxed  SIMD Spd  Rlx Spd
-------------------------------------------------------------------
AMD Zen 4             595.0 us 137.0 us  84.0 us     4.34x    7.08x
AMD Zen 3             708.0 us 148.0 us 107.0 us     4.78x    6.62x
AMD Zen 5             375.0 us 107.0 us  67.0 us     3.50x    5.60x
ARM Neoverse-V2       638.0 us 118.0 us 116.0 us     5.41x    5.50x
ARM Neoverse-N1      1046.0 us 294.0 us 294.0 us     3.56x    3.56x
Intel Ice Lake        707.0 us 209.0 us 220.0 us     3.38x    3.21x
Intel Haswell        1110.0 us 344.0 us 360.0 us     3.23x    3.08x
Intel Emerald Rapids  519.0 us 207.0 us 208.0 us     2.51x    2.50x
Intel Sapphire Rapids 551.0 us 220.0 us 255.0 us     2.50x    2.16x
ARM Cortex-A53      14440.0 us 8660.0us 6920.0us     1.67x    2.09x
Intel Granite Rapids  453.0 us 225.0 us 221.0 us     2.01x    2.05x

Bug: 42271072
Test: libyuv_test --gunit_filter=*RAWToRGB24*:*RGB24ToRAW*:*Cpu*
Change-Id: Id902668263a2ab70aa300eeeea18851490c917b5
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8515581
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-10-05 17:45:41 -07:00
Frank Barchard
2b7ecc0aad RAWToRGB24 for NEON, x86, and LoongArch
R=rrwinterton@gmail.com

Test: libyuv_unittest --gtest_filter=*RAWToRGB24*:*RGB24ToRAW*
Bug: None
Change-Id: I4454f3785ba5c39dc776ba1f5151cd9d3e68055b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8509286
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-10-05 12:09:40 -07:00
Frank Barchard
18835bfb35 ARGBToRGB24 AVX512 with tail masking
Bug: None
Change-Id: I7590c66940b5354ca0fdd8ff120392434d2785d7
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8490011
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-09-29 16:15:44 -07:00
Frank Barchard
783ea90384 [libyuv] Enable LIBYUV_ENABLE_ROWWIN and MSAN_MEMSET for MSan builds
Enable LIBYUV_ENABLE_ROWWIN instead of LIBYUV_DISABLE_X86 under
MemorySanitizer so that C++ SIMD intrinsics in row_win.cc and their
corresponding _Any wrappers in row_any.cc are compiled and tested
under MSan.

Rename MEMSET to MSAN_MEMSET in row_any.cc and scale_any.cc, and
initialize vout buffers across all ANY* macros in row_any.cc. Use
calloc for align_buffer_64 and align_buffer_page_end under
LIBYUV_MSAN, and zero-initialize stack pixel buffers in color_test.cc.

Test: out/msan/libyuv_unittest
Bug: None
Change-Id: I0b9fc69af159531699bb2b2db8b48f39831289ee
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8456982
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-09-28 10:49:58 -07:00
Frank Barchard
f1c9b58986 clang format and bump version
Bug: None
Change-Id: I6a482d5c538b113549b88e820473af644d6d3704
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8467772
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-09-28 10:42:45 -07:00
Frank Barchard
2124173f34 I422ToRGB24 avx512bw tail and row coalesce
I422ToRGB24Matrix (299x299, repeat=10000)
====================================================================
CPU                        Before       After            Improvement
--------------------------------------------------------------------
Intel Skylake-X            275 ms       213 ms       -22.5% (1.29x)
Intel Ice Lake             225 ms       177 ms       -21.3% (1.27x)
Intel Sapphire Rapids      181 ms       144 ms       -20.4% (1.26x)
Intel Emerald Rapids       167 ms       136 ms       -18.6% (1.23x)
Intel Granite Rapids       170 ms       140 ms       -17.6% (1.21x)
AMD Zen 4 (Genoa)          192 ms       136 ms       -29.2% (1.41x)
AMD Zen 5 (Turin)          102 ms        68 ms       -33.3% (1.50x)
AMD Zen 6 (Venice)         102 ms        60 ms       -41.2% (1.70x)
====================================================================

I422ToRGB24Matrix (298x299, repeat=10000)
====================================================================
CPU                        Before       After            Improvement
--------------------------------------------------------------------
Intel Skylake-X            271 ms       184 ms       -32.1% (1.47x)
Intel Ice Lake             235 ms       152 ms       -35.3% (1.55x)
Intel Sapphire Rapids      199 ms       128 ms       -35.7% (1.55x)
Intel Emerald Rapids       170 ms       121 ms       -28.8% (1.40x)
Intel Granite Rapids       177 ms       125 ms       -29.4% (1.42x)
AMD Zen 4 (Genoa)          185 ms       119 ms       -35.7% (1.55x)
AMD Zen 5 (Turin)          102 ms        59 ms       -42.2% (1.73x)
AMD Zen 6 (Venice)         100 ms        51 ms       -49.0% (1.96x)
====================================================================

Bug: None
Change-Id: Id75e3d1df6d26bc28a252672816a7c438cb664a4
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8452502
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-09-24 12:07:29 -07:00
Frank Barchard
41a6e684a6 I422ToRGB24Row_AVX512VBMI handle tail with mask
I422ToRGB24Matrix (299x299, repeat=10000)
====================================================================
CPU                        Before       After            Improvement
--------------------------------------------------------------------
Intel Ice Lake             220 ms       181 ms       -17.7% (1.22x)
Intel Sapphire Rapids      181 ms       145 ms       -19.9% (1.25x)
Intel Emerald Rapids       169 ms       148 ms       -12.4% (1.14x)
Intel Granite Rapids       191 ms       141 ms       -26.2% (1.35x)
AMD Zen 4 (Genoa)          171 ms       136 ms       -20.5% (1.26x)
AMD Zen 5 (Turin)           94 ms        72 ms       -23.4% (1.31x)
AMD Zen 6 (Venice)          95 ms        66 ms       -30.5% (1.44x)
====================================================================

Bug: None
Change-Id: I4cd657410cc5253b5e8fd2caa78d17e2b3812393
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8445804
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-09-23 22:42:30 -07:00
Frank Barchard
a09d909f63 [libyuv] Only memset row_any temporary buffers for MSAN
libyuv_test '--gunit_filter=*I422ToRGB24_Opt' --libyuv_width=299 --libyuv_height=299 --libyuv_repeat=10000 --libyuv_flags=-1 --libyuv_cpu_info=-1

Was I422ToRGB24_Opt (370 ms)
 88.46% I422ToRGB24Row_AVX2
  5.57% __llvm_libc_google3::memcpy()
  4.16% I422ToRGB24Row_Any_AVX2
  0.54% I422ToRGB24Matrix

R=rrwinterton@gmail.com

Bug: None
Test: libyuv_unittest --gtest_filter=*Any*
Change-Id: Ib8a16eaa7b59b71d8567f9a5f2291b31998486e9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8447593
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-09-22 19:19:45 -07:00
Frank Barchard
f51ad56a3e Multiply_16 port to avx512, rvv, neon 32 bit, and windows
- Also remove redundant neon check for I8MM kernels

======================================================================
CPU                                 Before      After          Speedup
----------------------------------------------------------------------
Intel Granite Rapids (AVX10.1)      251 ms     141 ms   1.78x (+43.8%)
Intel Emerald Rapids (AVX512)       199 ms     108 ms   1.84x (+45.7%)
Intel Sapphire Rapids (AVX512)      230 ms     112 ms   2.05x (+51.3%)
AMD Turin Zen 5 (AVX512)            156 ms      99 ms   1.58x (+36.5%)
AMD Venice Zen 6 (AVX512)           204 ms     106 ms   1.92x (+48.0%)
Intel Skylake-X (AVX512)            320 ms     156 ms   2.05x (+51.2%)
AMD Genoa Zen 4 (AVX512)            236 ms     346 ms   0.68x (-46.6%)
Intel Ice Lake (AVX512)             242 ms     316 ms   0.77x (-30.6%)
AMD Milan Zen 3 (AVX2)              252 ms     230 ms    1.10x (+8.7%)
Intel Haswell (AVX2)                369 ms     456 ms   0.81x (-23.6%)
NVIDIA Grace (SVE2)                 336 ms     337 ms    1.00x (-0.3%)
ARM Neoverse-N1 (NEON)             1081 ms    1105 ms    0.98x (-2.2%)
======================================================================


Bug: 537818862
Change-Id: I3ddeddb040fc52a30dabe7ae2c71d16dda021568
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8343467
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-09-01 19:08:52 -07:00
Frank Barchard
2fcc1272dd Convert8To16 takes bits instead of scale.
- NV16/24 FOURCC and document
- Rotate take uint8* for ubsan

Bug: 537818862
Change-Id: I2bc7109abaffe2464e031e33c22296c007077d82
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8339427
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-09-01 16:07:23 -07:00
Frank Barchard
af714f0810 Convert8To16 use shift to allow scale=65536
- Add avx512bw, neon 32 bit and RVV versions
- Adapt SSE2 to psrlw instead of pmulhuw

CPU                             Before   After    Improvement
---------------------------------------------------------------
Granite Rapids (AVX10)           77 ms    75 ms   +2.6% (1.03x)
Emerald Rapids (AVX512)          75 ms    67 ms  +10.7% (1.12x)
Sapphire Rapids (AVX512)         91 ms    85 ms   +6.6% (1.07x)
AMD Venice Zen 6 (AVX512)        30 ms    30 ms    0.0% (1.00x)
AMD Turin Zen 5 (AVX512)         32 ms    32 ms    0.0% (1.00x)
AMD Genoa Zen 4 (AVX512)         35 ms    36 ms   -2.9% (0.97x)
Skylake-X (AVX512)              119 ms   119 ms    0.0% (1.00x)
Ice Lake (AVX512)                93 ms   104 ms  -11.8% (0.89x)
AMD Milan Zen 3 (AVX2)           43 ms    44 ms   -2.3% (0.98x)
Haswell (AVX2)                  129 ms   138 ms   -7.0% (0.93x)
NVIDIA Grace (SVE2)              42 ms    43 ms   -2.4% (0.98x)
Neoverse-N1 (NEON)               87 ms    87 ms    0.0% (1.00x)
---------------------------------------------------------------


Bug: None
Change-Id: Ia8f310a70c8b1229927fcdf117fe22e131d70ea9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8330912
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-09-01 12:21:37 -07:00
yuanhecai
60102bd795 loongarch: Fix RGBToY SIMD
Add missing RGBToYMatrixRow_Any_{LSX,LASX} and kAddY offset fix so
RAW/RGB24 to YUV works on LoongArch.

Change-Id: I4c990a3705d7f521fa6d0c9e7e01f1e36f81c379
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8292090
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-31 20:57:34 -07:00
Frank Barchard
0c781f87b8 [libyuv] Keep LIBYUV_API in basic_types.h and remove legacy types and bool macros
Reduces include/libyuv/basic_types.h to only define LIBYUV_API.
Directly includes <stdint.h> and <stddef.h> where needed in public
headers.
Replaces LIBYUV_BOOL, LIBYUV_FALSE, and LIBYUV_TRUE with C++ bool,
true, and false in C++ code (MJpegDecoder, unit tests) and int (0, 1)
for C API functions.
Updates documentation and unit tests.

Test: ninja -C out/Release libyuv_unittest && ./out/Release/libyuv_unittest --gtest_filter=*
Change-Id: I2d58e872f0f976263bcda546dcc3b1b5f7e53d58
TAG=agy
CONV=2730bc56-93ff-48ed-b615-dcde1b834394
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8280662
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-28 08:32:19 -07:00
Frank Barchard
969c96cfb4 BlendPlaneRow_AVX512BW and NEON
CPU / Architecture                 Before (C) After (NEON) Improvement
----------------------------------------------------------------------
Cortex-A53 (Pixel 2 XL Little)        3248 ms       792 ms       4.10x
Cortex-A73 (Pixel 2 XL Big)            432 ms       392 ms       1.10x
Cortex-A55 (Pixel 7 Little)            780 ms       563 ms       1.39x
Cortex-A78 (Pixel 7 Mid)               254 ms       170 ms       1.49x
Cortex-X1 (Pixel 7 Big)                158 ms       129 ms       1.22x
Cortex-A510 (Galaxy S22 Little)        816 ms       441 ms       1.85x
Cortex-A710 (Galaxy S22 Mid)           270 ms       129 ms       2.09x
Cortex-X2 (Galaxy S22 Big)             116 ms        80 ms       1.45x
Cortex-A510 (Galaxy S23 Little)        723 ms       373 ms       1.94x
Cortex-A715 (Galaxy S23 Mid)           183 ms       119 ms       1.54x
Cortex-X3 (Galaxy S23 Big)             122 ms        72 ms       1.69x
Lumix C1 Pro (PD2509 Little)           246 ms       156 ms       1.58x
Lumix C1 Premium (PD2509 Mid)          211 ms       112 ms       1.88x
Lumix C1 Ultra (PD2509 Big)             82 ms        50 ms       1.64x
Oryon-v3M (OnePlus Mid)                233 ms       150 ms       1.55x
Oryon-v3L (OnePlus Big)                103 ms        85 ms       1.21x

On Icelake
Function (1280x720)           C     SSSE3     AVX2   AVX-512BW    Gain
----------------------------------------------------------------------
BlendPlane               901 ms    165 ms   135 ms      115 ms   1.17x
I420Blend               1398 ms    287 ms   198 ms      187 ms   1.06x


Bug: 546077674
Change-Id: I189c44cc757c0e26838a7b6fdb2db1cbe5f96f20
TAG=agy
CONV=0f82c25c-616e-4bb3-beeb-981decb0f40c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8297264
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-08-26 17:45:34 -07:00
Frank Barchard
3793561ddc RAWToRGB24 avx2/avx512 use permq/shufb and avx512vbmi
CPU / Arch                 Before (Kernel) After (Kernel)        Delta
----------------------------------------------------------------------
Haswell (x86_64)           263 ms (SSSE3)  263 ms (AVX2)          0.0%
Milan (Zen 3)              115 ms (SSSE3)  138 ms (AVX2)        -20.0%
SapphRap (x86_64)          173 ms (SSSE3)  178 ms (AVX512VBMI)   -2.9%
GNR (Granite R)            191 ms (SSSE3)  189 ms (AVX512VBMI)   +1.0%
Turin (Zen 5)               69 ms (SSSE3)   55 ms (AVX512VBMI)  +20.3%
Icelake (x86_64)           204 ms (SSSE3)  186 ms (AVX512VBMI)   +8.8%
Cascade Lake               237 ms (SSSE3)  229 ms (AVX512BW)     +3.4%
Neoverse (aarch64)*        103 ms (SVE2)   103 ms (SVE2)          0.0%

Bug: None
Change-Id: Ib218632e16b3308a214e9ffcbc745d6c41116c6e
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8280536
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-25 14:37:32 -07:00
Frank Barchard
a0fa632939 Add AVX2 row functions for RGB565, ARGB1555, and ARGB4444
On Icelake:
Was C
I420ToARGB1555_Opt (1230 ms)
I420ToARGB4444_Opt (1195 ms)
I420ToRGB565_Opt (1141 ms)

Now AVX2
I420ToARGB1555_Opt (372 ms)
I420ToARGB4444_Opt (397 ms)
I420ToRGB565_Opt (347 ms)
I420ToRGB24Filter_Opt (567 ms)
I420ToRGB565Dither_Opt (418 ms)
I420ToARGBFilter_Opt (381 ms)
I420ToRGBA_Opt (304 ms)
I420ToBGRA_Opt (296 ms)
I420ToARGB_Opt (257 ms)
I420ToABGR_Opt (254 ms)
I420ToAR30_Opt (215 ms)
I420ToRGB24_Opt (205 ms)
I420ToRAW_Opt (193 ms)

Bug: None
Change-Id: I36cf95d29ba85ae63c549fef7f55cb1fe0f95d8e
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8282746
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-24 19:41:39 -07:00
Frank Barchard
0f36c7f808 STORERGB24 macros for avx512
- improves I420ToRAW performance

I420ToRAW on Skylake
  Was AVX2
    I420ToRAW_Opt (262 ms)
  Now AVX512
    I420ToRAW_Opt (212 ms)

I420ToRAW on Icelake with avx512vbmi
  Was I420ToRAW_Opt (200 ms)
  Now I420ToRAW_Opt (187 ms)

Bug: None
Change-Id: If5b171801ba931557d379696fc128d9b155f7c44
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8267746
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-08-18 14:18:47 -07:00
Wan-Teh Chang
d67b51303d Revert "Add the ARGBToRGB565Row_SSE2() function back"
This reverts commit 87c797b3c29cc6fb233fc329a93aace2942ba2d9.

Reason for revert: Only commit 8aeb3a9 needs the workaround

Original change's description:
> Add the ARGBToRGB565Row_SSE2() function back
>
> Add the ARGBToRGB565Row_SSE2() and ARGBToRGB565Row_Any_SSE2() functions
> back because they hide the unaligned access in ARGBToRGB565Row_C().
>
> To reproduce the unalgined access error, run the following command in
> Google's internal repository:
>   blaze test --config=asan third_party/libyuv:libyuv_test \
>   --test_filter=LibYUVConvertTest.I420ToARGBToRGB565_Unaligned
>
> Bug: b:547803993
> Change-Id: I9cc6b643bc007c100dfc092ef3ec814428789219
> Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265046
> Commit-Queue: Wan-Teh Chang <wtc@google.com>
> Reviewed-by: Frank Barchard <fbarchard@google.com>

Bug: b:547803993
Change-Id: I904126f032f4ed37c470d8972152a137ca315168
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8258919
Reviewed-by: Frank Barchard <fbarchard@google.com>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-17 14:43:10 -07:00
Wan-Teh Chang
87c797b3c2 Add the ARGBToRGB565Row_SSE2() function back
Add the ARGBToRGB565Row_SSE2() and ARGBToRGB565Row_Any_SSE2() functions
back because they hide the unaligned access in ARGBToRGB565Row_C().

To reproduce the unalgined access error, run the following command in
Google's internal repository:
  blaze test --config=asan third_party/libyuv:libyuv_test \
  --test_filter=LibYUVConvertTest.I420ToARGBToRGB565_Unaligned

Bug: b:547803993
Change-Id: I9cc6b643bc007c100dfc092ef3ec814428789219
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265046
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-17 13:09:01 -07:00
Frank Barchard
c20b35a7bc I420ToAR30 add avx512bw support
Benchmark for 720p 1000 images
CPU Architecture          AVX2 (us)   AVX512 (us)   Speedup    Change
---------------------------------------------------------------------
Intel Skylake                325          229        1.42x     -29.5%
Intel Cascade Lake           289          213        1.36x     -26.3%
Intel Granite Rapids         209          168        1.24x     -19.6%
AMD Zen 4                    168          165        1.02x      -1.8%
AMD Zen 5 (Turin)            180          112        1.61x     -37.8%

Bug: None
Change-Id: I3d07c9b36196305ba7ff63973246c080ff872367
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8251940
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
2026-08-13 15:40:19 -07:00
Wan-Teh Chang
79d22698bc Add static_assert to source/row_any.cc
Bug: chromium:543078936
Change-Id: Idd25a8cd987e5295788173dce3cc2ec8c55e9bff
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8230873
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-11 18:28:15 -07:00
Frank Barchard
eac1ea9744 I410ToI420 use 1 step HalfWidthRow function for UV
On Icelake
Was C+AVX512
I410ToI420_Opt (593 ms)
I412ToI420_Opt (581 ms)
Now AVX512
I410ToI420_Opt (241 ms)
I412ToI420_Opt (227 ms)
 60.28% HalfWidthRow_16To8_AVX512BW
 32.34% Convert16To8Row_AVX512BW

Samsung S25 Oryon
Was C+NEON
I410ToI420_Opt (141 ms)
I412ToI420_Opt (127 ms)
Now NEON
I410ToI420_Opt (89 ms)
I412ToI420_Opt (88 ms)

Vivo X300 lunix c1
Was C+NEON
I410ToI420_Opt (682 ms)
I412ToI420_Opt (679 ms)
With SVE2 (slow)
I410ToI420_Opt (622 ms)
I412ToI420_Opt (584 ms)
 65.59% HalfWidthRow_16To8_SVE2
 26.74% Convert16To8Row_SVE2
Now NEON
I410ToI420_Opt (412 ms)
I412ToI420_Opt (406 ms)

Bug: chromium:531172025
Change-Id: I1732157f6be660d2a01086f21daf85fe7f7d166f
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8230200
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
2026-08-10 18:19:25 -07:00
Wan-Teh Chang
c409140ff6 Correct vin/vout buffer sizes in ANY21S and ANY13
Tested:
libyuv_unittest --gtest_filter=LibYUVConvertTest.YUY2ToNV12Overflow
libyuv_unittest --gtest_filter=LibYUVPlanarTest.SplitRGBPlaneOverflow
libyuv_unittest --gtest_filter=LibYUVPlanarTest.SplitARGBPlaneOverflow

Bug: chromium:543078936
Change-Id: I45cc5ec912612b09ac720e3bdefa11c8ad503098
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8219514
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-10 14:20:54 -07:00
Wan-Teh Chang
e2a1744681 Correct vin/vout buffer sizes in ANY21CT
Tested:
libyuv_unittest --gtest_filter=LibYUVConvertTest.P010ToARGBMatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P210ToARGBMatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P010ToAR30MatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P210ToAR30MatrixFilterOverflow

Bug: chromium:543078936
Change-Id: I7001c21d3ef9f7a01bf884332ea6ccbdfd7a69d0
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8229574
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-08-10 13:47:24 -07:00
Wan-Teh Chang
60c4b08950 Use standard way of applying ptrdiff_t casts to n
Remove unnecessary ptrdiff_t casts on r.

Change-Id: I36cf40ea1891a9b0e1c3b1ec2f73559040f243b6
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8229575
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
2026-08-10 10:32:01 -07:00
Frank Barchard
5dc477899b Harden I21xToI420 against oversize heights
I21xToI420 (reached via I210ToI420 / I212ToI420): fix integer overflows
in ScalePlaneVertical_16To8() by switching to HalfRow_16To8.

Add a unit test covering the I21x vertical-scale path. Co-authored-by:
Timothy Nikkel <tnikkel@mozilla.com> Test: libyuv_unittest
--gtest_filter=*.I21xToI420NoHeightOverflow

AMD Zen4
 Was LibYUVConvertTest.I210ToI420_Opt (81 ms)
  30.32% Convert16To8Row_AVX2
  29.81% Convert16To8Row_AVX512BW
  25.72% InterpolateRow_16To8_AVX2

 Now LibYUVConvertTest.I210ToI420_Opt (56 ms)
  41.32% Convert16To8Row_AVX512BW
  40.13% HalfRow_16To8_AVX512BW

Vivo X300 (ARM Lunix C1 Ultra)
 Was LibYUVConvertTest.I210ToI420_Opt (89 ms)
  38.95% InterpolateRow_16To8_NEON
  37.25% Convert16To8Row_NEON

 Now LibYUVConvertTest.I210ToI420_Opt (85 ms)
  47.26% Convert16To8Row_SVE2
  30.39% HalfRow_16To8_SVE2

Bug: chromium:531172025
Change-Id: I23e1215030c40b8577d58617098a8aeec27dd99a
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8221883
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-08 12:11:18 -07:00
Frank Barchard
7138e0a2a7 Make RGBToY a 1 pass avx512bw
- RGBToARGB use vpermi2q+vpshufb
- direct RGBToY for avx512 and rvv

+----------+----------+-------------+----------+---------+-----------+
| ARGBToY  | ARGBToUV | ARGBToUV444 | RGBToY   | RGBToUV | RGBToUV444|
+----------+----------+-------------+----------+---------+-----------+
| avx512bw | avx512bw | avx512bw    | avx512bw | 2 step  | 2 step    |
| avx2     | avx2     | avx2        | 2 step   | 2 step  | 2 step    |
| ssse3    | ssse3    | ssse3       | 2 step   | 2 step  | 2 step    |
| dot      | i8mm     | i8mm        | dot      | neon    | neon      |
| sve2     | sve2     | -           | -        | -       | -         |
| sme      | sme      | -           | -        | -       | -         |
| rvv      | rvv      | rvv         | rvv      | rvv     | rvv       |
+----------+----------+-------------+----------+---------+-----------+


Bug: 42280902
Change-Id: I9f83bf3039431f9fb5391bd7d9eb393e186d6bcf
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8175442
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-08-03 17:53:19 -07:00
Frank Barchard
0148582bb8 Change all 1 use wrappers to matrix calls
Bug: 42280902
Change-Id: Ieccb1e8eeaec3064fc5d36d2f1233fd38eb2a128
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8177647
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-07-31 17:29:30 -07:00
Frank Barchard
1a746db4ce Remove unused wrappers for 'matrix' functions
Bug: 42280902
Change-Id: Idbc757e10d1bcf276ce00dbdd07a39f4ad01a5af
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8177664
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-07-30 19:03:49 -07:00
Frank Barchard
86a4d94d7a I420ToRAW and I420ToRGB24 1 pass AVX2 and AVX512VBMI
- Implemented `I422ToRGB24Row_AVX2` and `I422ToRGB24Row_AVX512VBMI` in:
 - `row_gcc.cc`: Inline assembly for GCC/Clang.
 - `row_win.cc`: C++ intrinsics for MSVC (also verified with Clang).

Reduced width alignment requirement: changed from 32-pixel to 16-pixel
alignment in `convert_argb.cc` and `row_any.cc`. This allows the AVX2
path to be used for more common video resolutions.

```
I420ToRAW vs Rust on Icelake Xeon
Size        I420ToRAW     yuv420_to_rgb  iterations
-------     ---------   ---------------  ----------
640x480         57 us    77.377 µs/iter     3000
1280x720       170 us   221.671 µs/iter     1000
1920x1080      396 us   494.324 µs/iter      500
3840x2160     2040 us      2357 µs/iter      200
```

Bug: 42280902
Change-Id: I07c0505c95410ea16a6218c858844791a11ef073
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7908323
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-07-20 18:15:10 -07:00
Frank Barchard
3bdb3b94ca I420ToRAW use 2 step AVX512
On Icelake
Was AVX2
I420ToRAW_Opt (283 ms)
  67.55%  I422ToARGBRow_AVX2
  26.46%  ARGBToRGB24Row_AVX2

Now AVX512VBMI
I420ToRAW_Opt (238 ms)
  73.08%  I422ToARGBRow_AVX512BW
  21.59%  ARGBToRGB24Row_AVX512VBMI

Bug: 42280902
Change-Id: I9d4d21faed30c529a5e593819f103be115709f37
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7909924
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-06-08 14:32:13 -07:00
Frank Barchard
4be798d7c5 BGRAToI420 use BgraConstants for a direct conversion using AVX512BW
row win (msvc)
Was C/SSSE3
BGRAToARGB_Opt (594 ms)
BGRAToARGB_Endswap_Opt (609 ms)
BGRAToI420_Opt (122 ms)

Now AVX2
BGRAToARGB_Opt (100 ms)
BGRAToARGB_Endswap_Opt (99 ms)
BGRAToI420_Opt (115 ms)

Clang/GCC AVX512BW
BGRAToARGB_Opt (86 ms)
BGRAToARGB_Endswap_Opt (91 ms)
BGRAToI420_Opt (110 ms)


Bug: 42280902
Change-Id: I52cb2b0cacea8f2f0b138ec3cc521185dbef8595
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7905821
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-06-08 12:21:47 -07:00
Frank Barchard
e14b0e2c60 RGB565ToARGB use AVX2 instead of SSE2
Now AVX2/AVX512
ARGB4444ToI420_Opt (204 ms)
RGB565ToI420_Opt (211 ms)
ARGB1555ToI420_Opt (231 ms)
RAWToI420_Opt (197 ms)
RGB24ToI420_Opt (197 ms)

Was SSE2/AVX2
ARGB4444ToI420_Opt (276 ms)
RGB565ToI420_Opt (292 ms)
ARGB1555ToI420_Opt (332 ms)
RAWToI420_Opt (237 ms)
RGB24ToI420_Opt (232 ms)

Bug: libyuv:508639302
Change-Id: I2005189d1b6af15cb5ebef1f6d66b426fa9df8eb
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7891416
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-06-02 18:28:02 -07:00
Frank Barchard
e449eb2172 J400ToARGB switch from SSE2 to AVX2
- port for row_win
- remove unused HAS_ macros

Was C/SSE2
MSVC  J400ToARGB_Opt (1967 ms)
Clang J400ToARGB_Opt (568 ms)

Now AVX2
MSVC  J400ToARGB_Opt (411 ms)
Clang J400ToARGB_Opt (418 ms)

Test: libyuv_unittest --gtest_filter=*J400ToARGB*
Bug: libyuv:508639302

Change-Id: Ifdfb026832b708b61f55477250cc5ee52449f421
TAG=agy
CONV=186608fc-966a-4ea7-bf57-9fe07cc1383c
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7877368
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Justin Green <greenjustin@google.com>
2026-05-28 21:24:32 -07:00
Wan-Teh Chang
904f562d86 Remove redundant #include <stddef.h>
"libyuv/basic_types.h" includes <stddef.h>. So it is not necessary to
include both <stddef.h> and "libyuv/basic_types.h".

Change-Id: I5a461258a3c6820d1007ac635838f910237f367f
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7884381
Reviewed-by: Frank Barchard <fbarchard@google.com>
2026-05-28 17:10:22 -07:00
Frank Barchard
9d98aaefe7 InterpolateRow for Visual C
- remove InterpolateRow_SSSE3
- optimize ARGBToUV444MatrixRow_AVX2 to use unsigned pixels

5.7x faster on AMD Zen4

Was C
TestInterpolatePlane (144 ms)
TestInterpolatePlane_16 (142 ms)

Now AVX2
TestInterpolatePlane (25 ms)
TestInterpolatePlane_16 (48 ms)

Was signed
ARGBToJ444_Opt (157 ms)
Now unsigned
ARGBToJ444_Opt (155 ms)

Bug: None
Change-Id: I903109668ff9cfedaddad1ad75411393b3226f41
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7856498
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-05-18 17:28:46 -07:00
Frank Barchard
9f751100d2 InterpolateRow_16_AVX2 for row_gcc
On AMD Zen4
Was C
TestInterpolatePlane_16 (143 ms)
Now AVX2
TestInterpolatePlane_16 (48 ms)

Was
I210ToI420_Opt (87 ms)
 35.60% InterpolateRow_16To8_AVX2
 31.03% Convert16To8Row_AVX512BW
 21.35% Convert16To8Row_AVX2

Now
I210ToI420_Opt (69 ms)
 37.57% Convert16To8Row_AVX512BW
 32.69% InterpolateRow_16_AVX2
  7.18% Convert16To8Row_AVX2
  5.23% InterpolateRow_16To8_AVX2

Bug: None
Change-Id: Ica9b9c5dbd847068ae076b682c487e1753d3c812
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7855648
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Frank Barchard <fbarchard@google.com>
2026-05-18 14:29:36 -07:00
Frank Barchard
cda55fcf53 Mirrow AVX2 functions for Visual C
Bug: libyuv:42280902
Change-Id: Iabbec9af3a4f4dd89294e60145823c7fc4dd6ec6
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7843378
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-05-15 15:05:31 -07:00
Frank Barchard
561a9780e2 YUV to RGB avoid avx assist
Here are the functions flagged for mixing both SSE and AVX (or AVX-512)
instructions, which can trigger an AVX transition/assist performance
penalty:

Libyuv Functions addressed in this CL
   * I422ToARGBRow_AVX512BW
   * HalfFloatRow_SSE2

Not addressed:
   * ScaleFilterCols_SSSE3

Bug: libyuv:509681367
Change-Id: I8ced6065dfe0c516d05857086393782c8590062a
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7814945
Reviewed-by: richard winterton <rrwinterton@gmail.com>
2026-05-05 12:57:55 -07:00
Frank Barchard
2143edfa7a ARGBToUVMatrixRow_NEON arm32 reimplemented for GCC
Bug: libyuv:508639302
Change-Id: Ib120373d799c66926a64c980873034be262d8848
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7810481
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Justin Green <greenjustin@google.com>
2026-05-04 11:38:45 -07:00