From 6e71acf07b1aced39eb01a5ed858bcde4b77b454 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Fri, 24 Jul 2026 07:05:35 +0000 Subject: [PATCH 20/38] avutil/ppc: add directly-selectable top-level av_tx FFT codelets (F1) The AltiVec FFT codelets were registered only as FF_TX_PRESHUFFLE "_ns" building blocks, so a bare av_tx_init() always resolved to the generic C wrapper with the AltiVec kernel one level down as a sub-transform. That works, but is invisible to checkasm (which compares top-level function pointers) and pays a wrapper indirection. Mirror x86's TX_DEF dual-registration pattern: alongside each fftN_ns entry, register a plain fftN top-level codelet (out-of-place, aligned, no PRESHUFFLE) that gathers the input through the split-radix revtab into dst and runs the in-register kernel in place. In-place requests and MDCT wrappers keep selecting the _ns codelets as sub-transforms, as before. Verified under qemu -cpu 7400: av_tx_init() for a plain out-of-place FLOAT_FFT now selects fftN_altivec at the top level (transform-tree debug output), in-place/MDCT trees are unchanged; the AltiVec-vs-C end-to-end comparison passes for FFT lens 4..131072 fwd+inv and iMDCT 32..8192; checkasm av_tx now shows a real ALTIVEC: block and passes across 3 seeds; full checkasm suite 537/537 (was 530, +7 newly-dispatching float_fft lengths). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011BUPvhbJmFUU7zpuZf36JZ --- libavutil/ppc/tx_float_altivec.c | 68 ++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/libavutil/ppc/tx_float_altivec.c b/libavutil/ppc/tx_float_altivec.c index a892012..bbc3c86 100644 --- a/libavutil/ppc/tx_float_altivec.c +++ b/libavutil/ppc/tx_float_altivec.c @@ -359,6 +359,58 @@ DECL_SR_CODELET(32768) DECL_SR_CODELET(65536) DECL_SR_CODELET(131072) +/* Directly-selectable top-level codelets (same dual registration as x86's + * TX_DEF pattern: plain fftN alongside the fftN_ns building blocks above). + * They gather the input through the split-radix revtab (generated by + * sr_codelet_init) into dst and run the in-register kernel in place. + * Out-of-place only; in-place requests keep going through the generic C + * wrapper, which then picks the _ns codelets as its sub-transform. With + * these, a bare av_tx_init() resolves to a distinct AltiVec top-level + * function pointer -- which is also what checkasm's av_tx test compares, + * so the AltiVec path becomes directly testable. */ +#define DECL_SR_CODELET_TOP(n) \ +static void ff_tx_fft##n##_altivec(AVTXContext *s, void *_dst, \ + void *_src, ptrdiff_t stride) \ +{ \ + TXComplex *src = _src; \ + TXComplex *dst = _dst; \ + const int *map = s->map; \ + for (int i = 0; i < n; i++) \ + dst[i] = src[map[i]]; \ + fft##n##_av(dst, dst); \ +} \ + \ +static const FFTXCodelet ff_tx_fft##n##_def_altivec = { \ + .name = NULL_IF_CONFIG_SMALL("fft" #n "_altivec"), \ + .function = ff_tx_fft##n##_altivec, \ + .type = AV_TX_FLOAT_FFT, \ + .flags = FF_TX_OUT_OF_PLACE | FF_TX_ALIGNED, \ + .factors[0] = 2, \ + .nb_factors = 1, \ + .min_len = n, \ + .max_len = n, \ + .init = sr_codelet_init, \ + .cpu_flags = AV_CPU_FLAG_ALTIVEC, \ + .prio = FF_TX_PRIO_BASE + 128, \ +}; + +DECL_SR_CODELET_TOP(4) +DECL_SR_CODELET_TOP(8) +DECL_SR_CODELET_TOP(16) +DECL_SR_CODELET_TOP(32) +DECL_SR_CODELET_TOP(64) +DECL_SR_CODELET_TOP(128) +DECL_SR_CODELET_TOP(256) +DECL_SR_CODELET_TOP(512) +DECL_SR_CODELET_TOP(1024) +DECL_SR_CODELET_TOP(2048) +DECL_SR_CODELET_TOP(4096) +DECL_SR_CODELET_TOP(8192) +DECL_SR_CODELET_TOP(16384) +DECL_SR_CODELET_TOP(32768) +DECL_SR_CODELET_TOP(65536) +DECL_SR_CODELET_TOP(131072) + const FFTXCodelet * const ff_tx_codelet_list_float_ppc[] = { &ff_tx_fft4_ns_def_altivec, &ff_tx_fft8_ns_def_altivec, @@ -376,6 +428,22 @@ const FFTXCodelet * const ff_tx_codelet_list_float_ppc[] = { &ff_tx_fft32768_ns_def_altivec, &ff_tx_fft65536_ns_def_altivec, &ff_tx_fft131072_ns_def_altivec, + &ff_tx_fft4_def_altivec, + &ff_tx_fft8_def_altivec, + &ff_tx_fft16_def_altivec, + &ff_tx_fft32_def_altivec, + &ff_tx_fft64_def_altivec, + &ff_tx_fft128_def_altivec, + &ff_tx_fft256_def_altivec, + &ff_tx_fft512_def_altivec, + &ff_tx_fft1024_def_altivec, + &ff_tx_fft2048_def_altivec, + &ff_tx_fft4096_def_altivec, + &ff_tx_fft8192_def_altivec, + &ff_tx_fft16384_def_altivec, + &ff_tx_fft32768_def_altivec, + &ff_tx_fft65536_def_altivec, + &ff_tx_fft131072_def_altivec, NULL, }; -- 2.43.0