diff mbox series

[FFmpeg-devel] lavu: add/use flag for RISC-V Zba extension

Message ID 20230716123454.104057-1-remi@remlab.net
State Accepted
Commit b6585eb04c0f63f231ed16266c6ad893522dc750
Headers show
Series [FFmpeg-devel] lavu: add/use flag for RISC-V Zba extension | expand

Checks

Context Check Description
andriy/configure_x86 warning Failed to apply patch
yinshiyou/configure_loongarch64 warning Failed to apply patch

Commit Message

Rémi Denis-Courmont July 16, 2023, 12:34 p.m. UTC
The code was blindly assuming that Zbb or V implied Zba. While the
earlier is practically always true, the later broke some QEMU setups,
as V was introduced earlier than Zba.
---
 libavcodec/riscv/aacpsdsp_init.c          | 11 ++++++---
 libavcodec/riscv/alacdsp_init.c           |  2 +-
 libavcodec/riscv/audiodsp_init.c          | 12 +++++----
 libavcodec/riscv/bswapdsp_init.c          | 16 ++++++------
 libavcodec/riscv/fmtconvert_init.c        |  2 +-
 libavcodec/riscv/h264_chroma_init_riscv.c |  3 ++-
 libavcodec/riscv/vorbisdsp_init.c         |  2 +-
 libavutil/cpu.c                           |  1 +
 libavutil/cpu.h                           |  1 +
 libavutil/riscv/cpu.c                     |  5 +++-
 libavutil/riscv/fixed_dsp_init.c          |  2 +-
 libavutil/riscv/float_dsp_init.c          | 30 ++++++++++++-----------
 libswscale/riscv/rgb2rgb.c                |  2 +-
 tests/checkasm/checkasm.c                 |  1 +
 14 files changed, 53 insertions(+), 37 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/riscv/aacpsdsp_init.c b/libavcodec/riscv/aacpsdsp_init.c
index f42baf4251..c5ec796232 100644
--- a/libavcodec/riscv/aacpsdsp_init.c
+++ b/libavcodec/riscv/aacpsdsp_init.c
@@ -43,13 +43,16 @@  av_cold void ff_psdsp_init_riscv(PSDSPContext *c)
     int flags = av_get_cpu_flags();
 
     if (flags & AV_CPU_FLAG_RVV_F32) {
-        c->add_squares = ff_ps_add_squares_rvv;
-        c->mul_pair_single = ff_ps_mul_pair_single_rvv;
         c->hybrid_analysis = ff_ps_hybrid_analysis_rvv;
-        c->stereo_interpolate[0] = ff_ps_stereo_interpolate_rvv;
+
+        if (flags & AV_CPU_FLAG_RVB_ADDR) {
+            c->add_squares = ff_ps_add_squares_rvv;
+            c->mul_pair_single = ff_ps_mul_pair_single_rvv;
+            c->stereo_interpolate[0] = ff_ps_stereo_interpolate_rvv;
+        }
     }
 
