PR #23754 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23754 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23754.patch
(There is still stuff left to do; e.g. there are still unnecessary intermediate stores. And I haven't even started what I initially wanted to do: No longer use MMX.) >From 7c3096636b40acda3b41ec37518755c506f471f5 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Sun, 5 Jul 2026 10:07:02 +0200 Subject: [PATCH 1/8] avcodec/x86/vp9lpf: Combine comparisons The VP9 loop filter involves comparing several unsigned values against the same value and combines the results: a <= I && b <= I && ... This is equivalent to max(a,b,...) <= I and using this form is beneficial: Each comparison needs one pxor* and one pcmpgtb and every comparison except the first uses one por to combine the result. Switching to max instead results in one comparison and (operands - 1) pmaxub to create the maximum; the latter can be relaxed to por if the final comparator is one**, as it is for flat8{in,out}. Doing so saves 4113B of .text here and is beneficial for performance: Old benchmarks: vp9_loop_filter_h_4_8_8bpp_c: 78.0 vp9_loop_filter_h_4_8_8bpp_mmxext: 74.2 ( 1.05x) vp9_loop_filter_h_8_8_8bpp_c: 85.0 vp9_loop_filter_h_8_8_8bpp_mmxext: 101.9 ( 0.83x) vp9_loop_filter_h_16_8_8bpp_c: 140.3 vp9_loop_filter_h_16_16_8bpp_c: 250.7 vp9_loop_filter_h_16_16_8bpp_sse2: 176.1 ( 1.39x) vp9_loop_filter_h_16_16_8bpp_ssse3: 172.9 ( 1.38x) vp9_loop_filter_h_16_16_8bpp_avx: 165.5 ( 1.46x) vp9_loop_filter_mix2_h_44_16_8bpp_c: 167.5 vp9_loop_filter_mix2_h_44_16_8bpp_sse2: 70.5 ( 2.32x) vp9_loop_filter_mix2_h_44_16_8bpp_ssse3: 69.7 ( 2.40x) vp9_loop_filter_mix2_h_44_16_8bpp_avx: 70.3 ( 2.38x) vp9_loop_filter_mix2_h_48_16_8bpp_c: 175.5 vp9_loop_filter_mix2_h_48_16_8bpp_sse2: 93.3 ( 1.87x) vp9_loop_filter_mix2_h_48_16_8bpp_ssse3: 93.3 ( 1.87x) vp9_loop_filter_mix2_h_48_16_8bpp_avx: 90.1 ( 1.95x) vp9_loop_filter_mix2_h_84_16_8bpp_c: 177.1 vp9_loop_filter_mix2_h_84_16_8bpp_sse2: 94.3 ( 1.82x) vp9_loop_filter_mix2_h_84_16_8bpp_ssse3: 90.6 ( 1.92x) vp9_loop_filter_mix2_h_84_16_8bpp_avx: 88.8 ( 1.99x) vp9_loop_filter_mix2_h_88_16_8bpp_c: 186.4 vp9_loop_filter_mix2_h_88_16_8bpp_sse2: 94.7 ( 1.95x) vp9_loop_filter_mix2_h_88_16_8bpp_ssse3: 93.7 ( 1.98x) vp9_loop_filter_mix2_h_88_16_8bpp_avx: 89.7 ( 2.07x) vp9_loop_filter_mix2_v_44_16_8bpp_c: 176.0 vp9_loop_filter_mix2_v_44_16_8bpp_sse2: 29.7 ( 5.92x) vp9_loop_filter_mix2_v_44_16_8bpp_ssse3: 29.3 ( 6.02x) vp9_loop_filter_mix2_v_44_16_8bpp_avx: 30.5 ( 5.76x) vp9_loop_filter_mix2_v_48_16_8bpp_c: 187.7 vp9_loop_filter_mix2_v_48_16_8bpp_sse2: 65.1 ( 2.82x) vp9_loop_filter_mix2_v_48_16_8bpp_ssse3: 65.2 ( 2.84x) vp9_loop_filter_mix2_v_48_16_8bpp_avx: 56.0 ( 3.35x) vp9_loop_filter_mix2_v_84_16_8bpp_c: 188.3 vp9_loop_filter_mix2_v_84_16_8bpp_sse2: 60.7 ( 3.03x) vp9_loop_filter_mix2_v_84_16_8bpp_ssse3: 64.8 ( 2.80x) vp9_loop_filter_mix2_v_84_16_8bpp_avx: 56.8 ( 3.21x) vp9_loop_filter_mix2_v_88_16_8bpp_c: 199.4 vp9_loop_filter_mix2_v_88_16_8bpp_sse2: 65.8 ( 3.01x) vp9_loop_filter_mix2_v_88_16_8bpp_ssse3: 57.6 ( 3.46x) vp9_loop_filter_mix2_v_88_16_8bpp_avx: 56.3 ( 3.53x) vp9_loop_filter_v_4_8_8bpp_c: 82.8 vp9_loop_filter_v_4_8_8bpp_mmxext: 32.4 ( 2.50x) vp9_loop_filter_v_8_8_8bpp_c: 91.9 vp9_loop_filter_v_8_8_8bpp_mmxext: 65.6 ( 1.40x) vp9_loop_filter_v_16_8_8bpp_c: 156.2 vp9_loop_filter_v_16_16_8bpp_c: 291.3 vp9_loop_filter_v_16_16_8bpp_sse2: 125.7 ( 2.25x) vp9_loop_filter_v_16_16_8bpp_ssse3: 123.1 ( 2.31x) vp9_loop_filter_v_16_16_8bpp_avx: 115.3 ( 2.51x) New benchmarks: vp9_loop_filter_h_4_8_8bpp_c: 78.8 vp9_loop_filter_h_4_8_8bpp_mmxext: 62.4 ( 1.26x) vp9_loop_filter_h_8_8_8bpp_c: 85.8 vp9_loop_filter_h_8_8_8bpp_mmxext: 86.5 ( 0.97x) vp9_loop_filter_h_16_8_8bpp_c: 139.3 vp9_loop_filter_h_16_16_8bpp_c: 251.3 vp9_loop_filter_h_16_16_8bpp_sse2: 164.7 ( 1.45x) vp9_loop_filter_h_16_16_8bpp_ssse3: 164.2 ( 1.49x) vp9_loop_filter_h_16_16_8bpp_avx: 155.2 ( 1.56x) vp9_loop_filter_mix2_h_44_16_8bpp_c: 168.3 vp9_loop_filter_mix2_h_44_16_8bpp_sse2: 60.1 ( 2.80x) vp9_loop_filter_mix2_h_44_16_8bpp_ssse3: 60.1 ( 2.80x) vp9_loop_filter_mix2_h_44_16_8bpp_avx: 60.4 ( 2.79x) vp9_loop_filter_mix2_h_48_16_8bpp_c: 178.1 vp9_loop_filter_mix2_h_48_16_8bpp_sse2: 83.5 ( 2.07x) vp9_loop_filter_mix2_h_48_16_8bpp_ssse3: 84.0 ( 2.02x) vp9_loop_filter_mix2_h_48_16_8bpp_avx: 78.0 ( 2.28x) vp9_loop_filter_mix2_h_84_16_8bpp_c: 181.7 vp9_loop_filter_mix2_h_84_16_8bpp_sse2: 78.3 ( 2.20x) vp9_loop_filter_mix2_h_84_16_8bpp_ssse3: 85.1 ( 2.12x) vp9_loop_filter_mix2_h_84_16_8bpp_avx: 79.8 ( 2.27x) vp9_loop_filter_mix2_h_88_16_8bpp_c: 184.8 vp9_loop_filter_mix2_h_88_16_8bpp_sse2: 85.6 ( 2.14x) vp9_loop_filter_mix2_h_88_16_8bpp_ssse3: 85.1 ( 2.09x) vp9_loop_filter_mix2_h_88_16_8bpp_avx: 77.6 ( 2.38x) vp9_loop_filter_mix2_v_44_16_8bpp_c: 176.0 vp9_loop_filter_mix2_v_44_16_8bpp_sse2: 28.1 ( 6.27x) vp9_loop_filter_mix2_v_44_16_8bpp_ssse3: 32.3 ( 5.42x) vp9_loop_filter_mix2_v_44_16_8bpp_avx: 27.4 ( 6.43x) vp9_loop_filter_mix2_v_48_16_8bpp_c: 187.4 vp9_loop_filter_mix2_v_48_16_8bpp_sse2: 55.3 ( 3.39x) vp9_loop_filter_mix2_v_48_16_8bpp_ssse3: 54.7 ( 3.42x) vp9_loop_filter_mix2_v_48_16_8bpp_avx: 53.7 ( 3.48x) vp9_loop_filter_mix2_v_84_16_8bpp_c: 189.6 vp9_loop_filter_mix2_v_84_16_8bpp_sse2: 62.5 ( 3.00x) vp9_loop_filter_mix2_v_84_16_8bpp_ssse3: 61.3 ( 3.07x) vp9_loop_filter_mix2_v_84_16_8bpp_avx: 54.3 ( 3.47x) vp9_loop_filter_mix2_v_88_16_8bpp_c: 199.5 vp9_loop_filter_mix2_v_88_16_8bpp_sse2: 55.1 ( 3.52x) vp9_loop_filter_mix2_v_88_16_8bpp_ssse3: 54.4 ( 3.66x) vp9_loop_filter_mix2_v_88_16_8bpp_avx: 53.0 ( 3.69x) vp9_loop_filter_v_4_8_8bpp_c: 84.3 vp9_loop_filter_v_4_8_8bpp_mmxext: 32.0 ( 2.62x) vp9_loop_filter_v_8_8_8bpp_c: 94.3 vp9_loop_filter_v_8_8_8bpp_mmxext: 63.7 ( 1.48x) vp9_loop_filter_v_16_8_8bpp_c: 155.8 vp9_loop_filter_v_16_16_8bpp_c: 292.0 vp9_loop_filter_v_16_16_8bpp_sse2: 119.5 ( 2.39x) vp9_loop_filter_v_16_16_8bpp_ssse3: 119.1 ( 2.39x) vp9_loop_filter_v_16_16_8bpp_avx: 111.0 ( 2.61x) *: to shift unsigned values to signed ones for pcmpgtb **: or any comparison like <= 2^n-1 Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 101 ++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 58 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 92e5d03ad7..8509b61ebc 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -89,12 +89,6 @@ SECTION .text pcmpgtb %1, %2 %endmacro -; %1 = abs(%2-%3) > %4 -%macro ABSSUB_GT 5-6 [pb_80]; dst, src1, src2, cmp, tmp, [pb_80] - ABSSUB %1, %2, %3, %5 ; dst = abs(src1-src2) - CMP_GT %1, %4, %6 ; dst > cmp -%endmacro - %macro MASK_APPLY 4 ; %1=new_data/dst %2=old_data %3=mask %4=tmp pand %1, %3 ; new &= mask pandn %4, %3, %2 ; tmp = ~mask & old @@ -618,17 +612,18 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %define rq2 [Q2] %define rq3 [Q3] %endif - ABSSUB_GT m5, rp3, rp2, m2, m7, m0 ; m5 = abs(p3-p2) <= I - ABSSUB_GT m1, rp2, rp1, m2, m7, m0 ; m1 = abs(p2-p1) <= I - por m5, m1 - ABSSUB_GT m1, rp1, rp0, m2, m7, m0 ; m1 = abs(p1-p0) <= I - por m5, m1 - ABSSUB_GT m1, rq0, rq1, m2, m7, m0 ; m1 = abs(q1-q0) <= I - por m5, m1 - ABSSUB_GT m1, rq1, rq2, m2, m7, m0 ; m1 = abs(q2-q1) <= I - por m5, m1 - ABSSUB_GT m1, rq2, rq3, m2, m7, m0 ; m1 = abs(q3-q2) <= I - por m5, m1 + ABSSUB m5, rp3, rp2, m7 ; m5 = abs(p3-p2) + ABSSUB m1, rp2, rp1, m7 ; m1 = abs(p2-p1) + pmaxub m5, m1 + ABSSUB m1, rp1, rp0, m7 ; m1 = abs(p1-p0) + pmaxub m5, m1 + ABSSUB m1, rq0, rq1, m7 ; m1 = abs(q1-q0) + pmaxub m5, m1 + ABSSUB m1, rq1, rq2, m7 ; m1 = abs(q2-q1) + pmaxub m5, m1 + ABSSUB m1, rq2, rq3, m7 ; m1 = abs(q3-q2) + pmaxub m5, m1 + CMP_GT m5, m2, m0 ABSSUB m1, rp0, rq0, m7 ; abs(p0-q0) paddusb m1, m1 ; abs(p0-q0) * 2 ABSSUB m2, rp1, rq1, m7 ; abs(p1-q1) @@ -641,44 +636,35 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride SWAP 1, 3 pxor m3, [pb_ff] - ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) + ; (m0: pb_80, m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) ; calc flat8in (if not 44_16) and hev masks %if %2 != 44 && %2 != 4 mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 - ABSSUB_GT m2, rp3, rp0, m6, m5 ; abs(p3 - p0) <= 1 -%ifdef m8 - mova m8, [pb_80] -%define rb80 m8 -%else -%define rb80 [pb_80] -%endif - ABSSUB_GT m1, rp2, rp0, m6, m5, rb80 ; abs(p2 - p0) <= 1 - por m2, m1 - ABSSUB m4, rp1, rp0, m5 ; abs(p1 - p0) + ABSSUB m2, rp1, rp0, m5 ; abs(p1 - p0) %if %2 <= 16 %if cpuflag(ssse3) - pxor m0, m0 + pxor m5, m5 %endif - SPLATB_REG m7, H, m0 ; H H H H ... + SPLATB_REG m7, H, m5 ; H H H H ... %else movd m7, Hd SPLATB_MIX m7 %endif - pxor m7, rb80 - pxor m4, rb80 - pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) - CMP_GT m4, m6 ; abs(p1 - p0) <= 1 - por m2, m4 ; (flat8in) - ABSSUB m4, rq1, rq0, m1 ; abs(q1 - q0) - pxor m4, rb80 - pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) - por m0, m5 ; hev final value - CMP_GT m4, m6 ; abs(q1 - q0) <= 1 - por m2, m4 ; (flat8in) - ABSSUB_GT m1, rq2, rq0, m6, m5, rb80 ; abs(q2 - q0) <= 1 + ABSSUB m4, rq1, rq0, m5 ; abs(q1 - q0) + pmaxub m4, m2 ; max(abs(q1 - q0), abs(p1 - p0)) + ABSSUB m2, rp2, rp0, m5 ; abs(p2 - p0) + pxor m7, m0 + por m2, m4 + pxor m4, m0 + pcmpgtb m4, m7 ; hev: max(abs(q1 - q0), abs(p1 - p0)) > H + ABSSUB m1, rp3, rp0, m5 ; abs(p3 - p0) por m2, m1 - ABSSUB_GT m1, rq3, rq0, m6, m5, rb80 ; abs(q3 - q0) <= 1 - por m2, m1 ; flat8in final value + ABSSUB m1, rq2, rq0, m5 ; abs(q2 - q0) + por m2, m1 + ABSSUB m1, rq3, rq0, m5 ; abs(q3 - q0) + por m2, m1 + CMP_GT m2, m6, m0 ; flat8in + SWAP 0, 4 pxor m2, [pb_ff] %if %2 == 84 || %2 == 48 pand m2, [mask_mix%2] @@ -695,13 +681,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride SPLATB_REG m7, H, m0 ; H H H H ... %endif pxor m7, m6 - ABSSUB m4, rp1, rp0, m1 ; abs(p1 - p0) - pxor m4, m6 - pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) + ABSSUB m0, rp1, rp0, m1 ; abs(p1 - p0) ABSSUB m4, rq1, rq0, m1 ; abs(q1 - q0) - pxor m4, m6 - pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) - por m0, m5 ; hev final value + pmaxub m0, m4 ; max(abs(p1 - p0), abs(q1 - q0)) + pxor m0, m6 + pcmpgtb m0, m7 ; max > H; hev final value %endif %if %2 == 16 @@ -716,8 +700,8 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %define rp7 [P7] %define rp6 [P6] %endif - ABSSUB_GT m1, rp7, rp0, m6, m5 ; abs(p7 - p0) <= 1 - ABSSUB_GT m7, rp6, rp0, m6, m5 ; abs(p6 - p0) <= 1 + ABSSUB m7, rp7, rp0, m5 ; abs(p7 - p0) + ABSSUB m1, rp6, rp0, m5 ; abs(p6 - p0) por m1, m7 %ifdef m8 mova m8, [P5] @@ -728,9 +712,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %define rp5 [P5] %define rp4 [P4] %endif - ABSSUB_GT m7, rp5, rp0, m6, m5 ; abs(p5 - p0) <= 1 + ABSSUB m7, rp5, rp0, m5 ; abs(p5 - p0) por m1, m7 - ABSSUB_GT m7, rp4, rp0, m6, m5 ; abs(p4 - p0) <= 1 + ABSSUB m7, rp4, rp0, m5 ; abs(p4 - p0) por m1, m7 %ifdef m8 mova m14, [Q4] @@ -741,9 +725,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %define rq4 [Q4] %define rq5 [Q5] %endif - ABSSUB_GT m7, rq4, rq0, m6, m5 ; abs(q4 - q0) <= 1 + ABSSUB m7, rq4, rq0, m5 ; abs(q4 - q0) por m1, m7 - ABSSUB_GT m7, rq5, rq0, m6, m5 ; abs(q5 - q0) <= 1 + ABSSUB m7, rq5, rq0, m5 ; abs(q5 - q0) por m1, m7 %ifdef m8 mova m14, [Q6] @@ -754,10 +738,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %define rq6 [Q6] %define rq7 [Q7] %endif - ABSSUB_GT m7, rq6, rq0, m6, m5 ; abs(q4 - q0) <= 1 + ABSSUB m7, rq6, rq0, m5 ; abs(q4 - q0) por m1, m7 - ABSSUB_GT m7, rq7, rq0, m6, m5 ; abs(q5 - q0) <= 1 + ABSSUB m7, rq7, rq0, m5 ; abs(q5 - q0) por m1, m7 ; flat8out final value + CMP_GT m1, m6, [pb_80] pxor m1, [pb_ff] %endif -- 2.52.0 >From 2e269d0f70817ba41a75bf54abaf257feb8a4d32 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Sun, 5 Jul 2026 20:41:52 +0200 Subject: [PATCH 2/8] avcodec/x86/vp9lpf: Don't do work twice max(abs(p1-p0),abs(q1-q0)) is currently computed twice. Stop doing so. This saves 1681B of .text and gives a small performance boost. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 8509b61ebc..8ccba1f09b 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -616,9 +616,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride ABSSUB m1, rp2, rp1, m7 ; m1 = abs(p2-p1) pmaxub m5, m1 ABSSUB m1, rp1, rp0, m7 ; m1 = abs(p1-p0) - pmaxub m5, m1 - ABSSUB m1, rq0, rq1, m7 ; m1 = abs(q1-q0) - pmaxub m5, m1 + ABSSUB m4, rq0, rq1, m7 ; m1 = abs(q1-q0) + pmaxub m4, m1 + pmaxub m5, m4 ABSSUB m1, rq1, rq2, m7 ; m1 = abs(q2-q1) pmaxub m5, m1 ABSSUB m1, rq2, rq3, m7 ; m1 = abs(q3-q2) @@ -636,11 +636,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride SWAP 1, 3 pxor m3, [pb_ff] - ; (m0: pb_80, m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) + ; (m0: pb_80, m3: fm, m4: max(abs(q1 - q0), abs(p1 - p0)) + ; m8..15: p3 p2 p1 p0 q0 q1 q2 q3) ; calc flat8in (if not 44_16) and hev masks %if %2 != 44 && %2 != 4 mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 - ABSSUB m2, rp1, rp0, m5 ; abs(p1 - p0) %if %2 <= 16 %if cpuflag(ssse3) pxor m5, m5 @@ -650,8 +650,6 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride movd m7, Hd SPLATB_MIX m7 %endif - ABSSUB m4, rq1, rq0, m5 ; abs(q1 - q0) - pmaxub m4, m2 ; max(abs(q1 - q0), abs(p1 - p0)) ABSSUB m2, rp2, rp0, m5 ; abs(p2 - p0) pxor m7, m0 por m2, m4 @@ -664,29 +662,26 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride ABSSUB m1, rq3, rq0, m5 ; abs(q3 - q0) por m2, m1 CMP_GT m2, m6, m0 ; flat8in - SWAP 0, 4 pxor m2, [pb_ff] %if %2 == 84 || %2 == 48 pand m2, [mask_mix%2] %endif %else - mova m6, [pb_80] %if %2 == 44 movd m7, Hd SPLATB_MIX m7 %else %if cpuflag(ssse3) - pxor m0, m0 + pxor m5, m5 %endif - SPLATB_REG m7, H, m0 ; H H H H ... + SPLATB_REG m7, H, m5 ; H H H H ... %endif - pxor m7, m6 - ABSSUB m0, rp1, rp0, m1 ; abs(p1 - p0) - ABSSUB m4, rq1, rq0, m1 ; abs(q1 - q0) - pmaxub m0, m4 ; max(abs(p1 - p0), abs(q1 - q0)) - pxor m0, m6 - pcmpgtb m0, m7 ; max > H; hev final value + pxor m4, m0 + pxor m7, m0 + pcmpgtb m4, m7 ; max > H; hev final value + SWAP 0, 6 %endif + SWAP 0, 4 %if %2 == 16 ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) -- 2.52.0 >From 083006f08be9ff29100e3aba178599f4052569b4 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Wed, 8 Jul 2026 19:20:04 +0200 Subject: [PATCH 3/8] avcodec/x86/vp9lpf: Improve deriving masks Deriving the fm, flat8in and flat8out masks involves calculating max{abs(a_i-a), 1<=i<=N} (with N being two or four). The current code does this by calculating the abs individually (two psubusb and a por), followed by combining the results (another por or pmaxub). But there is a better way: Calculate the min m and max M of the a_i. Then the result equals max{(M-a)^+,(a-m)^+}, which can be calculated with two psubusb, followed by combining the result. E.g. for N=2 this saves two por and exchanges two psubusb with pmaxub/pminub. Doing so saves 2062B of .text here; performance is basically flat (the length of the critical section is unchanged). Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 148 ++++++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 62 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 8ccba1f09b..7447992ea9 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -81,6 +81,73 @@ SECTION .text por %1, %4 %endmacro +%macro MINMAX 3-5 ; maxdst, mindst, src, scratch reg, [initial value] +%if %0 == 5 + %ifnum sizeof%5 ; register + %define %%srcmax %5 + %define %%srcmin %5 + %else + mova %2, %5 + %define %%srcmax %2 + %define %%srcmin %2 + %endif +%else + %define %%srcmax %1 + %define %%srcmin %2 +%endif + +%ifnum sizeof%3 ; src is register + %define %%src %3 +%else ; src is memory + %ifnidn %4, "" + %define %%src %4 + mova %4, %3 + %else + %define %%src %3 + %endif +%endif + + pmaxub %1, %%srcmax, %%src + pminub %2, %%srcmin, %%src +%endmacro + +%macro ABSDIFF_MAX 5-6 ; max [dst], min, common subtrahend, combine op, scratch reg, [dst] +%ifidn %5, "" + ; no spare reg; must have separate dst reg + %define %%sub + psubusb %1, %3 + %4 %6, %1 + mova %1, %3 + psubusb %1, %2 + %4 %6, %1 +%else +%ifnum sizeof%3 + psubusb %1, %3 + %define %%sub %3 +%else + mova %5, %3 + psubusb %1, %5 + %define %%sub %5 +%endif +%if avx_enabled + %define %%min %2 + psubusb %2, %%sub, %2 +%else + %define %%min %5 + %ifnidn %%sub, %5 + mova %5, %%sub + %endif + psubusb %5, %2 +%endif +%if %0 == 6 + %4 %6, %1 + %4 %6, %%min +%else + %4 %1, %%min +%endif +%endif +%endmacro + ; %1 = %1>%2 %macro CMP_GT 2-3 ; src/dst, cmp, pb_80 %if %0 == 3 @@ -612,17 +679,14 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %define rq2 [Q2] %define rq3 [Q3] %endif - ABSSUB m5, rp3, rp2, m7 ; m5 = abs(p3-p2) - ABSSUB m1, rp2, rp1, m7 ; m1 = abs(p2-p1) - pmaxub m5, m1 + MINMAX m5, m1, rp1, m6, rp3 ; max(p1,p3), min(p1,p3) + ABSDIFF_MAX m5, m1, rp2, pmaxub, m6 ; max(abs(p3-p2),abs(p2-p1)) ABSSUB m1, rp1, rp0, m7 ; m1 = abs(p1-p0) ABSSUB m4, rq0, rq1, m7 ; m1 = abs(q1-q0) pmaxub m4, m1 + MINMAX m1, m6, rq3, m7, rq1 ; max(q1,q3), min(q1,q3) pmaxub m5, m4 - ABSSUB m1, rq1, rq2, m7 ; m1 = abs(q2-q1) - pmaxub m5, m1 - ABSSUB m1, rq2, rq3, m7 ; m1 = abs(q3-q2) - pmaxub m5, m1 + ABSDIFF_MAX m1, m6, rq2, pmaxub, m7, m5 CMP_GT m5, m2, m0 ABSSUB m1, rp0, rq0, m7 ; abs(p0-q0) paddusb m1, m1 ; abs(p0-q0) * 2 @@ -640,6 +704,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride ; m8..15: p3 p2 p1 p0 q0 q1 q2 q3) ; calc flat8in (if not 44_16) and hev masks %if %2 != 44 && %2 != 4 + MINMAX m2, m1, rp2, m5, rp3 ; max(p2,p3), min(p2,p3) mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 %if %2 <= 16 %if cpuflag(ssse3) @@ -650,17 +715,14 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride movd m7, Hd SPLATB_MIX m7 %endif - ABSSUB m2, rp2, rp0, m5 ; abs(p2 - p0) + ABSDIFF_MAX m2, m1, rp0, por, m5 ; max(abs(p2-p0),abs(p3-p0)) pxor m7, m0 por m2, m4 pxor m4, m0 pcmpgtb m4, m7 ; hev: max(abs(q1 - q0), abs(p1 - p0)) > H - ABSSUB m1, rp3, rp0, m5 ; abs(p3 - p0) - por m2, m1 - ABSSUB m1, rq2, rq0, m5 ; abs(q2 - q0) - por m2, m1 - ABSSUB m1, rq3, rq0, m5 ; abs(q3 - q0) - por m2, m1 + + MINMAX m7, m1, rq3, m5, rq2 ; max(q2,q3), min(q2,q3) + ABSDIFF_MAX m7, m1, rq0, por, m5, m2 CMP_GT m2, m6, m0 ; flat8in pxor m2, [pb_ff] %if %2 == 84 || %2 == 48 @@ -686,57 +748,19 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %if %2 == 16 ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) ; calc flat8out mask + MINMAX m1, m7, [P6], m5, [P7] ; max(p6, p7), min(p6,p7) + MINMAX m1, m7, [P5], m5 ; max(p5,p6,p7), min(p5,p6,p7) + MINMAX m1, m7, [P4], m5 ; max(p4...p7), min(p4...p7) + ABSDIFF_MAX m1, m7, rp0, por, m5 %ifdef m8 - mova m8, [P7] - mova m9, [P6] -%define rp7 m8 -%define rp6 m9 + %define M8 m8 %else -%define rp7 [P7] -%define rp6 [P6] + %define M8 "" %endif - ABSSUB m7, rp7, rp0, m5 ; abs(p7 - p0) - ABSSUB m1, rp6, rp0, m5 ; abs(p6 - p0) - por m1, m7 -%ifdef m8 - mova m8, [P5] - mova m9, [P4] -%define rp5 m8 -%define rp4 m9 -%else -%define rp5 [P5] -%define rp4 [P4] -%endif - ABSSUB m7, rp5, rp0, m5 ; abs(p5 - p0) - por m1, m7 - ABSSUB m7, rp4, rp0, m5 ; abs(p4 - p0) - por m1, m7 -%ifdef m8 - mova m14, [Q4] - mova m15, [Q5] -%define rq4 m14 -%define rq5 m15 -%else -%define rq4 [Q4] -%define rq5 [Q5] -%endif - ABSSUB m7, rq4, rq0, m5 ; abs(q4 - q0) - por m1, m7 - ABSSUB m7, rq5, rq0, m5 ; abs(q5 - q0) - por m1, m7 -%ifdef m8 - mova m14, [Q6] - mova m15, [Q7] -%define rq6 m14 -%define rq7 m15 -%else -%define rq6 [Q6] -%define rq7 [Q7] -%endif - ABSSUB m7, rq6, rq0, m5 ; abs(q4 - q0) - por m1, m7 - ABSSUB m7, rq7, rq0, m5 ; abs(q5 - q0) - por m1, m7 ; flat8out final value + MINMAX m5, m7, [Q5], M8, [Q4] ; max(q4,q5), min(q4,q5) + MINMAX m5, m7, [Q6], M8 ; max(q4,q5,q6), min(q4,q5,q6) + MINMAX m5, m7, [Q7], M8 ; max(q4...q7), min(q4...q7) + ABSDIFF_MAX m5, m7, rq0, por, M8, m1 CMP_GT m1, m6, [pb_80] pxor m1, [pb_ff] %endif -- 2.52.0 >From 14dc8f95ed4ff8e8dbd210d43377a04c6066afb3 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Wed, 8 Jul 2026 21:14:02 +0200 Subject: [PATCH 4/8] avcodec/x86/vp9lpf: Avoid reloading constant pb_80 is still in a register. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 7447992ea9..106afff654 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -741,12 +741,11 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride pxor m4, m0 pxor m7, m0 pcmpgtb m4, m7 ; max > H; hev final value - SWAP 0, 6 %endif SWAP 0, 4 %if %2 == 16 - ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) + ; (m0: hev, m2: flat8in, m3: fm, m4: pb_80, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) ; calc flat8out mask MINMAX m1, m7, [P6], m5, [P7] ; max(p6, p7), min(p6,p7) MINMAX m1, m7, [P5], m5 ; max(p5,p6,p7), min(p5,p6,p7) @@ -761,7 +760,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride MINMAX m5, m7, [Q6], M8 ; max(q4,q5,q6), min(q4,q5,q6) MINMAX m5, m7, [Q7], M8 ; max(q4...q7), min(q4...q7) ABSDIFF_MAX m5, m7, rq0, por, M8, m1 - CMP_GT m1, m6, [pb_80] + CMP_GT m1, m6, m4 pxor m1, [pb_ff] %endif @@ -777,10 +776,10 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride ; f2: fm & ~f14 & ~f6 & hev => fm & ~(out & in) & ~(~out & in) & hev => fm & ~in & hev ; f4: fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & hev) => fm & ~in & ~hev - ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) + ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m4: pb_80, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) ; filter2() + SWAP 4, 6 %if %2 != 44 && %2 != 4 - mova m6, [pb_80] ; already in m6 if 44_16 SCRATCH 2, 15, rsp+%3+%4 %if %2 == 16 SCRATCH 1, 8, rsp+%3+%4+16 -- 2.52.0 >From aadec4b3d03bd20546c43a4ce10207f490f3e80a Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 9 Jul 2026 10:27:44 +0200 Subject: [PATCH 5/8] avcodec/x86/vp9lpf: Avoid inverting masks Change the comparison instead to already yield the inverted mask. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index 106afff654..e231d46d92 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -31,7 +31,7 @@ cextern pb_80 pb_4: times 16 db 0x04 pb_10: times 16 db 0x10 pb_40: times 16 db 0x40 -pb_81: times 16 db 0x81 +pb_82: times 16 db 0x82 pb_f8: times 16 db 0xf8 pb_fe: times 16 db 0xfe pb_ff: times 16 db 0xff @@ -705,7 +705,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride ; calc flat8in (if not 44_16) and hev masks %if %2 != 44 && %2 != 4 MINMAX m2, m1, rp2, m5, rp3 ; max(p2,p3), min(p2,p3) - mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 + mova m6, [pb_82] ; [2 2 2 2 ...] ^ 0x80 %if %2 <= 16 %if cpuflag(ssse3) pxor m5, m5 @@ -723,8 +723,15 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride MINMAX m7, m1, rq3, m5, rq2 ; max(q2,q3), min(q2,q3) ABSDIFF_MAX m7, m1, rq0, por, m5, m2 - CMP_GT m2, m6, m0 ; flat8in - pxor m2, [pb_ff] + pxor m2, m0 +%if %2 == 16 + ; preserve pb_82 in m6 + pcmpgtb m5, m6, m2 ; flat8in + SWAP 2,5 +%else + pcmpgtb m6, m2 ; flat8in + SWAP 2,6 +%endif %if %2 == 84 || %2 == 48 pand m2, [mask_mix%2] %endif @@ -745,7 +752,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride SWAP 0, 4 %if %2 == 16 - ; (m0: hev, m2: flat8in, m3: fm, m4: pb_80, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) + ; (m0: hev, m2: flat8in, m3: fm, m4: pb_80, m6: pb_82, m9..15: p2 p1 p0 q0 q1 q2 q3) ; calc flat8out mask MINMAX m1, m7, [P6], m5, [P7] ; max(p6, p7), min(p6,p7) MINMAX m1, m7, [P5], m5 ; max(p5,p6,p7), min(p5,p6,p7) @@ -760,8 +767,9 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride MINMAX m5, m7, [Q6], M8 ; max(q4,q5,q6), min(q4,q5,q6) MINMAX m5, m7, [Q7], M8 ; max(q4...q7), min(q4...q7) ABSDIFF_MAX m5, m7, rq0, por, M8, m1 - CMP_GT m1, m6, m4 - pxor m1, [pb_ff] + pxor m1, m4 + pcmpgtb m6, m1 + SWAP 1, 6 %endif ; if (fm) { -- 2.52.0 >From b1dc4d4080617c1354bb8c2f440c1cc444f38381 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 9 Jul 2026 12:37:18 +0200 Subject: [PATCH 6/8] avcodec/x86/vp9lpf: Avoid unnecessary stores P1, P0, Q0 and Q1 are kept in registers throughout the whole function (when using xmm registers on x64), so they need not be stored on the stack. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index e231d46d92..fd34881014 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -519,10 +519,6 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride %endif ; %2 mova [P3], m4 mova [P2], m5 - mova [P1], m6 - mova [P0], m7 - mova [Q0], m8 - mova [Q1], m9 mova [Q2], m10 mova [Q3], m11 %if %2 == 16 -- 2.52.0 >From 351494ad40f7b58957a6603a0d04904405091d69 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 9 Jul 2026 18:30:49 +0200 Subject: [PATCH 7/8] avcodec/x86/vp9lpf: Combine filter2 and filter4 cases There are two differences between the filter2 and filter4 case. The first one is if (hev) { int f = av_clip_intp2(p1 - q1, BIT_DEPTH - 1); f = av_clip_intp2(3 * (q0 - p0) + f, BIT_DEPTH - 1); ... } else { int f = av_clip_intp2(3 * (q0 - p0), BIT_DEPTH - 1); ... which can simply be combined to int f = hev ? av_clip_intp2(p1 - q1, BIT_DEPTH - 1) : 0; f = av_clip_intp2(3 * (q0 - p0) + f, BIT_DEPTH - 1); which boils down to masking f by hev after the first av_clip_intp2(). The second is that two more rows are processed for filter4(), but one can simply mask the differential there, too. So one can just combine both filters into one; doing so saves 8457B of .text here and improves performance. Old benchmarks: vp9_loop_filter_h_4_8_8bpp_c: 77.3 vp9_loop_filter_h_4_8_8bpp_mmxext: 60.8 ( 1.27x) vp9_loop_filter_h_8_8_8bpp_c: 86.3 vp9_loop_filter_h_8_8_8bpp_mmxext: 82.9 ( 1.04x) vp9_loop_filter_h_16_8_8bpp_c: 139.7 vp9_loop_filter_h_16_16_8bpp_c: 251.9 vp9_loop_filter_h_16_16_8bpp_sse2: 164.8 ( 1.44x) vp9_loop_filter_h_16_16_8bpp_ssse3: 164.4 ( 1.49x) vp9_loop_filter_h_16_16_8bpp_avx: 155.1 ( 1.59x) vp9_loop_filter_mix2_h_44_16_8bpp_c: 169.2 vp9_loop_filter_mix2_h_44_16_8bpp_sse2: 58.0 ( 2.91x) vp9_loop_filter_mix2_h_44_16_8bpp_ssse3: 56.6 ( 2.99x) vp9_loop_filter_mix2_h_44_16_8bpp_avx: 57.1 ( 2.96x) vp9_loop_filter_mix2_h_48_16_8bpp_c: 174.9 vp9_loop_filter_mix2_h_48_16_8bpp_sse2: 75.4 ( 2.32x) vp9_loop_filter_mix2_h_48_16_8bpp_ssse3: 80.6 ( 2.16x) vp9_loop_filter_mix2_h_48_16_8bpp_avx: 75.1 ( 2.28x) vp9_loop_filter_mix2_h_84_16_8bpp_c: 179.7 vp9_loop_filter_mix2_h_84_16_8bpp_sse2: 79.5 ( 2.25x) vp9_loop_filter_mix2_h_84_16_8bpp_ssse3: 78.2 ( 2.28x) vp9_loop_filter_mix2_h_84_16_8bpp_avx: 76.1 ( 2.32x) vp9_loop_filter_mix2_h_88_16_8bpp_c: 184.5 vp9_loop_filter_mix2_h_88_16_8bpp_sse2: 82.5 ( 2.23x) vp9_loop_filter_mix2_h_88_16_8bpp_ssse3: 78.7 ( 2.34x) vp9_loop_filter_mix2_h_88_16_8bpp_avx: 74.4 ( 2.48x) vp9_loop_filter_mix2_v_44_16_8bpp_c: 176.0 vp9_loop_filter_mix2_v_44_16_8bpp_sse2: 28.4 ( 6.18x) vp9_loop_filter_mix2_v_44_16_8bpp_ssse3: 26.3 ( 6.69x) vp9_loop_filter_mix2_v_44_16_8bpp_avx: 26.2 ( 6.72x) vp9_loop_filter_mix2_v_48_16_8bpp_c: 188.7 vp9_loop_filter_mix2_v_48_16_8bpp_sse2: 60.4 ( 3.11x) vp9_loop_filter_mix2_v_48_16_8bpp_ssse3: 53.6 ( 3.50x) vp9_loop_filter_mix2_v_48_16_8bpp_avx: 51.2 ( 3.64x) vp9_loop_filter_mix2_v_84_16_8bpp_c: 191.7 vp9_loop_filter_mix2_v_84_16_8bpp_sse2: 55.2 ( 3.40x) vp9_loop_filter_mix2_v_84_16_8bpp_ssse3: 51.6 ( 3.71x) vp9_loop_filter_mix2_v_84_16_8bpp_avx: 50.8 ( 3.77x) vp9_loop_filter_mix2_v_88_16_8bpp_c: 201.1 vp9_loop_filter_mix2_v_88_16_8bpp_sse2: 52.1 ( 3.86x) vp9_loop_filter_mix2_v_88_16_8bpp_ssse3: 53.9 ( 3.73x) vp9_loop_filter_mix2_v_88_16_8bpp_avx: 51.5 ( 3.90x) vp9_loop_filter_v_4_8_8bpp_c: 83.7 vp9_loop_filter_v_4_8_8bpp_mmxext: 29.7 ( 2.81x) vp9_loop_filter_v_8_8_8bpp_c: 93.2 vp9_loop_filter_v_8_8_8bpp_mmxext: 58.7 ( 1.59x) vp9_loop_filter_v_16_8_8bpp_c: 156.5 vp9_loop_filter_v_16_16_8bpp_c: 292.9 vp9_loop_filter_v_16_16_8bpp_sse2: 117.8 ( 2.43x) vp9_loop_filter_v_16_16_8bpp_ssse3: 116.7 ( 2.45x) vp9_loop_filter_v_16_16_8bpp_avx: 104.5 ( 2.78x) New benchmarks: vp9_loop_filter_h_4_8_8bpp_c: 77.5 vp9_loop_filter_h_4_8_8bpp_mmxext: 54.8 ( 1.41x) vp9_loop_filter_h_8_8_8bpp_c: 85.5 vp9_loop_filter_h_8_8_8bpp_mmxext: 75.0 ( 1.12x) vp9_loop_filter_h_16_8_8bpp_c: 139.8 vp9_loop_filter_h_16_16_8bpp_c: 249.7 vp9_loop_filter_h_16_16_8bpp_sse2: 154.9 ( 1.54x) vp9_loop_filter_h_16_16_8bpp_ssse3: 152.9 ( 1.54x) vp9_loop_filter_h_16_16_8bpp_avx: 142.1 ( 1.62x) vp9_loop_filter_mix2_h_44_16_8bpp_c: 167.8 vp9_loop_filter_mix2_h_44_16_8bpp_sse2: 52.3 ( 3.21x) vp9_loop_filter_mix2_h_44_16_8bpp_ssse3: 52.7 ( 3.18x) vp9_loop_filter_mix2_h_44_16_8bpp_avx: 51.9 ( 3.18x) vp9_loop_filter_mix2_h_48_16_8bpp_c: 175.1 vp9_loop_filter_mix2_h_48_16_8bpp_sse2: 73.2 ( 2.39x) vp9_loop_filter_mix2_h_48_16_8bpp_ssse3: 74.9 ( 2.28x) vp9_loop_filter_mix2_h_48_16_8bpp_avx: 69.0 ( 2.54x) vp9_loop_filter_mix2_h_84_16_8bpp_c: 177.7 vp9_loop_filter_mix2_h_84_16_8bpp_sse2: 72.6 ( 2.45x) vp9_loop_filter_mix2_h_84_16_8bpp_ssse3: 71.3 ( 2.48x) vp9_loop_filter_mix2_h_84_16_8bpp_avx: 69.3 ( 2.56x) vp9_loop_filter_mix2_h_88_16_8bpp_c: 184.3 vp9_loop_filter_mix2_h_88_16_8bpp_sse2: 69.6 ( 2.59x) vp9_loop_filter_mix2_h_88_16_8bpp_ssse3: 70.2 ( 2.62x) vp9_loop_filter_mix2_h_88_16_8bpp_avx: 69.3 ( 2.66x) vp9_loop_filter_mix2_v_44_16_8bpp_c: 176.3 vp9_loop_filter_mix2_v_44_16_8bpp_sse2: 22.0 ( 7.98x) vp9_loop_filter_mix2_v_44_16_8bpp_ssse3: 21.4 ( 8.23x) vp9_loop_filter_mix2_v_44_16_8bpp_avx: 21.6 ( 8.18x) vp9_loop_filter_mix2_v_48_16_8bpp_c: 187.8 vp9_loop_filter_mix2_v_48_16_8bpp_sse2: 49.9 ( 3.75x) vp9_loop_filter_mix2_v_48_16_8bpp_ssse3: 47.3 ( 3.96x) vp9_loop_filter_mix2_v_48_16_8bpp_avx: 46.1 ( 4.07x) vp9_loop_filter_mix2_v_84_16_8bpp_c: 189.7 vp9_loop_filter_mix2_v_84_16_8bpp_sse2: 51.2 ( 3.58x) vp9_loop_filter_mix2_v_84_16_8bpp_ssse3: 48.4 ( 3.90x) vp9_loop_filter_mix2_v_84_16_8bpp_avx: 45.9 ( 4.14x) vp9_loop_filter_mix2_v_88_16_8bpp_c: 199.8 vp9_loop_filter_mix2_v_88_16_8bpp_sse2: 51.2 ( 3.88x) vp9_loop_filter_mix2_v_88_16_8bpp_ssse3: 50.5 ( 3.93x) vp9_loop_filter_mix2_v_88_16_8bpp_avx: 45.4 ( 4.40x) vp9_loop_filter_v_4_8_8bpp_c: 83.3 vp9_loop_filter_v_4_8_8bpp_mmxext: 23.2 ( 3.58x) vp9_loop_filter_v_8_8_8bpp_c: 92.6 vp9_loop_filter_v_8_8_8bpp_mmxext: 52.5 ( 1.76x) vp9_loop_filter_v_16_8_8bpp_c: 154.9 vp9_loop_filter_v_16_16_8bpp_c: 291.3 vp9_loop_filter_v_16_16_8bpp_sse2: 104.8 ( 2.68x) vp9_loop_filter_v_16_16_8bpp_ssse3: 107.5 ( 2.64x) vp9_loop_filter_v_16_16_8bpp_avx: 97.7 ( 2.90x) Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 127 +++++++++++++------------------------- 1 file changed, 44 insertions(+), 83 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index fd34881014..e4366e8713 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -219,10 +219,11 @@ SECTION .text mova %5, %1 %endmacro -%macro SRSHIFT3B_2X 4 ; reg1, reg2, [pb_10], tmp - mova %4, [pb_f8] - pand %1, %4 - pand %2, %4 +%macro SRSHIFT3B_2X 3 ; reg1, reg2, tmp + mova %3, [pb_f8] + pand %1, %3 + pand %2, %3 + mova %3, [pb_10] psrlq %1, 3 psrlq %2, 3 pxor %1, %3 @@ -771,8 +772,7 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride ; if (fm) { ; if (out && in) filter_14() ; else if (in) filter_6() - ; else if (hev) filter_2() - ; else filter_4() + ; else filter_2_4() ; } ; ; f14: fm & out & in @@ -781,86 +781,49 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride ; f4: fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & hev) => fm & ~in & ~hev ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m4: pb_80, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) - ; filter2() - SWAP 4, 6 -%if %2 != 44 && %2 != 4 - SCRATCH 2, 15, rsp+%3+%4 + ; filter2_4() %if %2 == 16 SCRATCH 1, 8, rsp+%3+%4+16 %endif -%endif - pxor m2, m6, rq0 ; q0 ^ 0x80 - pxor m4, m6, rp0 ; p0 ^ 0x80 - psubsb m2, m4 ; (signed) q0 - p0 - pxor m4, m6, rp1 ; p1 ^ 0x80 - pxor m5, m6, rq1 ; q1 ^ 0x80 - psubsb m4, m5 ; (signed) p1 - q1 - paddsb m4, m2 ; (q0 - p0) + (p1 - q1) - paddsb m4, m2 ; 2*(q0 - p0) + (p1 - q1) - paddsb m4, m2 ; 3*(q0 - p0) + (p1 - q1) - paddsb m6, m4, [pb_4] ; m6: f1 = clip(f + 4, 127) - paddsb m4, [pb_3] ; m4: f2 = clip(f + 3, 127) -%ifdef m8 - mova m14, [pb_10] ; will be reused in filter4() -%define rb10 m14 -%else -%define rb10 [pb_10] -%endif - SRSHIFT3B_2X m6, m4, rb10, m7 ; f1 and f2 sign byte shift by 3 - SIGN_SUB m7, rq0, m6, m5 ; m7 = q0 - f1 - SIGN_ADD m1, rp0, m4, m5 ; m1 = p0 + f2 + pxor m5, m4, rp1 ; p1 - 128 + pxor m7, m4, rq1 ; q1 - 128 + pxor m6, m4, rq0 ; q0 - 128 + psubsb m5, m7 ; clip_i8(p1 - q1) + pxor m7, m4, rp0 ; p0 - 128 + ; mask so we can treat the !hev and hev cases in parallel + pand m5, m0 ; hev ? clip_i8(p1 - q1) : 0 + psubsb m6, m7 ; clip_i8(q0 - p0) + paddsb m5, m6 ; (q0 - p0) + (p1 - q1) + paddsb m5, m6 ; 2*(q0 - p0) + (p1 - q1) + paddsb m5, m6 ; f = 3*(q0 - p0) + (p1 - q1) + ; zero f unless we are in filter2_4 case to ensure that p0, p1, q0, q1 + ; are only changed if they should be %if %2 != 44 && %2 != 4 -%ifdef m8 - pandn m6, m15, m3 ; ~mask(in) & mask(fm) + pandn m7, m2, m3 + pand m5, m7 %else - mova m6, [rsp+%3+%4] - pandn m6, m3 + pand m5, m3 %endif - pand m6, m0 ; (~mask(in) & mask(fm)) & mask(hev) -%else - pand m6, m3, m0 -%endif - MASK_APPLY m7, rq0, m6, m5 ; m7 = filter2(q0) & mask / we write it in filter4() - MASK_APPLY m1, rp0, m6, m5 ; m1 = filter2(p0) & mask / we write it in filter4() - - ; (m0: hev, m1: p0', m2: q0-p0, m3: fm, m7: q0', [m8: flat8out], m10..13: p1 p0 q0 q1, m14: pb_10, [m15: flat8in], ) - ; filter4() - paddsb m4, m2, m2 ; 2 * (q0 - p0) - paddsb m2, m4 ; 3 * (q0 - p0) - paddsb m6, m2, [pb_4] ; m6: f1 = clip(f + 4, 127) - paddsb m2, [pb_3] ; m2: f2 = clip(f + 3, 127) - SRSHIFT3B_2X m6, m2, rb10, m4 ; f1 and f2 sign byte shift by 3 -%if %2 != 44 && %2 != 4 -%ifdef m8 - pandn m5, m15, m3 ; ~mask(in) & mask(fm) -%else - mova m5, [rsp+%3+%4] - pandn m5, m3 -%endif - pandn m0, m5 ; ~mask(hev) & (~mask(in) & mask(fm)) -%else - pandn m0, m3 -%endif - SIGN_SUB m5, rq0, m6, m4 ; q0 - f1 - MASK_APPLY m5, m7, m0, m4 ; filter4(q0) & mask - mova [Q0], m5 - SIGN_ADD m7, rp0, m2, m4 ; p0 + f2 - MASK_APPLY m7, m1, m0, m4 ; filter4(p0) & mask - mova [P0], m7 - paddb m6, [pb_80] ; - pxor m1, m1 ; f=(f1+1)>>1 - pavgb m6, m1 ; - psubb m6, [pb_40] ; - SIGN_ADD m1, rp1, m6, m2 ; p1 + f - SIGN_SUB m4, rq1, m6, m2 ; q1 - f - MASK_APPLY m1, rp1, m0, m2 ; m1 = filter4(p1) - MASK_APPLY m4, rq1, m0, m2 ; m4 = filter4(q1) - mova [P1], m1 - mova [Q1], m4 - -%if %2 != 44 && %2 != 4 - UNSCRATCH 2, 15, rsp+%3+%4 + paddsb m6, m5, [pb_4] ; m6: f1 = clip(f + 4, 127) + paddsb m5, [pb_3] ; m5: f2 = clip(f + 3, 127) + SRSHIFT3B_2X m6, m5, m7 ; f1 and f2 sign byte shift by 3 + pandn m0, m6 ; hev ? 0 : f1 + SIGN_SUB m7, rq0, m6, m1 ; m7 = q0 - f1 + SIGN_ADD m6, rp0, m5, m1 ; m6 = p0 + f2 + mova [Q0], m7 + mova [P0], m6 + pxor m0, m4 ; f1 ^ 0x80 + pxor m5, m5 + pavgb m0, m5 + psubb m0, [pb_40] ; (f1 + 1) >> 1 +%if %2 == 44 || %2 == 4 + SWAP 1, 6 ; m1 = p0 + SWAP 2, 7 ; m2 = q0 %endif + SIGN_ADD m6, rp1, m0, m5 ; p1 + f + SIGN_SUB m7, rq1, m0, m5 ; q1 - f + mova [P1], m6 + mova [Q1], m7 ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) ; filter6() @@ -1052,10 +1015,8 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride movhps [Q7], m7 %endif %elif %2 == 44 || %2 == 4 - SWAP 0, 1 ; m0 = p1 - SWAP 1, 7 ; m1 = p0 - SWAP 2, 5 ; m2 = q0 - SWAP 3, 4 ; m3 = q1 + SWAP 0, 6 ; m0 = p1 + SWAP 3, 7 ; m3 = q1 DEFINE_REAL_P7_TO_Q7 2 SBUTTERFLY bw, 0, 1, 4 SBUTTERFLY bw, 2, 3, 4 -- 2.52.0 >From c821d10fe36704a86268311e26c40bdefe583899 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 9 Jul 2026 20:06:42 +0200 Subject: [PATCH 8/8] avcodec/x86/vp9lpf: Simplify clip_u8(u8+i8) Just subtract 128 from u8 to make it signed, use paddsb and convert back to u8. Saves 2477B of .text here. Old benchmarks: vp9_loop_filter_h_4_8_8bpp_c: 77.5 vp9_loop_filter_h_4_8_8bpp_mmxext: 54.8 ( 1.41x) vp9_loop_filter_h_8_8_8bpp_c: 85.5 vp9_loop_filter_h_8_8_8bpp_mmxext: 75.0 ( 1.12x) vp9_loop_filter_h_16_8_8bpp_c: 139.8 vp9_loop_filter_h_16_16_8bpp_c: 249.7 vp9_loop_filter_h_16_16_8bpp_sse2: 154.9 ( 1.54x) vp9_loop_filter_h_16_16_8bpp_ssse3: 152.9 ( 1.54x) vp9_loop_filter_h_16_16_8bpp_avx: 142.1 ( 1.62x) vp9_loop_filter_mix2_h_44_16_8bpp_c: 167.8 vp9_loop_filter_mix2_h_44_16_8bpp_sse2: 52.3 ( 3.21x) vp9_loop_filter_mix2_h_44_16_8bpp_ssse3: 52.7 ( 3.18x) vp9_loop_filter_mix2_h_44_16_8bpp_avx: 51.9 ( 3.18x) vp9_loop_filter_mix2_h_48_16_8bpp_c: 175.1 vp9_loop_filter_mix2_h_48_16_8bpp_sse2: 73.2 ( 2.39x) vp9_loop_filter_mix2_h_48_16_8bpp_ssse3: 74.9 ( 2.28x) vp9_loop_filter_mix2_h_48_16_8bpp_avx: 69.0 ( 2.54x) vp9_loop_filter_mix2_h_84_16_8bpp_c: 177.7 vp9_loop_filter_mix2_h_84_16_8bpp_sse2: 72.6 ( 2.45x) vp9_loop_filter_mix2_h_84_16_8bpp_ssse3: 71.3 ( 2.48x) vp9_loop_filter_mix2_h_84_16_8bpp_avx: 69.3 ( 2.56x) vp9_loop_filter_mix2_h_88_16_8bpp_c: 184.3 vp9_loop_filter_mix2_h_88_16_8bpp_sse2: 69.6 ( 2.59x) vp9_loop_filter_mix2_h_88_16_8bpp_ssse3: 70.2 ( 2.62x) vp9_loop_filter_mix2_h_88_16_8bpp_avx: 69.3 ( 2.66x) vp9_loop_filter_mix2_v_44_16_8bpp_c: 176.3 vp9_loop_filter_mix2_v_44_16_8bpp_sse2: 22.0 ( 7.98x) vp9_loop_filter_mix2_v_44_16_8bpp_ssse3: 21.4 ( 8.23x) vp9_loop_filter_mix2_v_44_16_8bpp_avx: 21.6 ( 8.18x) vp9_loop_filter_mix2_v_48_16_8bpp_c: 187.8 vp9_loop_filter_mix2_v_48_16_8bpp_sse2: 49.9 ( 3.75x) vp9_loop_filter_mix2_v_48_16_8bpp_ssse3: 47.3 ( 3.96x) vp9_loop_filter_mix2_v_48_16_8bpp_avx: 46.1 ( 4.07x) vp9_loop_filter_mix2_v_84_16_8bpp_c: 189.7 vp9_loop_filter_mix2_v_84_16_8bpp_sse2: 51.2 ( 3.58x) vp9_loop_filter_mix2_v_84_16_8bpp_ssse3: 48.4 ( 3.90x) vp9_loop_filter_mix2_v_84_16_8bpp_avx: 45.9 ( 4.14x) vp9_loop_filter_mix2_v_88_16_8bpp_c: 199.8 vp9_loop_filter_mix2_v_88_16_8bpp_sse2: 51.2 ( 3.88x) vp9_loop_filter_mix2_v_88_16_8bpp_ssse3: 50.5 ( 3.93x) vp9_loop_filter_mix2_v_88_16_8bpp_avx: 45.4 ( 4.40x) vp9_loop_filter_v_4_8_8bpp_c: 83.3 vp9_loop_filter_v_4_8_8bpp_mmxext: 23.2 ( 3.58x) vp9_loop_filter_v_8_8_8bpp_c: 92.6 vp9_loop_filter_v_8_8_8bpp_mmxext: 52.5 ( 1.76x) vp9_loop_filter_v_16_8_8bpp_c: 154.9 vp9_loop_filter_v_16_16_8bpp_c: 291.3 vp9_loop_filter_v_16_16_8bpp_sse2: 104.8 ( 2.68x) vp9_loop_filter_v_16_16_8bpp_ssse3: 107.5 ( 2.64x) vp9_loop_filter_v_16_16_8bpp_avx: 97.7 ( 2.90x) New benchmarks: vp9_loop_filter_h_4_8_8bpp_c: 77.1 vp9_loop_filter_h_4_8_8bpp_mmxext: 52.0 ( 1.48x) vp9_loop_filter_h_8_8_8bpp_c: 85.6 vp9_loop_filter_h_8_8_8bpp_mmxext: 73.3 ( 1.17x) vp9_loop_filter_h_16_8_8bpp_c: 139.2 vp9_loop_filter_h_16_16_8bpp_c: 252.4 vp9_loop_filter_h_16_16_8bpp_sse2: 149.3 ( 1.60x) vp9_loop_filter_h_16_16_8bpp_ssse3: 149.3 ( 1.62x) vp9_loop_filter_h_16_16_8bpp_avx: 140.2 ( 1.77x) vp9_loop_filter_mix2_h_44_16_8bpp_c: 168.5 vp9_loop_filter_mix2_h_44_16_8bpp_sse2: 48.4 ( 3.48x) vp9_loop_filter_mix2_h_44_16_8bpp_ssse3: 49.6 ( 3.39x) vp9_loop_filter_mix2_h_44_16_8bpp_avx: 49.0 ( 3.43x) vp9_loop_filter_mix2_h_48_16_8bpp_c: 174.8 vp9_loop_filter_mix2_h_48_16_8bpp_sse2: 66.0 ( 2.65x) vp9_loop_filter_mix2_h_48_16_8bpp_ssse3: 64.9 ( 2.69x) vp9_loop_filter_mix2_h_48_16_8bpp_avx: 64.6 ( 2.65x) vp9_loop_filter_mix2_h_84_16_8bpp_c: 177.6 vp9_loop_filter_mix2_h_84_16_8bpp_sse2: 70.5 ( 2.51x) vp9_loop_filter_mix2_h_84_16_8bpp_ssse3: 66.8 ( 2.65x) vp9_loop_filter_mix2_h_84_16_8bpp_avx: 66.3 ( 2.68x) vp9_loop_filter_mix2_h_88_16_8bpp_c: 185.6 vp9_loop_filter_mix2_h_88_16_8bpp_sse2: 72.1 ( 2.50x) vp9_loop_filter_mix2_h_88_16_8bpp_ssse3: 70.7 ( 2.54x) vp9_loop_filter_mix2_h_88_16_8bpp_avx: 65.5 ( 2.83x) vp9_loop_filter_mix2_v_44_16_8bpp_c: 175.9 vp9_loop_filter_mix2_v_44_16_8bpp_sse2: 19.2 ( 9.17x) vp9_loop_filter_mix2_v_44_16_8bpp_ssse3: 19.2 ( 9.16x) vp9_loop_filter_mix2_v_44_16_8bpp_avx: 19.1 ( 9.18x) vp9_loop_filter_mix2_v_48_16_8bpp_c: 186.9 vp9_loop_filter_mix2_v_48_16_8bpp_sse2: 49.6 ( 3.73x) vp9_loop_filter_mix2_v_48_16_8bpp_ssse3: 47.7 ( 3.89x) vp9_loop_filter_mix2_v_48_16_8bpp_avx: 43.6 ( 4.28x) vp9_loop_filter_mix2_v_84_16_8bpp_c: 189.1 vp9_loop_filter_mix2_v_84_16_8bpp_sse2: 45.8 ( 4.12x) vp9_loop_filter_mix2_v_84_16_8bpp_ssse3: 46.6 ( 4.05x) vp9_loop_filter_mix2_v_84_16_8bpp_avx: 43.0 ( 4.27x) vp9_loop_filter_mix2_v_88_16_8bpp_c: 198.6 vp9_loop_filter_mix2_v_88_16_8bpp_sse2: 43.5 ( 4.57x) vp9_loop_filter_mix2_v_88_16_8bpp_ssse3: 43.3 ( 4.57x) vp9_loop_filter_mix2_v_88_16_8bpp_avx: 43.0 ( 4.62x) vp9_loop_filter_v_4_8_8bpp_c: 83.2 vp9_loop_filter_v_4_8_8bpp_mmxext: 21.8 ( 3.81x) vp9_loop_filter_v_8_8_8bpp_c: 92.3 vp9_loop_filter_v_8_8_8bpp_mmxext: 51.5 ( 1.79x) vp9_loop_filter_v_16_8_8bpp_c: 155.6 vp9_loop_filter_v_16_16_8bpp_c: 290.3 vp9_loop_filter_v_16_16_8bpp_sse2: 105.1 ( 2.68x) vp9_loop_filter_v_16_16_8bpp_ssse3: 103.8 ( 2.72x) vp9_loop_filter_v_16_16_8bpp_avx: 97.7 ( 2.86x) Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp9lpf.asm | 51 +++++++++++++++------------------------ 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index e4366e8713..13a3530b19 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -232,27 +232,18 @@ SECTION .text psubb %2, %3 %endmacro -%macro EXTRACT_POS_NEG 3 ; i8, neg, pos - pxor %3, %3 - pxor %2, %2 - pcmpgtb %3, %1 ; i8 < 0 mask - psubb %2, %1 ; neg values (only the originally - will be kept) - pand %2, %3 ; negative values of i8 (but stored as +) - pandn %3, %1 ; positive values of i8 -%endmacro - -; clip_u8(u8 + i8) -%macro SIGN_ADD 4 ; dst, u8, i8, tmp1 - EXTRACT_POS_NEG %3, %4, %1 - paddusb %1, %2 ; add the positives - psubusb %1, %4 ; sub the negatives -%endmacro - -; clip_u8(u8 - i8) -%macro SIGN_SUB 4 ; dst, u8, i8, tmp1 - EXTRACT_POS_NEG %3, %1, %4 - paddusb %1, %2 ; add the negatives - psubusb %1, %4 ; sub the positives +%macro ADD_SUB_CLIP 8; dst0, dst1, u8_0, u8_1, i8_0, i8_1, pb_80, tmp + pxor m%8, %7, %3 + paddsb m%1, m%5, m%8 + pxor m%8, %7, %4 +%if avx_enabled + psubsb m%2, m%8, m%6 +%else + psubsb m%8, m%6 + SWAP %2, %8 +%endif + pxor m%1, %7 + pxor m%2, %7 %endmacro %macro FILTER6_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off @@ -808,20 +799,18 @@ cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride paddsb m5, [pb_3] ; m5: f2 = clip(f + 3, 127) SRSHIFT3B_2X m6, m5, m7 ; f1 and f2 sign byte shift by 3 pandn m0, m6 ; hev ? 0 : f1 - SIGN_SUB m7, rq0, m6, m1 ; m7 = q0 - f1 - SIGN_ADD m6, rp0, m5, m1 ; m6 = p0 + f2 - mova [Q0], m7 - mova [P0], m6 + ADD_SUB_CLIP 5, 6, rp0, rq0, 5, 6, m4, 7 ; m5 = p0 + f2, m6 = q0 - f1 + mova [Q0], m6 + mova [P0], m5 pxor m0, m4 ; f1 ^ 0x80 - pxor m5, m5 - pavgb m0, m5 + pxor m7, m7 + pavgb m0, m7 psubb m0, [pb_40] ; (f1 + 1) >> 1 %if %2 == 44 || %2 == 4 - SWAP 1, 6 ; m1 = p0 - SWAP 2, 7 ; m2 = q0 + SWAP 1, 5 ; m1 = p0 + SWAP 2, 6 ; m2 = q0 %endif - SIGN_ADD m6, rp1, m0, m5 ; p1 + f - SIGN_SUB m7, rq1, m0, m5 ; q1 - f + ADD_SUB_CLIP 6, 7, rp1, rq1, 0, 0, m4, 5 ; m6 = p1 + f, m7 = q1 - f mova [P1], m6 mova [Q1], m7 -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
