RVV port to inline from intrinsics

- avoids intrinsics API changes
- build options for rvv not needed for inline instructions
- declare vl and vtype clobbers instead of cc
- tune for SiFive X280 using 16/32-bit loads and stores instead of
  vlseg/vsseg where more efficient
- tune LMUL for SpacemiT K3 (256-bit vectors) with max m4 (m2 where
  constrained by register pressure or vlseg/vsseg field rules)
- YUVTORGB use vmulhu

NV12ToARGB performance estimates:
CPU           VLEN      C       Intrinsics  Inline ASM  Speedup (Inline)
------------------------------------------------------------------------
SiFive X390  1024-bit  360 ms     29 ms       9.5 ms     37.89x (3.05x)
SiFive X280   512-bit  980 ms    115 ms      38.0 ms     25.79x (3.03x)
SpacemiT K3   256-bit  420 ms     68 ms      28.0 ms     15.00x (2.43x)
Google Coral  256-bit 1120 ms    190 ms      58.0 ms     19.31x (3.28x)
T-Head C920   128-bit  510 ms     88 ms      39.0 ms     13.08x (2.26x)
T-Head C908   128-bit  860 ms    145 ms      62.0 ms     13.87x (2.34x)

Bug: b/443984359
Change-Id: If4097b99ced4cc2306f12236b8605994e713eecd
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8426529
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
This commit is contained in:
Frank Barchard 2026-09-21 12:43:53 -07:00 committed by libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 715a84778e
commit 7c85a3a082
7 changed files with 2944 additions and 3345 deletions

View File

@ -1,6 +1,6 @@
Name: libyuv
URL: https://chromium.googlesource.com/libyuv/libyuv/
Version: 1971
Version: 1972
Revision: DEPS
License: BSD-3-Clause
License File: LICENSE

View File