-    if (flags & AV_CPU_FLAG_RVV_I32) {
+    if ((flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB_ADDR)) {
         c->hybrid_analysis_ileave = ff_ps_hybrid_analysis_ileave_rvv;
         c->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_rvv;
     }
diff --git a/libavcodec/riscv/alacdsp_init.c b/libavcodec/riscv/alacdsp_init.c
index fa8a7c8129..cd6dc4f8ae 100644
--- a/libavcodec/riscv/alacdsp_init.c
+++ b/libavcodec/riscv/alacdsp_init.c
@@ -41,7 +41,7 @@  av_cold void ff_alacdsp_init_riscv(ALACDSPContext *c)
 #if HAVE_RVV && (__riscv_xlen == 64)
     int flags = av_get_cpu_flags();
 
-    if (flags & AV_CPU_FLAG_RVV_I32) {
+    if ((flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB_ADDR)) {
         c->decorrelate_stereo = ff_alac_decorrelate_stereo_rvv;
         c->append_extra_bits[0] = ff_alac_append_extra_bits_mono_rvv;
         c->append_extra_bits[1] = ff_alac_append_extra_bits_stereo_rvv;
diff --git a/libavcodec/riscv/audiodsp_init.c b/libavcodec/riscv/audiodsp_init.c
index 32c3c6794d..9ab59c011e 100644
--- a/libavcodec/riscv/audiodsp_init.c
+++ b/libavcodec/riscv/audiodsp_init.c
@@ -38,11 +38,13 @@  av_cold void ff_audiodsp_init_riscv(AudioDSPContext *c)
     if (flags & AV_CPU_FLAG_RVF)
         c->vector_clipf = ff_vector_clipf_rvf;
 #if HAVE_RVV
-    if (flags & AV_CPU_FLAG_RVV_I32) {
-        c->scalarproduct_int16 = ff_scalarproduct_int16_rvv;
-        c->vector_clip_int32 = ff_vector_clip_int32_rvv;
+    if (flags & AV_CPU_FLAG_RVB_ADDR) {
+        if (flags & AV_CPU_FLAG_RVV_I32) {
+            c->scalarproduct_int16 = ff_scalarproduct_int16_rvv;
+            c->vector_clip_int32 = ff_vector_clip_int32_rvv;
+        }
+        if (flags & AV_CPU_FLAG_RVV_F32)
+            c->vector_clipf = ff_vector_clipf_rvv;
     }
-    if (flags & AV_CPU_FLAG_RVV_F32)
-        c->vector_clipf = ff_vector_clipf_rvv;
 #endif
 }
diff --git a/libavcodec/riscv/bswapdsp_init.c b/libavcodec/riscv/bswapdsp_init.c
index abe84ec1f7..6ad63e3805 100644
--- a/libavcodec/riscv/bswapdsp_init.c
+++ b/libavcodec/riscv/bswapdsp_init.c
@@ -31,16 +31,18 @@  void ff_bswap16_buf_rvv(uint16_t *dst, const uint16_t *src, int len);
 
 av_cold void ff_bswapdsp_init_riscv(BswapDSPContext *c)
 {
-    int cpu_flags = av_get_cpu_flags();
+    int flags = av_get_cpu_flags();
 
+    if (flags & AV_CPU_FLAG_RVB_ADDR) {
 #if (__riscv_xlen >= 64)
-    if (cpu_flags & AV_CPU_FLAG_RVB_BASIC)
-        c->bswap_buf = ff_bswap32_buf_rvb;
+        if (flags & AV_CPU_FLAG_RVB_BASIC)
+            c->bswap_buf = ff_bswap32_buf_rvb;
 #endif
 #if HAVE_RVV
-    if (cpu_flags & AV_CPU_FLAG_RVV_I32) {
-        c->bswap_buf = ff_bswap32_buf_rvv;
-        c->bswap16_buf = ff_bswap16_buf_rvv;
-    }
+        if (flags & AV_CPU_FLAG_RVV_I32) {
+            c->bswap_buf = ff_bswap32_buf_rvv;
+            c->bswap16_buf = ff_bswap16_buf_rvv;
+        }
 #endif
+    }
 }
diff --git a/libavcodec/riscv/fmtconvert_init.c b/libavcodec/riscv/fmtconvert_init.c
index 2ded9d3615..f5eeafba45 100644
--- a/libavcodec/riscv/fmtconvert_init.c
+++ b/libavcodec/riscv/fmtconvert_init.c
@@ -36,7 +36,7 @@  av_cold void ff_fmt_convert_init_riscv(FmtConvertContext *c)
 #if HAVE_RVV
     int flags = av_get_cpu_flags();
 
-    if (flags & AV_CPU_FLAG_RVV_F32) {
+    if ((flags & AV_CPU_FLAG_RVV_F32) && (flags & AV_CPU_FLAG_RVB_ADDR)) {
         c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_rvv;
         c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_rvv;
     }
diff --git a/libavcodec/riscv/h264_chroma_init_riscv.c b/libavcodec/riscv/h264_chroma_init_riscv.c
index 7c905edfcd..f3e912823b 100644
--- a/libavcodec/riscv/h264_chroma_init_riscv.c
+++ b/libavcodec/riscv/h264_chroma_init_riscv.c
@@ -33,7 +33,8 @@  av_cold void ff_h264chroma_init_riscv(H264ChromaContext *c, int bit_depth)
 #if HAVE_RVV
     int flags = av_get_cpu_flags();
 
-    if (bit_depth == 8 && (flags & AV_CPU_FLAG_RVV_I32) && ff_get_rv_vlenb() >= 16) {
+    if (bit_depth == 8 && (flags & AV_CPU_FLAG_RVV_I32) &&
+        (flags & AV_CPU_FLAG_RVB_ADDR) && ff_get_rv_vlenb() >= 16) {
         c->put_h264_chroma_pixels_tab[0] = h264_put_chroma_mc8_rvv;
         c->avg_h264_chroma_pixels_tab[0] = h264_avg_chroma_mc8_rvv;
     }
diff --git a/libavcodec/riscv/vorbisdsp_init.c b/libavcodec/riscv/vorbisdsp_init.c
index 0c56ffcb9b..0bbbcb68de 100644
--- a/libavcodec/riscv/vorbisdsp_init.c
+++ b/libavcodec/riscv/vorbisdsp_init.c
@@ -31,7 +31,7 @@  av_cold void ff_vorbisdsp_init_riscv(VorbisDSPContext *c)
 #if HAVE_RVV
     int flags = av_get_cpu_flags();
 
-    if (flags & AV_CPU_FLAG_RVV_I32)
+    if ((flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB_ADDR))
         c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_rvv;
 #endif
 }
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 2ffc3986aa..1e0607d581 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -190,6 +190,7 @@  int av_parse_cpu_caps(unsigned *flags, const char *s)
         { "rvv-f32",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_F32 },     .unit = "flags" },
         { "rvv-i64",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_I64 },     .unit = "flags" },
         { "rvv",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVV_F64 },     .unit = "flags" },
+        { "rvb-addr",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVB_ADDR },   .unit = "flags" },
         { "rvb-basic",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_RVB_BASIC },   .unit = "flags" },
 #endif
         { NULL },
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index da486f9c7a..8dff341886 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -89,6 +89,7 @@ 
 #define AV_CPU_FLAG_RVV_I64      (1 << 5) ///< Vectors of 64-bit int's */
 #define AV_CPU_FLAG_RVV_F64      (1 << 6) ///< Vectors of double's
 #define AV_CPU_FLAG_RVB_BASIC    (1 << 7) ///< Basic bit-manipulations
+#define AV_CPU_FLAG_RVB_ADDR     (1 << 8) ///< Address bit-manipulations
 
 /**
  * Return the flags which specify extensions supported by the CPU.
diff --git a/libavutil/riscv/cpu.c b/libavutil/riscv/cpu.c
index a9263dbb78..fa45c0ad83 100644
--- a/libavutil/riscv/cpu.c
+++ b/libavutil/riscv/cpu.c
@@ -41,7 +41,7 @@  int ff_get_cpu_flags_riscv(void)
     if (hwcap & HWCAP_RV('D'))
         ret |= AV_CPU_FLAG_RVD;
     if (hwcap & HWCAP_RV('B'))
-        ret |= AV_CPU_FLAG_RVB_BASIC;
+        ret |= AV_CPU_FLAG_RVB_ADDR | AV_CPU_FLAG_RVB_BASIC;
 
     /* The V extension implies all Zve* functional subsets */
     if (hwcap & HWCAP_RV('V'))
@@ -59,6 +59,9 @@  int ff_get_cpu_flags_riscv(void)
 #endif
 #endif
 
+#ifdef __riscv_zba
+    ret |= AV_CPU_FLAG_RVB_ADDR;
+#endif
 #ifdef __riscv_zbb
     ret |= AV_CPU_FLAG_RVB_BASIC;
 #endif
diff --git a/libavutil/riscv/fixed_dsp_init.c b/libavutil/riscv/fixed_dsp_init.c
index e2915f1fcd..d4ca2e2064 100644
--- a/libavutil/riscv/fixed_dsp_init.c
+++ b/libavutil/riscv/fixed_dsp_init.c
@@ -32,7 +32,7 @@  av_cold void ff_fixed_dsp_init_riscv(AVFixedDSPContext *fdsp)
 #if HAVE_RVV
     int flags = av_get_cpu_flags();
 
-    if (flags & AV_CPU_FLAG_RVV_I32)
+    if ((flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB_ADDR))
         fdsp->butterflies_fixed = ff_butterflies_fixed_rvv;
 #endif
 }
diff --git a/libavutil/riscv/float_dsp_init.c b/libavutil/riscv/float_dsp_init.c
index e61f887862..585f237225 100644
--- a/libavutil/riscv/float_dsp_init.c
+++ b/libavutil/riscv/float_dsp_init.c
@@ -52,21 +52,23 @@  av_cold void ff_float_dsp_init_riscv(AVFloatDSPContext *fdsp)
 #if HAVE_RVV
     int flags = av_get_cpu_flags();
 
-    if (flags & AV_CPU_FLAG_RVV_F32) {
-        fdsp->vector_fmul = ff_vector_fmul_rvv;
-        fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_rvv;
-        fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_rvv;
-        fdsp->vector_fmul_window = ff_vector_fmul_window_rvv;
-        fdsp->vector_fmul_add = ff_vector_fmul_add_rvv;
-        fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_rvv;
-        fdsp->butterflies_float = ff_butterflies_float_rvv;
-        fdsp->scalarproduct_float = ff_scalarproduct_float_rvv;
-    }
+    if (flags & AV_CPU_FLAG_RVB_ADDR) {
+        if (flags & AV_CPU_FLAG_RVV_F32) {
+            fdsp->vector_fmul = ff_vector_fmul_rvv;
+            fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_rvv;
+            fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_rvv;
+            fdsp->vector_fmul_window = ff_vector_fmul_window_rvv;
+            fdsp->vector_fmul_add = ff_vector_fmul_add_rvv;
+            fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_rvv;
+            fdsp->butterflies_float = ff_butterflies_float_rvv;
+            fdsp->scalarproduct_float = ff_scalarproduct_float_rvv;
+        }
 
-    if (flags & AV_CPU_FLAG_RVV_F64) {
-        fdsp->vector_dmul = ff_vector_dmul_rvv;
-        fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_rvv;
-        fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_rvv;
+        if (flags & AV_CPU_FLAG_RVV_F64) {
+            fdsp->vector_dmul = ff_vector_dmul_rvv;
+            fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_rvv;
+            fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_rvv;
+        }
     }
 #endif
 }
diff --git a/libswscale/riscv/rgb2rgb.c b/libswscale/riscv/rgb2rgb.c
index 37a2cd5ea1..4c2d0f07d2 100644
--- a/libswscale/riscv/rgb2rgb.c
+++ b/libswscale/riscv/rgb2rgb.c
@@ -45,7 +45,7 @@  av_cold void rgb2rgb_init_riscv(void)
 #if HAVE_RVV
     int flags = av_get_cpu_flags();
 
-    if (flags & AV_CPU_FLAG_RVV_I32) {
+    if ((flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB_ADDR)) {
         shuffle_bytes_0321 = ff_shuffle_bytes_0321_rvv;
         shuffle_bytes_2103 = ff_shuffle_bytes_2103_rvv;
         shuffle_bytes_1230 = ff_shuffle_bytes_1230_rvv;
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 4fb2cb8dab..8d1e24d94b 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -248,6 +248,7 @@  static const struct {
     { "RVI",      "rvi",      AV_CPU_FLAG_RVI },
     { "RVF",      "rvf",      AV_CPU_FLAG_RVF },
     { "RVD",      "rvd",      AV_CPU_FLAG_RVD },
+    { "RVBaddr",  "rvb_a",    AV_CPU_FLAG_RVB_ADDR },
     { "RVBbasic", "rvb_b",    AV_CPU_FLAG_RVB_BASIC },
     { "RVVi32",   "rvv_i32",  AV_CPU_FLAG_RVV_I32 },
     { "RVVf32",   "rvv_f32",  AV_CPU_FLAG_RVV_F32 },