Commit 174f470813 for ffmpeg
commit 174f470813641991aae2ced845d460fb9c3bc572
Author: Niklas Haas <git@haasn.dev>
Date: Sat Nov 7 14:13:51 2026 +0100
swscale/ops_chain: re-order SwsOpImpl to store func with its data
The only downside to doing this is that it makes the C code unable to
reuse the CONTINUE() helper implicitly, but I don't think that's a huge
loss.
It also actually saves 16 bytes of data per ops chain, though that will
become moot after the rest of the series.
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c
index 19d0330a52..5755bac610 100644
--- a/libswscale/aarch64/ops.c
+++ b/libswscale/aarch64/ops.c
@@ -37,7 +37,7 @@ static_assert(offsetof_exec_in == offsetof(SwsOpExec, in), "SwsOpExe
static_assert(offsetof_exec_out == offsetof(SwsOpExec, out), "SwsOpExec layout mismatch");
static_assert(offsetof_exec_in_bump == offsetof(SwsOpExec, in_bump), "SwsOpExec layout mismatch");
static_assert(offsetof_exec_out_bump == offsetof(SwsOpExec, out_bump), "SwsOpExec layout mismatch");
-static_assert(offsetof_impl_cont == offsetof(SwsOpImpl, cont), "SwsOpImpl layout mismatch");
+static_assert(offsetof_impl_func == offsetof(SwsOpImpl, func), "SwsOpImpl layout mismatch");
static_assert(offsetof_impl_priv == offsetof(SwsOpImpl, priv), "SwsOpImpl layout mismatch");
static_assert(sizeof_impl == sizeof(SwsOpImpl), "SwsOpImpl layout mismatch");
diff --git a/libswscale/aarch64/ops_asmgen.h b/libswscale/aarch64/ops_asmgen.h
index d77fcabe4d..33ba2d114e 100644
--- a/libswscale/aarch64/ops_asmgen.h
+++ b/libswscale/aarch64/ops_asmgen.h
@@ -61,7 +61,7 @@ typedef struct SwsAArch64Context {
/* CPS-related variables. */
RasmOp op0_func;
- RasmOp op1_impl;
+ RasmOp op0_impl;
RasmOp cont;
RasmNode *load_cont_node;
SwsAArch64OpRegs regs;
diff --git a/libswscale/aarch64/ops_impl.h b/libswscale/aarch64/ops_impl.h
index 2553805967..b8b952a1f6 100644
--- a/libswscale/aarch64/ops_impl.h
+++ b/libswscale/aarch64/ops_impl.h
@@ -91,7 +91,7 @@ static inline int linear_num_vregs(const SwsAArch64OpImplParams *params)
#define offsetof_exec_out 32
#define offsetof_exec_in_bump 128
#define offsetof_exec_out_bump 160
-#define offsetof_impl_cont 0
+#define offsetof_impl_func 0
#define offsetof_impl_priv 8
#define sizeof_impl 24
diff --git a/libswscale/aarch64/ops_static.c b/libswscale/aarch64/ops_static.c
index 2a7933d675..62a0a42bdc 100644
--- a/libswscale/aarch64/ops_static.c
+++ b/libswscale/aarch64/ops_static.c
@@ -451,7 +451,7 @@ static void asmgen_process_frame(SwsAArch64Context *s, SwsCompMask imask, SwsCom
/* CPS-related variables. */
s->op0_func = a64op_gpx(7);
- s->op1_impl = a64op_gpx(8);
+ s->op0_impl = a64op_gpx(8);
/* Read/Write data pointer padding. */
LOOP(imask, i) { s->in_bump [i] = a64op_gpx(rw_gprs[(i * 4) + 2]); }
@@ -519,13 +519,13 @@ static void asmgen_process_cps(SwsAArch64Context *s, SwsCompMask mask)
/* Load values from impl. */
rasm_set_current_node(r, s->setup);
- RasmOp impl_cont = a64op_off(s->impl, offsetof_impl_cont);
- i_ldr(r, s->op0_func, impl_cont); CMT("SwsFuncPtr op0_func = impl->cont;");
- i_add(r, s->op1_impl, s->impl, IMM(sizeof_impl)); CMT("SwsOpImpl *op1_impl = impl + 1;");
+ RasmOp impl_func = a64op_off(s->impl, offsetof_impl_func);
+ i_ldr(r, s->op0_func, impl_func); CMT("SwsFuncPtr op0_func = impl->func;");
+ i_mov(r, s->op0_impl, s->impl); CMT("SwsOpImpl *op0_impl = impl;");
/* Reset impl and call first kernel. */
rasm_set_current_node(r, s->loop);
- i_mov(r, s->impl, s->op1_impl); CMT("impl = op1_impl;");
+ i_mov(r, s->impl, s->op0_impl); CMT("impl = op0_impl;");
i_blr(r, s->op0_func); CMT("op0_func();");
}
@@ -635,8 +635,8 @@ static void asmgen_op_cps(SwsAArch64Context *s, const SwsAArch64OpEntry *entry)
} else {
/* Load continuation address and increment impl pointer. */
RasmNode *node = rasm_set_current_node(r, s->load_cont_node);
- RasmOp impl_post = a64op_post(s->impl, sizeof_impl);
- i_ldr(r, s->cont, impl_post); CMT("SwsFuncPtr cont = (impl++)->cont;");
+ RasmOp impl_pre = a64op_pre(s->impl, sizeof_impl);
+ i_ldr(r, s->cont, impl_pre); CMT("SwsFuncPtr cont = (++impl)->func;");
rasm_set_current_node(r, node);
/* Common end for remaining CPS functions. */
i_br (r, s->cont); CMT("jump to cont");
diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c
index 9eb4b242dc..0e2bd237a8 100644
--- a/libswscale/ops_chain.c
+++ b/libswscale/ops_chain.c
@@ -51,8 +51,8 @@ int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, const void *ref,
return AVERROR(EINVAL);
av_assert1(func);
- chain->impl[idx].cont = func;
- chain->impl[idx + 1].priv = *priv;
+ chain->impl[idx].func = func;
+ chain->impl[idx].priv = *priv;
chain->num_impl++;
if (ref)
chain->ref[chain->num_ref++] = av_refstruct_ref_c(ref);
diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h
index b2dfd3f3ad..f660215520 100644
--- a/libswscale/ops_chain.h
+++ b/libswscale/ops_chain.h
@@ -71,7 +71,7 @@ static_assert(sizeof(SwsOpPriv) == 16, "SwsOpPriv size mismatch");
*/
typedef void (*SwsFuncPtr)(void);
typedef struct SwsOpImpl {
- SwsFuncPtr cont; /* Continuation for this operation. */
+ SwsFuncPtr func; /* Function pointer for this operation. */
SwsOpPriv priv; /* Private data for this operation. */
} SwsOpImpl;
@@ -87,7 +87,7 @@ static_assert(offsetof(SwsOpImpl, priv) == 8, "SwsOpImpl layout mismatch");
*/
typedef struct SwsOpChain {
#define SWS_MAX_OPS 16
- SwsOpImpl impl[SWS_MAX_OPS + 1]; /* reserve extra space for the entrypoint */
+ SwsOpImpl impl[SWS_MAX_OPS];
int num_impl;
int cpu_flags; /* set of all used CPU flags */
int over_read[4]; /* chain over-reads input by this many bytes */
diff --git a/libswscale/uops_backend.c b/libswscale/uops_backend.c
index 3f62cbff96..b5554800a0 100644
--- a/libswscale/uops_backend.c
+++ b/libswscale/uops_backend.c
@@ -115,17 +115,21 @@ static void process_c(const SwsOpExec *exec, const void *priv,
block_t x, y, z, w; /* allocate enough space for any intermediate */
SwsOpIter iterdata;
- SwsOpIter *iter = &iterdata; /* for CONTINUE() macro to work */
+ SwsOpIter *iter = &iterdata;
iter->exec = exec;
for (int i = 0; i < 4; i++) {
iter->in[i] = (uintptr_t) exec->in[i];
iter->out[i] = (uintptr_t) exec->out[i];
}
+ void (*entry)(SwsOpIter *, const SwsOpImpl *, void *, void *, void *, void *);
+ entry = (void (*)(SwsOpIter *, const SwsOpImpl *,
+ void *, void *, void *, void *)) impl->func;
+
for (iter->y = y_start; iter->y < y_end; iter->y++) {
for (int block = bx_start; block < bx_end; block++) {
iter->x = block * SWS_BLOCK_SIZE;
- CONTINUE(&x, &y, &z, &w);
+ entry(iter, impl, &x, &y, &z, &w);
}
const int y_bump = exec->in_bump_y ? exec->in_bump_y[iter->y] : 0;
diff --git a/libswscale/uops_tmpl.h b/libswscale/uops_tmpl.h
index c684ad3645..3d04e7e31d 100644
--- a/libswscale/uops_tmpl.h
+++ b/libswscale/uops_tmpl.h
@@ -112,7 +112,7 @@ typedef struct SwsOpIter {
#define CONTINUE(...) \
((void (*)(SwsOpIter *, const SwsOpImpl *, \
void *restrict x, void *restrict y, \
- void *restrict z, void *restrict w)) impl->cont) \
+ void *restrict z, void *restrict w)) impl[1].func) \
(iter, &impl[1], __VA_ARGS__)
/* Helper macros for common op setup code */
diff --git a/libswscale/x86/ops_common.asm b/libswscale/x86/ops_common.asm
index 9053147dca..5b4adc6325 100644
--- a/libswscale/x86/ops_common.asm
+++ b/libswscale/x86/ops_common.asm
@@ -33,8 +33,8 @@ cglobal sws_process%1_x86, 6, 7 + 2 * %1, 16
; (see SwsOpFunc signature)
;
; Stack layout:
- ; [rsp + 0] = [qword] impl->cont (address of first kernel)
- ; [rsp + 8] = [qword] &impl[1] (restore implq after chain)
+ ; [rsp + 0] = [qword] impl->func (address of first kernel)
+ ; [rsp + 8] = [qword] impl (restore implq after chain)
; [rsp + 16] = [dword] bx start (restore after line finish)
; [rsp + 20] = [dword] bx end (loop counter limit)
; [rsp + 24] = [dword] y end (loop counter limit)
@@ -42,8 +42,7 @@ cglobal sws_process%1_x86, 6, 7 + 2 * %1, 16
mov [rsp + 16], bxd
mov [rsp + 20], tmp0d ; bx_end
mov [rsp + 24], tmp1d ; y_end
- mov tmp0q, [implq + SwsOpImpl.cont]
- add implq, SwsOpImpl.next
+ mov tmp0q, [implq + SwsOpImpl.func]
mov [rsp + 0], tmp0q
mov [rsp + 8], implq
movsxdifnidn bxq, bxd
diff --git a/libswscale/x86/ops_include.asm b/libswscale/x86/ops_include.asm
index b8f41ca07b..ab103b8f67 100644
--- a/libswscale/x86/ops_include.asm
+++ b/libswscale/x86/ops_include.asm
@@ -134,7 +134,7 @@ struc SwsOpExec
endstruc
struc SwsOpImpl
- .cont resq 1
+ .func resq 1
.priv resb 16
.next resb 0
endstruc
@@ -303,7 +303,7 @@ endstruc
; Load the next operation kernel's address to a register
%macro LOAD_CONT 1 ; reg
- mov %1, [implq + SwsOpImpl.cont]
+ mov %1, [implq + SwsOpImpl.next + SwsOpImpl.func]
%endmacro
; Tail call into the next operation kernel, given that kernel's address