@ -627,14 +627,17 @@ extern "C" {
#define HAS_ARGBTOYMATRIXROW_SVE2
#define HAS_AYUVTOUVROW_SVE2
#define HAS_AYUVTOVUROW_SVE2
// #define HAS_CONVERT16TO8ROW_SVE2 // Disabled: NEON version is faster for 128 bit vectors.
// Disabled: NEON version is faster for 128 bit vectors.
// #define HAS_CONVERT16TO8ROW_SVE2
#define HAS_CONVERT8TO8ROW_SVE2
#define HAS_COPYROW_SVE2
#define HAS_DIVIDEROW_16_SVE2
#define HAS_HALFFLOATROW_SVE2
#define HAS_HALFMERGEUVROW_SVE2
// #define HAS_HALFROW_16TO8_SVE2 // Disabled: NEON version is faster for 128 bit vectors.
// #define HAS_HALFWIDTHROW_16TO8_SVE2 // Disabled: NEON version is faster for 128 bit vectors.
// Disabled: NEON version is faster for 128 bit vectors.
// #define HAS_HALFROW_16TO8_SVE2
// Disabled: NEON version is faster for 128 bit vectors.
// #define HAS_HALFWIDTHROW_16TO8_SVE2
#define HAS_I210ALPHATOARGBROW_SVE2
#define HAS_I210TOAR30ROW_SVE2
#define HAS_I210TOARGBROW_SVE2
@ -857,20 +860,6 @@ extern "C" {
#define HAS_YUY2TOYROW_LASX
#endif
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector)
#if defined(__riscv_v_intrinsic) && __riscv_v_intrinsic >= 100000
// Since v1.0, vcreate intrinsic is introduced
#define LIBYUV_RVV_HAS_VCREATE
#endif
#if defined(__riscv_v_intrinsic) && __riscv_v_intrinsic >= 12000
// Since v0.12, TUPLE_TYPE is introduced for segment load and store.
#define LIBYUV_RVV_HAS_TUPLE_TYPE
// Since v0.12, VXRM(fixed-point rounding mode) is included in arguments of
// fixed-point intrinsics.
#define LIBYUV_RVV_HAS_VXRM_ARG
#endif
#endif
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector)
#define HAS_AR64TOARGBROW_RVV
#define HAS_ARGBCOPYYTOALPHAROW_RVV
@ -896,20 +885,6 @@ extern "C" {
#define HAS_SPLITUVROW_RVV
#define HAS_SPLITXRGBROW_RVV
#define HAS_SWAPUVROW_RVV
// The following are available for RVV v0.11 and RVV v1.0
// TODO(fbarchard): Port to RVV v0.12 (tuple)
// missing support for vcreate_v:
// __riscv_vcreate_v_u16m2x2
// __riscv_vcreate_v_u16m2x4
// __riscv_vcreate_v_u16m4x2
// __riscv_vcreate_v_u8m1x3
// __riscv_vcreate_v_u8m1x4
// __riscv_vcreate_v_u8m2x2
// __riscv_vcreate_v_u8m2x3
// __riscv_vcreate_v_u8m2x4
// __riscv_vcreate_v_u8m4x2
#if defined(LIBYUV_RVV_HAS_VCREATE)
#define HAS_AB64TOARGBROW_RVV
#define HAS_AR64TOAB64ROW_RVV
#define HAS_ARGBATTENUATEROW_RVV
@ -944,7 +919,6 @@ extern "C" {
#define HAS_RGB24TOARGBROW_RVV
#define HAS_RGBATOARGBROW_RVV
#endif
#endif
#if defined(_MSC_VER) && !defined(__CLR_VER) && !defined(__clang__)
#if defined(VISUALC_HAS_AVX2)

View File

@ -151,19 +151,9 @@ extern "C" {
#define HAS_SCALEROWDOWN34_LSX
#endif
// The following are available on RVV with 64 bit elements
// TODO: Update compiler to support 64 bit
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector) && \
defined(__riscv_zve64x)
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector)
#define HAS_SCALEUVROWDOWN4_RVV
#define HAS_SCALEARGBROWDOWN2_RVV
#endif
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector) && \
defined(__riscv_v_intrinsic)
// The following are available on RVV v0.11 and RVV v1.0
// TODO: Port to RVV v0.12
#if __riscv_v_intrinsic == 11000 || __riscv_v_intrinsic >= 100000
#define HAS_SCALEROWDOWN34_0_BOX_RVV
#define HAS_SCALEROWDOWN34_1_BOX_RVV
#define HAS_SCALEROWDOWN38_2_BOX_RVV
@ -190,13 +180,8 @@ extern "C" {
#define HAS_SCALEUVROWDOWN2_RVV
#define HAS_SCALEUVROWDOWN2BOX_RVV
#define HAS_SCALEUVROWDOWN2LINEAR_RVV
#endif
// The following are available on RVV v0.11
#if __riscv_v_intrinsic == 11000
#define HAS_SCALEARGBFILTERCOLS_RVV
#endif
#endif
// Scale ARGB vertically with bilinear interpolation.
void ScalePlaneVertical(int src_height,

View File

@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1971
#define LIBYUV_VERSION 1972
#endif // INCLUDE_LIBYUV_VERSION_H_

View File

@ -304,7 +304,7 @@ LIBYUV_API SAFEBUFFERS int RiscvCpuCaps(const char* cpuinfo_name) {
int flag = 0;
FILE* f = fopen(cpuinfo_name, "re");
if (!f) {
#if defined(__riscv_vector)
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv) && __riscv_xlen == 64
// Assume RVV if /proc/cpuinfo is unavailable.
// This will occur for Chrome sandbox for Pepper or Render process.
return kCpuHasRVV;
@ -364,7 +364,7 @@ LIBYUV_API SAFEBUFFERS int RiscvCpuCaps(const char* cpuinfo_name) {
}
}
}
#if defined(__riscv_vector)
#if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv) && __riscv_xlen == 64
// Assume RVV if /proc/cpuinfo is from x86 host running QEMU.
else if ((memcmp(cpuinfo_line, "vendor_id\t: GenuineIntel", 24) == 0) ||
(memcmp(cpuinfo_line, "vendor_id\t: AuthenticAMD", 24) == 0)) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff