Commit 429133adf3 for ffmpeg
commit 429133adf34fa7fb9e1c762c80f01865f78f8539
Author: Ramiro Polla <ramiro.polla@gmail.com>
Date: Mon Nov 9 17:11:17 2026 +0100
swscale/aarch64: implement SWS_UOP_ADD
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c
index d479eaa4f8..b35882c854 100644
--- a/libswscale/aarch64/ops.c
+++ b/libswscale/aarch64/ops.c
@@ -137,6 +137,7 @@ static int aarch64_setup(const SwsUOp *uop, const SwsAArch64OpImplParams *p,
break;
}
case SWS_UOP_CLEAR:
+ case SWS_UOP_ADD:
case SWS_UOP_MIN:
case SWS_UOP_MAX: {
int ret = ff_sws_setup_vec4(&(const SwsImplParams) { .uop = uop }, out);
@@ -233,7 +234,7 @@ static int compile_ops_aarch64(SwsContext *ctx, const SwsOpList *ops,
if (!uops)
return AVERROR(ENOMEM);
- SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING;
+ SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING | SWS_UOP_FLAG_ADD;
if (!(ctx->flags & SWS_BITEXACT))
flags |= SWS_UOP_FLAG_FMA;
int ret = ff_sws_ops_translate(ctx, ops, flags, uops);
diff --git a/libswscale/aarch64/ops_asmgen.c b/libswscale/aarch64/ops_asmgen.c
index f698915b61..ffd5e8cbad 100644
--- a/libswscale/aarch64/ops_asmgen.c
+++ b/libswscale/aarch64/ops_asmgen.c
@@ -753,6 +753,25 @@ static void asmgen_op_expand(SwsAArch64Context *s, const SwsAArch64OpImplParams
}
}
+/*********************************************************************/
+/* SWS_UOP_ADD: add vec4 to masked components */
+
+static void asmgen_op_add(SwsAArch64Context *s, const SwsAArch64OpImplParams *p,
+ SwsAArch64OpRegs *regs)
+{
+ RasmContext *r = s->rctx;
+ RasmOp *sl = regs->sl;
+ RasmOp *sh = regs->sh;
+ RasmOp *dl = regs->dl;
+ RasmOp *dh = regs->dh;
+ RasmOp *vk = regs->vk;
+
+ av_assert0(p->type == SWS_PIXEL_F32);
+
+ LOOP_MASK (p, i) { i_fadd(r, dl[i], sl[i], vk[i]); CMTF("vl[%u] += vadd%u;", i, i); }
+ LOOP_MASK_VH(s, p, i) { i_fadd(r, dh[i], sh[i], vk[i]); CMTF("vh[%u] += vadd%u;", i, i); }
+}
+
/*********************************************************************/
/* SWS_UOP_MIN: min(x, vec4) on masked components */
diff --git a/libswscale/aarch64/ops_impl.h b/libswscale/aarch64/ops_impl.h
index 10447638b3..7a6b2370a6 100644
--- a/libswscale/aarch64/ops_impl.h
+++ b/libswscale/aarch64/ops_impl.h
@@ -92,6 +92,7 @@ static inline int aarch64_priv_size(const SwsAArch64OpImplParams *params)
case SWS_UOP_READ_BIT:
case SWS_UOP_WRITE_BIT:
case SWS_UOP_CLEAR:
+ case SWS_UOP_ADD:
case SWS_UOP_MIN:
case SWS_UOP_MAX:
return 16; /* one full vector register */
diff --git a/libswscale/aarch64/ops_static.c b/libswscale/aarch64/ops_static.c
index 52af60ee08..7dbaff726d 100644
--- a/libswscale/aarch64/ops_static.c
+++ b/libswscale/aarch64/ops_static.c
@@ -246,6 +246,18 @@ static void asmgen_setup_clear(SwsAArch64Context *s, const SwsAArch64OpImplParam
}
}
+static void asmgen_setup_add(SwsAArch64Context *s, const SwsAArch64OpImplParams *p,
+ SwsAArch64OpRegs *regs)
+{
+ RasmContext *r = s->rctx;
+ RasmOp *vk = regs->vk;
+
+ RasmOp add_vec = regs->vt[0];
+ i_ldr(r, v_q(add_vec), IMPL_PRIV(s)); CMT("v128 add_vec = impl->priv.v128;");
+ asmgen_set_load_cont_node(s);
+ LOOP_MASK(p, i) { i_dup(r, vk[i], a64op_elem(add_vec, i)); CMTF("v128 vadd%u = add_vec[%u];", i, i); }
+}
+
static void asmgen_setup_min(SwsAArch64Context *s, const SwsAArch64OpImplParams *p,
SwsAArch64OpRegs *regs)
{
@@ -584,6 +596,7 @@ static void asmgen_op_cps(SwsAArch64Context *s, const SwsAArch64OpEntry *entry)
case SWS_UOP_WRITE_BIT: asmgen_setup_write_bit(s, p, &s->regs); break;
case SWS_UOP_UNPACK: asmgen_setup_unpack(s, p, &s->regs); break;
case SWS_UOP_CLEAR: asmgen_setup_clear(s, p, &s->regs); break;
+ case SWS_UOP_ADD: asmgen_setup_add(s, p, &s->regs); break;
case SWS_UOP_MIN: asmgen_setup_min(s, p, &s->regs); break;
case SWS_UOP_MAX: asmgen_setup_max(s, p, &s->regs); break;
case SWS_UOP_SCALE: asmgen_setup_scale(s, p, &s->regs); break;
@@ -618,6 +631,7 @@ static void asmgen_op_cps(SwsAArch64Context *s, const SwsAArch64OpEntry *entry)
case SWS_UOP_TO_F32: asmgen_op_convert(s, p, &s->regs); break;
case SWS_UOP_EXPAND_PAIR: asmgen_op_expand(s, p, &s->regs); break;
case SWS_UOP_EXPAND_QUAD: asmgen_op_expand(s, p, &s->regs); break;
+ case SWS_UOP_ADD: asmgen_op_add(s, p, &s->regs); break;
case SWS_UOP_MIN: asmgen_op_min(s, p, &s->regs); break;
case SWS_UOP_MAX: asmgen_op_max(s, p, &s->regs); break;
case SWS_UOP_SCALE: asmgen_op_scale(s, p, &s->regs); break;
diff --git a/libswscale/tests/sws_ops_aarch64.c b/libswscale/tests/sws_ops_aarch64.c
index 3a56d71f59..97bc2c37e5 100644
--- a/libswscale/tests/sws_ops_aarch64.c
+++ b/libswscale/tests/sws_ops_aarch64.c
@@ -201,7 +201,7 @@ static int collect_ops_compile(SwsContext *ctx, const SwsOpList *ops,
if (!uops)
return AVERROR(ENOMEM);
- SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING;
+ SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING | SWS_UOP_FLAG_ADD;
if (!(ctx->flags & SWS_BITEXACT))
flags |= SWS_UOP_FLAG_FMA;
ret = ff_sws_ops_translate(ctx, ops, flags, uops);
@@ -298,6 +298,7 @@ static const char op_type_names[SWS_UOP_TYPE_NB][16] = {
[SWS_UOP_TO_F32 ] = "to_f32",
[SWS_UOP_EXPAND_PAIR ] = "expand_pair",
[SWS_UOP_EXPAND_QUAD ] = "expand_quad",
+ [SWS_UOP_ADD ] = "add",
[SWS_UOP_MIN ] = "min",
[SWS_UOP_MAX ] = "max",
[SWS_UOP_SCALE ] = "scale",
@@ -336,6 +337,7 @@ static const char uop_types[SWS_UOP_TYPE_NB][32] = {
[SWS_UOP_TO_F32 ] = "SWS_UOP_TO_F32",
[SWS_UOP_EXPAND_PAIR ] = "SWS_UOP_EXPAND_PAIR",
[SWS_UOP_EXPAND_QUAD ] = "SWS_UOP_EXPAND_QUAD",
+ [SWS_UOP_ADD ] = "SWS_UOP_ADD",
[SWS_UOP_MIN ] = "SWS_UOP_MIN",
[SWS_UOP_MAX ] = "SWS_UOP_MAX",
[SWS_UOP_SCALE ] = "SWS_UOP_SCALE",