[PR] avcodec/x86/vc1dsp*: Improve loop filter, avoid MMX in loop filter, inv trans (PR #23949)
mkver via ffmpeg-devel <[email protected]> Wed, 29 Jul 2026 15:00:37 -0000
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <178533723846.51.6110903665477993785@29965ddac10e> |
PR #23949 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23949 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23949.patch >From 84fab7ff090d49e9fdaa9bde83770534602d82a2 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Tue, 21 Jul 2026 17:57:24 +0200 Subject: [PATCH 01/10] avcodec/x86/vc1dsp_init: Avoid fpel wrappers One can just reuse the already existing SIZExSIZE fpel wrappers. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/fpel.asm | 13 +++++++++++++ libavcodec/x86/vc1dsp_init.c | 18 +----------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/libavcodec/x86/fpel.asm b/libavcodec/x86/fpel.asm index 598a57ab0d..e7d2dcc8f7 100644 --- a/libavcodec/x86/fpel.asm +++ b/libavcodec/x86/fpel.asm @@ -26,6 +26,18 @@ SECTION .text INIT_XMM sse2 + +%macro VC1_FPEL_FUNC 2 ; avg vs put, size +%if CONFIG_VC1DSP +; void ff_vc1_{avg,put}_mspel_mc00_{8,16}_sse2(uint8_t *dst, const uint8_t *src, +; ptrdiff_t stride, int rnd) +; rnd is unused for fpel functions and for all supported ABIs +; we can just reuse the SIZExSIZE functions. +cglobal vc1_%1_mspel_mc00_%2 +%endif +%endmacro + +VC1_FPEL_FUNC avg, 8 ; void ff_avg_pixels8x8_sse2(uint8_t *block, const uint8_t *pixels, ; ptrdiff_t line_size) cglobal avg_pixels8x8, 3,5,6 @@ -67,6 +79,7 @@ avg_pixels8_after_prologue: %define LOAD movu %define SAVE mova %endif +VC1_FPEL_FUNC %1, %2 cglobal %1_pixels%2x%2, 3,5+4*%3,4 mov r3d, %2 jmp %1_pixels%2_after_prologue diff --git a/libavcodec/x86/vc1dsp_init.c b/libavcodec/x86/vc1dsp_init.c index d0705f6bfb..e5a177cb76 100644 --- a/libavcodec/x86/vc1dsp_init.c +++ b/libavcodec/x86/vc1dsp_init.c @@ -28,7 +28,6 @@ #include "libavutil/cpu.h" #include "libavutil/x86/cpu.h" #include "libavcodec/vc1dsp.h" -#include "fpel.h" #include "vc1dsp.h" #include "config.h" @@ -63,18 +62,6 @@ static void vc1_h_loop_filter16_sse4(uint8_t *src, ptrdiff_t stride, int pq) ff_vc1_h_loop_filter8_sse4(src+8*stride, stride, pq); } -#define DECLARE_FUNCTION(OP, DEPTH, INSN) \ - static void OP##vc1_mspel_mc00_##DEPTH##INSN(uint8_t *dst, \ - const uint8_t *src, ptrdiff_t stride, int rnd) \ - { \ - ff_ ## OP ## pixels ## DEPTH ## INSN(dst, src, stride, DEPTH); \ - } - -DECLARE_FUNCTION(put_, 8, _sse2) -DECLARE_FUNCTION(avg_, 8, _sse2) -DECLARE_FUNCTION(put_, 16, _sse2) -DECLARE_FUNCTION(avg_, 16, _sse2) - void ff_put_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h, int x, int y); void ff_avg_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, const uint8_t *src, @@ -132,10 +119,7 @@ av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp) if (EXTERNAL_SSE2(cpu_flags)) { ASSIGN_LF816(sse2); - dsp->put_vc1_mspel_pixels_tab[0][0] = put_vc1_mspel_mc00_16_sse2; - dsp->put_vc1_mspel_pixels_tab[1][0] = put_vc1_mspel_mc00_8_sse2; - dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_vc1_mspel_mc00_16_sse2; - dsp->avg_vc1_mspel_pixels_tab[1][0] = avg_vc1_mspel_mc00_8_sse2; + MSPEL_FUNCS(0, 0, sse2); } if (EXTERNAL_SSSE3(cpu_flags)) { ASSIGN_LF4(ssse3); -- 2.52.0 >From eec7dd83623d982ad1599cd8be3fbb5633e30315 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Wed, 22 Jul 2026 11:34:40 +0200 Subject: [PATCH 02/10] avcodec/vc1dsp: Avoid negating unnecessarily Due to the earlier "if (a1 < a0 || a2 < a0)" check it is guaranteed that min(a1,a2) is < a0, allowing simplifications. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/vc1dsp.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c index dd143b114c..355e4b8b02 100644 --- a/libavcodec/vc1dsp.c +++ b/libavcodec/vc1dsp.c @@ -166,17 +166,11 @@ static av_always_inline int vc1_filter_line(uint8_t *src, ptrdiff_t stride, int clip = ((clip ^ clip_sign) - clip_sign) >> 1; if (clip) { int a3 = FFMIN(a1, a2); - int d = 5 * (a3 - a0); - int d_sign = (d >> 31); + int d = (5 * (a0 - a3)) >> 3; - d = ((d ^ d_sign) - d_sign) >> 3; - d_sign ^= a0_sign; - - if (d_sign ^ clip_sign) - d = 0; - else { + if (a0_sign ^ clip_sign) { d = FFMIN(d, clip); - d = (d ^ d_sign) - d_sign; /* Restore sign */ + d = (d ^ clip_sign) - clip_sign; /* Restore sign */ src[-1 * stride] = av_clip_uint8(src[-1 * stride] - d); src[ 0 * stride] = av_clip_uint8(src[ 0 * stride] + d); } -- 2.52.0 >From c23d742fdf96a3caeb8fa6b85a92ca3848282874 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 23 Jul 2026 01:19:49 +0200 Subject: [PATCH 03/10] avcodec/x86/vc1dsp_loopfilter: Avoid imul Multipliying a GPR by 0x01010101 splats a byte to a dword; the intention was to avoid vector shuffles lateron, yet this is not true because the byte splat necessitates a byte->word conversion lateron. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_loopfilter.asm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/x86/vc1dsp_loopfilter.asm b/libavcodec/x86/vc1dsp_loopfilter.asm index f1367da5fa..373608588f 100644 --- a/libavcodec/x86/vc1dsp_loopfilter.asm +++ b/libavcodec/x86/vc1dsp_loopfilter.asm @@ -89,9 +89,10 @@ SECTION .text pxor m5, m5 movd m3, r2d %if %1 > 4 - punpcklbw m3, m3 + SPLATW m3, m3 +%else + pshufw m3, m3, 0 %endif - punpcklbw m3, m5 pcmpgtw m3, m4 ; if (a0 < pq) pand m6, m3 @@ -217,7 +218,6 @@ SECTION .text lea r3, [4*r1] sub r4, r3 lea r3, [r1+2*r1] - imul r2, 0x01010101 %endmacro %macro START_H_FILTER 1 @@ -225,7 +225,6 @@ SECTION .text %if %1 > 4 lea r4, [r0+4*r1] %endif - imul r2, 0x01010101 %endmacro INIT_XMM sse2 -- 2.52.0 >From 1ce1e0194350b24cfc641ca648b7874d91776ee6 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 23 Jul 2026 01:47:49 +0200 Subject: [PATCH 04/10] avcodec/x86/vc1dsp_loopfilter: Reduce number of GPRs used Reuse the register that held pq for this instead of using another one. This saves a push+pop on 32bit systems and avoids REX prefixes on Unix64. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_loopfilter.asm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libavcodec/x86/vc1dsp_loopfilter.asm b/libavcodec/x86/vc1dsp_loopfilter.asm index 373608588f..0db1ebc8e3 100644 --- a/libavcodec/x86/vc1dsp_loopfilter.asm +++ b/libavcodec/x86/vc1dsp_loopfilter.asm @@ -235,9 +235,9 @@ cglobal vc1_v_loop_filter8, 3,5,8 RET ; void ff_vc1_h_loop_filter8_sse2(uint8_t *src, ptrdiff_t stride, int pq) -cglobal vc1_h_loop_filter8, 3,6,8 +cglobal vc1_h_loop_filter8, 3,5,8 START_H_FILTER 8 - VC1_H_LOOP_FILTER 8, r5 + VC1_H_LOOP_FILTER 8, r2 RET INIT_MMX ssse3 @@ -248,9 +248,9 @@ cglobal vc1_v_loop_filter4, 3,5,0 RET ; void ff_vc1_h_loop_filter4_ssse3(uint8_t *src, ptrdiff_t stride, int pq) -cglobal vc1_h_loop_filter4, 3,5,0 +cglobal vc1_h_loop_filter4, 3,4,0 START_H_FILTER 4 - VC1_H_LOOP_FILTER 4, r4 + VC1_H_LOOP_FILTER 4, r2 RET INIT_XMM ssse3 @@ -261,9 +261,9 @@ cglobal vc1_v_loop_filter8, 3,5,8 RET ; void ff_vc1_h_loop_filter8_ssse3(uint8_t *src, ptrdiff_t stride, int pq) -cglobal vc1_h_loop_filter8, 3,6,8 +cglobal vc1_h_loop_filter8, 3,5,8 START_H_FILTER 8 - VC1_H_LOOP_FILTER 8, r5 + VC1_H_LOOP_FILTER 8, r2 RET INIT_XMM sse4 -- 2.52.0 >From 96ffce169807f5eea12a4882f8ad6f93d1e059a3 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Mon, 27 Jul 2026 00:41:39 +0200 Subject: [PATCH 05/10] avcodec/x86/vc1dsp_loopfilter: Reorder instructions slightly In particular, apply the rounding before adding the result of the multiplication. No change in performance here. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_loopfilter.asm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/x86/vc1dsp_loopfilter.asm b/libavcodec/x86/vc1dsp_loopfilter.asm index 0db1ebc8e3..fa42864ae1 100644 --- a/libavcodec/x86/vc1dsp_loopfilter.asm +++ b/libavcodec/x86/vc1dsp_loopfilter.asm @@ -60,12 +60,12 @@ SECTION .text ; in: p1 p0 q0 q1, clobbers p0 ; out: p1 = (2*(p1 - q1) - 5*(p0 - q0) + 4) >> 3 %macro VC1_LOOP_FILTER_A0 4 - psubw %1, %4 psubw %2, %3 - paddw %1, %1 + psubw %1, %4 pmullw %2, [pw_5] - psubw %1, %2 + paddw %1, %1 paddw %1, [pw_4] + psubw %1, %2 psraw %1, 3 %endmacro -- 2.52.0 >From bf410d22a4c34cb60a6cbedbfad4cd226c62ad40 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 23 Jul 2026 15:11:19 +0200 Subject: [PATCH 06/10] avcodec/x86/vc1dsp_loopfilter: Avoid unnecessary PABSW The loop filter is only active if min(a1,a2)<abs(a0) which is done via masking. Ergo the sign of min(a1,a2)-abs(a0) is known (always negative) and one does not need to use PABSW to get its absolute value. This gives a small speedup. Old benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.1 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 33.6 ( 0.09x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 43.0 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 33.4 ( 1.29x) vc1dsp.vc1_h_loop_filter8_bestcase_c: 6.0 vc1dsp.vc1_h_loop_filter8_bestcase_sse2: 38.4 ( 0.16x) vc1dsp.vc1_h_loop_filter8_bestcase_ssse3: 37.2 ( 0.16x) vc1dsp.vc1_h_loop_filter8_bestcase_sse4: 37.6 ( 0.16x) vc1dsp.vc1_h_loop_filter8_worstcase_c: 87.5 vc1dsp.vc1_h_loop_filter8_worstcase_sse2: 38.4 ( 2.28x) vc1dsp.vc1_h_loop_filter8_worstcase_ssse3: 37.6 ( 2.32x) vc1dsp.vc1_h_loop_filter8_worstcase_sse4: 37.6 ( 2.32x) vc1dsp.vc1_h_loop_filter16_bestcase_c: 11.7 vc1dsp.vc1_h_loop_filter16_bestcase_sse2: 42.0 ( 0.28x) vc1dsp.vc1_h_loop_filter16_bestcase_ssse3: 41.4 ( 0.28x) vc1dsp.vc1_h_loop_filter16_bestcase_sse4: 44.8 ( 0.26x) vc1dsp.vc1_h_loop_filter16_worstcase_c: 167.2 vc1dsp.vc1_h_loop_filter16_worstcase_sse2: 41.8 ( 4.00x) vc1dsp.vc1_h_loop_filter16_worstcase_ssse3: 41.7 ( 3.92x) vc1dsp.vc1_h_loop_filter16_worstcase_sse4: 45.3 ( 3.69x) vc1dsp.vc1_v_loop_filter4_bestcase_c: 3.6 vc1dsp.vc1_v_loop_filter4_bestcase_ssse3: 17.1 ( 0.21x) vc1dsp.vc1_v_loop_filter4_worstcase_c: 49.3 vc1dsp.vc1_v_loop_filter4_worstcase_ssse3: 17.0 ( 2.89x) vc1dsp.vc1_v_loop_filter8_bestcase_c: 6.3 vc1dsp.vc1_v_loop_filter8_bestcase_sse2: 17.7 ( 0.36x) vc1dsp.vc1_v_loop_filter8_bestcase_ssse3: 16.8 ( 0.38x) vc1dsp.vc1_v_loop_filter8_worstcase_c: 85.8 vc1dsp.vc1_v_loop_filter8_worstcase_sse2: 17.7 ( 4.83x) vc1dsp.vc1_v_loop_filter8_worstcase_ssse3: 16.7 ( 5.12x) vc1dsp.vc1_v_loop_filter16_bestcase_c: 12.7 vc1dsp.vc1_v_loop_filter16_bestcase_sse2: 26.4 ( 0.48x) vc1dsp.vc1_v_loop_filter16_bestcase_ssse3: 24.0 ( 0.53x) vc1dsp.vc1_v_loop_filter16_worstcase_c: 170.1 vc1dsp.vc1_v_loop_filter16_worstcase_sse2: 25.7 ( 6.63x) vc1dsp.vc1_v_loop_filter16_worstcase_ssse3: 25.2 ( 6.75x) New benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.0 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 32.4 ( 0.09x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 42.3 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 32.7 ( 1.29x) vc1dsp.vc1_h_loop_filter8_bestcase_c: 6.1 vc1dsp.vc1_h_loop_filter8_bestcase_sse2: 37.1 ( 0.17x) vc1dsp.vc1_h_loop_filter8_bestcase_ssse3: 36.4 ( 0.17x) vc1dsp.vc1_h_loop_filter8_bestcase_sse4: 36.6 ( 0.17x) vc1dsp.vc1_h_loop_filter8_worstcase_c: 87.2 vc1dsp.vc1_h_loop_filter8_worstcase_sse2: 36.9 ( 2.36x) vc1dsp.vc1_h_loop_filter8_worstcase_ssse3: 35.8 ( 2.35x) vc1dsp.vc1_h_loop_filter8_worstcase_sse4: 36.7 ( 2.38x) vc1dsp.vc1_h_loop_filter16_bestcase_c: 12.0 vc1dsp.vc1_h_loop_filter16_bestcase_sse2: 40.0 ( 0.30x) vc1dsp.vc1_h_loop_filter16_bestcase_ssse3: 39.8 ( 0.30x) vc1dsp.vc1_h_loop_filter16_bestcase_sse4: 44.4 ( 0.27x) vc1dsp.vc1_h_loop_filter16_worstcase_c: 166.4 vc1dsp.vc1_h_loop_filter16_worstcase_sse2: 39.9 ( 4.17x) vc1dsp.vc1_h_loop_filter16_worstcase_ssse3: 39.7 ( 4.19x) vc1dsp.vc1_h_loop_filter16_worstcase_sse4: 43.8 ( 3.80x) vc1dsp.vc1_v_loop_filter4_bestcase_c: 3.6 vc1dsp.vc1_v_loop_filter4_bestcase_ssse3: 16.3 ( 0.22x) vc1dsp.vc1_v_loop_filter4_worstcase_c: 49.3 vc1dsp.vc1_v_loop_filter4_worstcase_ssse3: 16.2 ( 3.04x) vc1dsp.vc1_v_loop_filter8_bestcase_c: 6.4 vc1dsp.vc1_v_loop_filter8_bestcase_sse2: 16.3 ( 0.39x) vc1dsp.vc1_v_loop_filter8_bestcase_ssse3: 15.8 ( 0.40x) vc1dsp.vc1_v_loop_filter8_worstcase_c: 85.7 vc1dsp.vc1_v_loop_filter8_worstcase_sse2: 16.3 ( 5.24x) vc1dsp.vc1_v_loop_filter8_worstcase_ssse3: 15.8 ( 5.42x) vc1dsp.vc1_v_loop_filter16_bestcase_c: 12.7 vc1dsp.vc1_v_loop_filter16_bestcase_sse2: 24.7 ( 0.52x) vc1dsp.vc1_v_loop_filter16_bestcase_ssse3: 22.7 ( 0.56x) vc1dsp.vc1_v_loop_filter16_worstcase_c: 169.4 vc1dsp.vc1_v_loop_filter16_worstcase_sse2: 24.1 ( 7.03x) vc1dsp.vc1_v_loop_filter16_worstcase_ssse3: 24.6 ( 6.88x) Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_loopfilter.asm | 68 ++++++++++++---------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/libavcodec/x86/vc1dsp_loopfilter.asm b/libavcodec/x86/vc1dsp_loopfilter.asm index fa42864ae1..883896a3ed 100644 --- a/libavcodec/x86/vc1dsp_loopfilter.asm +++ b/libavcodec/x86/vc1dsp_loopfilter.asm @@ -74,56 +74,44 @@ SECTION .text ; %1: size ; out: m0=p0' m1=q0' %macro VC1_FILTER 1 - PABSW m4, m7 PABSW m3, m6 + movd m6, r2d PABSW m2, m5 - mova m6, m4 + PABSW m4, m7 + PSHUFLW m6, m6, 0 pminsw m3, m2 - pcmpgtw m6, m3 ; if (a2 < a0 || a1 < a0) - psubw m3, m4 - pmullw m3, [pw_5] ; 5*(a3 - a0) - PABSW m2, m3 - psraw m2, 3 ; abs(d/8) - pxor m7, m3 ; d_sign ^= a0_sign - - pxor m5, m5 - movd m3, r2d + pcmpgtw m2, m4, m3 ; if (a2 < a0 || a1 < a0) %if %1 > 4 - SPLATW m3, m3 -%else - pshufw m3, m3, 0 + punpcklqdq m6, m6 %endif - pcmpgtw m3, m4 ; if (a0 < pq) - pand m6, m3 - - mova m3, m0 - psubw m3, m1 - PABSW m4, m3 - psraw m4, 1 - pxor m3, m7 ; d_sign ^ clip_sign + pcmpgtw m6, m4 ; if (a0 < pq) + psubw m4, m3 + psubw m3, m0, m1 ; clip + pmullw m4, [pw_5] ; 5*(a0 - a3) + PABSW m5, m3 + pand m6, m2 ; if (min(a1,a2) < a0 && a0 < pq) + psraw m5, 1 ; final clip + psraw m4, 3 ; d = (5*(a0 - a3)) >> 3 + pxor m2, m2 + pminsw m4, m5 ; d = min(d, clip) psraw m3, 15 - pminsw m2, m4 ; min(d, clip) - pcmpgtw m4, m5 - pand m6, m4 ; filt3 (C return value) + pcmpgtw m5, m2 ; if (clip) + pxor m7, m3 ; a0_sign ^ clip_sign + pand m6, m5 ; filt3 (C return value) ; each set of 4 pixels is not filtered if the 3rd is not -%if mmsize==16 - pshuflw m4, m6, 0xaa + PSHUFLW m5, m6, q2222 + psraw m7, 15 ; a0_sign ^ clip_sign as mask + pand m4, m6 %if %1 > 4 - pshufhw m4, m4, 0xaa + pshufhw m5, m5, q2222 %endif -%else - pshufw m4, m6, 0xaa -%endif - pandn m3, m4 - pand m2, m6 - pand m3, m2 ; d final - - psraw m7, 15 - pxor m3, m7 - psubw m3, m7 - psubw m0, m3 - paddw m1, m3 + pxor m4, m3 + pand m5, m7 + psubw m4, m3 + pand m4, m5 + psubw m0, m4 + paddw m1, m4 packuswb m0, m0 packuswb m1, m1 %endmacro -- 2.52.0 >From fca75b752ea59416e269066bb02b76cf7085c4f6 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 24 Jul 2026 13:07:35 +0200 Subject: [PATCH 07/10] avcodec/x86/vc1dsp_loopfilter: Use psignw when available The VC1 loop filter uses something equivalent to if (a0_sign ^ clip_sign) { if (clip_sign) d = -d; } else d = 0; which can be mapped to psignw. Old benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.0 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 32.4 ( 0.09x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 42.3 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 32.7 ( 1.29x) vc1dsp.vc1_h_loop_filter8_bestcase_c: 6.1 vc1dsp.vc1_h_loop_filter8_bestcase_sse2: 37.1 ( 0.17x) vc1dsp.vc1_h_loop_filter8_bestcase_ssse3: 36.4 ( 0.17x) vc1dsp.vc1_h_loop_filter8_bestcase_sse4: 36.6 ( 0.17x) vc1dsp.vc1_h_loop_filter8_worstcase_c: 87.2 vc1dsp.vc1_h_loop_filter8_worstcase_sse2: 36.9 ( 2.36x) vc1dsp.vc1_h_loop_filter8_worstcase_ssse3: 35.8 ( 2.35x) vc1dsp.vc1_h_loop_filter8_worstcase_sse4: 36.7 ( 2.38x) vc1dsp.vc1_h_loop_filter16_bestcase_c: 12.0 vc1dsp.vc1_h_loop_filter16_bestcase_sse2: 40.0 ( 0.30x) vc1dsp.vc1_h_loop_filter16_bestcase_ssse3: 39.8 ( 0.30x) vc1dsp.vc1_h_loop_filter16_bestcase_sse4: 44.4 ( 0.27x) vc1dsp.vc1_h_loop_filter16_worstcase_c: 166.4 vc1dsp.vc1_h_loop_filter16_worstcase_sse2: 39.9 ( 4.17x) vc1dsp.vc1_h_loop_filter16_worstcase_ssse3: 39.7 ( 4.19x) vc1dsp.vc1_h_loop_filter16_worstcase_sse4: 43.8 ( 3.80x) vc1dsp.vc1_v_loop_filter4_bestcase_c: 3.6 vc1dsp.vc1_v_loop_filter4_bestcase_ssse3: 16.3 ( 0.22x) vc1dsp.vc1_v_loop_filter4_worstcase_c: 49.3 vc1dsp.vc1_v_loop_filter4_worstcase_ssse3: 16.2 ( 3.04x) vc1dsp.vc1_v_loop_filter8_bestcase_c: 6.4 vc1dsp.vc1_v_loop_filter8_bestcase_sse2: 16.3 ( 0.39x) vc1dsp.vc1_v_loop_filter8_bestcase_ssse3: 15.8 ( 0.40x) vc1dsp.vc1_v_loop_filter8_worstcase_c: 85.7 vc1dsp.vc1_v_loop_filter8_worstcase_sse2: 16.3 ( 5.24x) vc1dsp.vc1_v_loop_filter8_worstcase_ssse3: 15.8 ( 5.42x) vc1dsp.vc1_v_loop_filter16_bestcase_c: 12.7 vc1dsp.vc1_v_loop_filter16_bestcase_sse2: 24.7 ( 0.52x) vc1dsp.vc1_v_loop_filter16_bestcase_ssse3: 22.7 ( 0.56x) vc1dsp.vc1_v_loop_filter16_worstcase_c: 169.4 vc1dsp.vc1_v_loop_filter16_worstcase_sse2: 24.1 ( 7.03x) vc1dsp.vc1_v_loop_filter16_worstcase_ssse3: 24.6 ( 6.88x) New benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.0 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 32.0 ( 0.09x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 43.2 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 31.8 ( 1.36x) vc1dsp.vc1_h_loop_filter8_bestcase_c: 6.0 vc1dsp.vc1_h_loop_filter8_bestcase_sse2: 36.9 ( 0.16x) vc1dsp.vc1_h_loop_filter8_bestcase_ssse3: 35.5 ( 0.17x) vc1dsp.vc1_h_loop_filter8_bestcase_sse4: 36.2 ( 0.17x) vc1dsp.vc1_h_loop_filter8_worstcase_c: 87.3 vc1dsp.vc1_h_loop_filter8_worstcase_sse2: 37.6 ( 2.33x) vc1dsp.vc1_h_loop_filter8_worstcase_ssse3: 35.3 ( 2.40x) vc1dsp.vc1_h_loop_filter8_worstcase_sse4: 36.1 ( 2.42x) vc1dsp.vc1_h_loop_filter16_bestcase_c: 11.8 vc1dsp.vc1_h_loop_filter16_bestcase_sse2: 40.1 ( 0.29x) vc1dsp.vc1_h_loop_filter16_bestcase_ssse3: 39.2 ( 0.30x) vc1dsp.vc1_h_loop_filter16_bestcase_sse4: 42.9 ( 0.28x) vc1dsp.vc1_h_loop_filter16_worstcase_c: 166.5 vc1dsp.vc1_h_loop_filter16_worstcase_sse2: 39.8 ( 4.18x) vc1dsp.vc1_h_loop_filter16_worstcase_ssse3: 39.1 ( 4.26x) vc1dsp.vc1_h_loop_filter16_worstcase_sse4: 42.9 ( 3.88x) vc1dsp.vc1_v_loop_filter4_bestcase_c: 3.6 vc1dsp.vc1_v_loop_filter4_bestcase_ssse3: 15.7 ( 0.22x) vc1dsp.vc1_v_loop_filter4_worstcase_c: 49.1 vc1dsp.vc1_v_loop_filter4_worstcase_ssse3: 15.8 ( 3.10x) vc1dsp.vc1_v_loop_filter8_bestcase_c: 6.4 vc1dsp.vc1_v_loop_filter8_bestcase_sse2: 16.3 ( 0.39x) vc1dsp.vc1_v_loop_filter8_bestcase_ssse3: 15.3 ( 0.42x) vc1dsp.vc1_v_loop_filter8_worstcase_c: 85.7 vc1dsp.vc1_v_loop_filter8_worstcase_sse2: 16.3 ( 5.26x) vc1dsp.vc1_v_loop_filter8_worstcase_ssse3: 15.2 ( 5.62x) vc1dsp.vc1_v_loop_filter16_bestcase_c: 13.6 vc1dsp.vc1_v_loop_filter16_bestcase_sse2: 24.8 ( 0.55x) vc1dsp.vc1_v_loop_filter16_bestcase_ssse3: 21.3 ( 0.64x) vc1dsp.vc1_v_loop_filter16_worstcase_c: 170.0 vc1dsp.vc1_v_loop_filter16_worstcase_sse2: 23.9 ( 7.11x) vc1dsp.vc1_v_loop_filter16_worstcase_ssse3: 23.3 ( 7.28x) Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_loopfilter.asm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libavcodec/x86/vc1dsp_loopfilter.asm b/libavcodec/x86/vc1dsp_loopfilter.asm index 883896a3ed..7f4783afa7 100644 --- a/libavcodec/x86/vc1dsp_loopfilter.asm +++ b/libavcodec/x86/vc1dsp_loopfilter.asm @@ -94,21 +94,40 @@ SECTION .text psraw m4, 3 ; d = (5*(a0 - a3)) >> 3 pxor m2, m2 pminsw m4, m5 ; d = min(d, clip) +%if cpuflag(ssse3) + ; m3 and m7 are in the -255..255 range, so that every bit in each word's + ; upper half coincides with the sign bit. When subtracting as bytes + ; the upper byte of every word is 0 if m3 and m7 have the same sign, + ; 1 if m7 (a0_sign) is negative/set but m3 is not and -1 else. + ; After the right shift by eight bits below, the value of the word + ; coincides with the current value of the upper byte. + psubb m3, m7 + pcmpgtw m5, m2 ; if (clip) +%else psraw m3, 15 pcmpgtw m5, m2 ; if (clip) pxor m7, m3 ; a0_sign ^ clip_sign +%endif pand m6, m5 ; filt3 (C return value) ; each set of 4 pixels is not filtered if the 3rd is not PSHUFLW m5, m6, q2222 +%if cpuflag(ssse3) + psraw m3, 8 +%else psraw m7, 15 ; a0_sign ^ clip_sign as mask +%endif pand m4, m6 %if %1 > 4 pshufhw m5, m5, q2222 %endif +%if cpuflag(ssse3) + psignw m4, m3 +%else pxor m4, m3 pand m5, m7 psubw m4, m3 +%endif pand m4, m5 psubw m0, m4 paddw m1, m4 -- 2.52.0 >From 7c460deac89b378435909cb39c28293c5bd94994 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Sat, 25 Jul 2026 22:45:56 +0200 Subject: [PATCH 08/10] avcodec/x86/vc1dsp_loopfilter: Don't use MMX regs in horiz. loop filter Using XMM registers in this SSSE3 function leads to fewer shuffles when transposing the input; it also allows to combine calculating a1 and a2. Because of this, codesize is the same as before (on Unix64) although MMX instructions are shorter. Old benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.0 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 32.0 ( 0.09x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 42.9 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 31.9 ( 1.35x) New benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.0 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 29.9 ( 0.10x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 43.7 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 29.9 ( 1.46x) Hint: checkasm's benchmark always uses the same buffer that is partially updated by the horizontal loop filter function (the middle two of eight columns are updated using word-sized stores). They therefore lead to store-to-load-forwarding failure. If checkasm_alternate were used to alternate between two buffers, the benchmarks would be as follows: Old benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.0 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 16.4 ( 0.18x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 23.9 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 16.3 ( 1.47x) New benchmarks: vc1dsp.vc1_h_loop_filter4_bestcase_c: 3.0 vc1dsp.vc1_h_loop_filter4_bestcase_ssse3: 15.1 ( 0.20x) vc1dsp.vc1_h_loop_filter4_worstcase_c: 23.6 vc1dsp.vc1_h_loop_filter4_worstcase_ssse3: 15.2 ( 1.55x) Notice that at some callsites, the partially modified buffer is immediately reloaded again*, so that both scenarios can happen. *: See the TT_4X4 and TT_4X8 cases at the end of vc1_p_h_loop_filter() or vc1_b_h_intfi_loop_filter() or the luma field blocks in vc1_p_h_intfr_loop_filter(). Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_loopfilter.asm | 58 +++++++++++++++++----------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/libavcodec/x86/vc1dsp_loopfilter.asm b/libavcodec/x86/vc1dsp_loopfilter.asm index 7f4783afa7..819693e4a3 100644 --- a/libavcodec/x86/vc1dsp_loopfilter.asm +++ b/libavcodec/x86/vc1dsp_loopfilter.asm @@ -42,11 +42,7 @@ SECTION .text pextrw %4, %5, %6+3 %else movd %6d, %5 -%if mmsize==16 psrldq %5, 4 -%else - psrlq %5, 32 -%endif mov %1, %6w shr %6, 16 mov %2, %6w @@ -71,12 +67,16 @@ SECTION .text ; in: p0 q0 a0 a1 a2 ; m0 m1 m7 m6 m5 -; %1: size +; %1: size, %2: if set, m6 contains a1, a2 ; out: m0=p0' m1=q0' -%macro VC1_FILTER 1 +%macro VC1_FILTER 2 PABSW m3, m6 movd m6, r2d +%if %2 + movhlps m2, m3 +%else PABSW m2, m5 +%endif PABSW m4, m7 PSHUFLW m6, m6, 0 pminsw m3, m2 @@ -162,7 +162,7 @@ SECTION .text mova m5, m1 VC1_LOOP_FILTER_A0 m5, m2, m3, m4 - VC1_FILTER %1 + VC1_FILTER %1, 0 mov%2 [r4+r3], m0 mov%2 [r0], m1 %endmacro @@ -171,13 +171,6 @@ SECTION .text ; NOTE: UNPACK_8TO16 this number of 8 bit numbers are in half a register ; 2nd (optional) param: temp register to use for storing words %macro VC1_H_LOOP_FILTER 1-2 -%if %1 == 4 - movq m0, [r0 -4] - movq m1, [r0+ r1-4] - movq m2, [r0+2*r1-4] - movq m3, [r0+ r3-4] - TRANSPOSE4x4B 0, 1, 2, 3, 4 -%else movq m0, [r0 -4] movq m4, [r0+ r1-4] movq m1, [r0+2*r1-4] @@ -191,11 +184,11 @@ SECTION .text punpcklbw m2, m6 punpcklbw m3, m7 TRANSPOSE4x4W 0, 1, 2, 3, 4 -%endif - pxor m5, m5 + pxor m5, m5 UNPACK_8TO16 bw, 6, 0, 5 UNPACK_8TO16 bw, 7, 1, 5 + VC1_LOOP_FILTER_A0 m6, m0, m7, m1 UNPACK_8TO16 bw, 4, 2, 5 mova m0, m1 ; m0 = p0 @@ -205,14 +198,12 @@ SECTION .text VC1_LOOP_FILTER_A0 m5, m2, m1, m3 SWAP 1, 4 ; m1 = q0 - VC1_FILTER %1 + VC1_FILTER %1, 0 punpcklbw m0, m1 %if %0 > 1 STORE_4_WORDS [r0-1], [r0+r1-1], [r0+2*r1-1], [r0+r3-1], m0, %2 -%if %1 > 4 psrldq m0, 4 STORE_4_WORDS [r4-1], [r4+r1-1], [r4+2*r1-1], [r4+r3-1], m0, %2 -%endif %else STORE_4_WORDS [r0-1], [r0+r1-1], [r0+2*r1-1], [r0+r3-1], m0, 0 STORE_4_WORDS [r4-1], [r4+r1-1], [r4+2*r1-1], [r4+r3-1], m0, 4 @@ -254,13 +245,36 @@ cglobal vc1_v_loop_filter4, 3,5,0 VC1_V_LOOP_FILTER 4, d RET +INIT_XMM ssse3 ; void ff_vc1_h_loop_filter4_ssse3(uint8_t *src, ptrdiff_t stride, int pq) -cglobal vc1_h_loop_filter4, 3,4,0 +cglobal vc1_h_loop_filter4, 3,4,8 START_H_FILTER 4 - VC1_H_LOOP_FILTER 4, r2 + movq m0, [r0 -4] + movq m1, [r0+ r1-4] + movq m2, [r0+2*r1-4] + movq m3, [r0+ r3-4] + punpcklbw m0, m1 + punpcklbw m2, m3 + SBUTTERFLY wd, 0, 2, 1 + ; m0 now contains lines -4..-1, m2 0..4 as dwords + pxor m5, m5 + SBUTTERFLY dq, 0, 2, 1 + ; m0 now contains lines -4 0 -3 1, m2 -2 2 -1 3 + UNPACK_8TO16 bw, 6, 0, 5 + UNPACK_8TO16 bw, 7, 2, 5 + ; m0, m2, m6, m7 contain two unpacked lines each, namely: + ; m6: -4, 0; m0: -3, 1; m7: -2, 2; m2: -1, 3 + movhlps m5, m0 ; 1 + movhlps m1, m6 ; 0 + VC1_LOOP_FILTER_A0 m6, m0, m7, m2 ; m6: a1, a2 + mova m0, m2 + VC1_LOOP_FILTER_A0 m7, m2, m1, m5 + + VC1_FILTER 4, 1 + punpcklbw m0, m1 + STORE_4_WORDS [r0-1], [r0+r1-1], [r0+2*r1-1], [r0+r3-1], m0, r2 RET -INIT_XMM ssse3 ; void ff_vc1_v_loop_filter8_ssse3(uint8_t *src, ptrdiff_t stride, int pq) cglobal vc1_v_loop_filter8, 3,5,8 START_V_FILTER -- 2.52.0 >From 6a13b427903f7e83da5e45d40d06acb2f9617956 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Mon, 27 Jul 2026 00:21:24 +0200 Subject: [PATCH 09/10] avcodec/x86/vc1dsp_loopfilter: Don't use MMX regs Up until now ff_vc1_v_loop_filter4_ssse3 used MMX registers despite being an SSSE3 function. Porting it to XMM registers didn't lead to any change in benchmarks here, but abides by the ABI (one function less that does not omit emms). Unfortunately the size of the function increased by 64B by this. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_loopfilter.asm | 9 ++++----- tests/checkasm/vc1dsp.c | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libavcodec/x86/vc1dsp_loopfilter.asm b/libavcodec/x86/vc1dsp_loopfilter.asm index 819693e4a3..3a6af89f9e 100644 --- a/libavcodec/x86/vc1dsp_loopfilter.asm +++ b/libavcodec/x86/vc1dsp_loopfilter.asm @@ -78,7 +78,7 @@ SECTION .text PABSW m2, m5 %endif PABSW m4, m7 - PSHUFLW m6, m6, 0 + pshuflw m6, m6, 0 pminsw m3, m2 pcmpgtw m2, m4, m3 ; if (a2 < a0 || a1 < a0) %if %1 > 4 @@ -111,7 +111,7 @@ SECTION .text pand m6, m5 ; filt3 (C return value) ; each set of 4 pixels is not filtered if the 3rd is not - PSHUFLW m5, m6, q2222 + pshuflw m5, m6, q2222 %if cpuflag(ssse3) psraw m3, 8 %else @@ -238,14 +238,13 @@ cglobal vc1_h_loop_filter8, 3,5,8 VC1_H_LOOP_FILTER 8, r2 RET -INIT_MMX ssse3 +INIT_XMM ssse3 ; void ff_vc1_v_loop_filter4_ssse3(uint8_t *src, ptrdiff_t stride, int pq) -cglobal vc1_v_loop_filter4, 3,5,0 +cglobal vc1_v_loop_filter4, 3,5,8 START_V_FILTER VC1_V_LOOP_FILTER 4, d RET -INIT_XMM ssse3 ; void ff_vc1_h_loop_filter4_ssse3(uint8_t *src, ptrdiff_t stride, int pq) cglobal vc1_h_loop_filter4, 3,4,8 START_H_FILTER 4 diff --git a/tests/checkasm/vc1dsp.c b/tests/checkasm/vc1dsp.c index d4acf38e46..c8e8699e9f 100644 --- a/tests/checkasm/vc1dsp.c +++ b/tests/checkasm/vc1dsp.c @@ -354,7 +354,7 @@ static void check_loop_filter(void) for (size_t k = 0; k < FF_ARRAY_ELEMS(tests); ++k) { void (*func)(uint8_t *, ptrdiff_t, int) = *(void **)((intptr_t) &h + tests[k].offset); - declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, ptrdiff_t, int); + declare_func(void, uint8_t *, ptrdiff_t, int); if (check_func(func, "vc1dsp.%s", tests[k].name)) { for (int count = 1000; count > 0; --count) { int pq = rnd() % 31 + 1; -- 2.52.0 >From 100a540eced6c6acb926fea8bc6cbd5e4770ee88 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Wed, 29 Jul 2026 16:40:40 +0200 Subject: [PATCH 10/10] avcodec/x86/vc1dsp_inv_trans: Port to SSE2 No change in performance here. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vc1dsp_init.c | 27 +++++++++---------- libavcodec/x86/vc1dsp_inv_trans.asm | 41 +++++++++++++++-------------- tests/checkasm/vc1dsp.c | 2 +- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/libavcodec/x86/vc1dsp_init.c b/libavcodec/x86/vc1dsp_init.c index e5a177cb76..6c86b646f9 100644 --- a/libavcodec/x86/vc1dsp_init.c +++ b/libavcodec/x86/vc1dsp_init.c @@ -66,14 +66,14 @@ void ff_put_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h, int x, int y); void ff_avg_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h, int x, int y); -void ff_vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, - int16_t *block); -void ff_vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, - int16_t *block); -void ff_vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, - int16_t *block); -void ff_vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, - int16_t *block); +void ff_vc1_inv_trans_4x4_dc_sse2(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_4x8_dc_sse2(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_8x4_dc_sse2(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_8x8_dc_sse2(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); #define MSPEL_FUNC(OP, X, Y, SIZE, XMM) \ void ff_vc1_ ## OP ## _mspel_mc ## X ## Y ## _ ## SIZE ##_ ## XMM \ @@ -110,13 +110,12 @@ av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp) dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_ ## EXT; \ dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_ ## EXT - if (EXTERNAL_MMXEXT(cpu_flags)) { - dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_mmxext; - dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_mmxext; - dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_mmxext; - dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_mmxext; - } if (EXTERNAL_SSE2(cpu_flags)) { + dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_sse2; + dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_sse2; + dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_sse2; + dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_sse2; + ASSIGN_LF816(sse2); MSPEL_FUNCS(0, 0, sse2); diff --git a/libavcodec/x86/vc1dsp_inv_trans.asm b/libavcodec/x86/vc1dsp_inv_trans.asm index e1b74de6c4..788ffa24a8 100644 --- a/libavcodec/x86/vc1dsp_inv_trans.asm +++ b/libavcodec/x86/vc1dsp_inv_trans.asm @@ -23,9 +23,13 @@ SECTION .text -%macro INV_TRANS_INIT 0 +%macro INV_TRANS_INIT 1 ; width movd m0, blockd +%if %1 == 4 + pshuflw m0, m0, 0 +%else SPLATW m0, m0 +%endif pxor m1, m1 psubw m1, m0 packuswb m0, m0 @@ -54,9 +58,9 @@ SECTION .text mov%1 [linesize3q +destq], m5 %endmacro -; ff_vc1_inv_trans_?x?_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, int16_t *block) -INIT_MMX mmxext -cglobal vc1_inv_trans_4x4_dc, 3,4,0, dest, linesize, block +INIT_XMM sse2 +; ff_vc1_inv_trans_?x?_dc_sse2(uint8_t *dest, ptrdiff_t linesize, int16_t *block) +cglobal vc1_inv_trans_4x4_dc, 3,4,6, dest, linesize, block movsx r3d, WORD [blockq] mov blockd, r3d ; dc shl blockd, 4 ; 16 * dc @@ -67,13 +71,12 @@ cglobal vc1_inv_trans_4x4_dc, 3,4,0, dest, linesize, block lea blockd, [blockq+r3+64] ; 17 * dc + 64 sar blockd, 7 ; >> 7 - INV_TRANS_INIT + INV_TRANS_INIT 4 - INV_TRANS_PROCESS h + INV_TRANS_PROCESS d RET -INIT_MMX mmxext -cglobal vc1_inv_trans_4x8_dc, 3,4,0, dest, linesize, block +cglobal vc1_inv_trans_4x8_dc, 3,4,6, dest, linesize, block movsx r3d, WORD [blockq] mov blockd, r3d ; dc shl blockd, 4 ; 16 * dc @@ -83,15 +86,14 @@ cglobal vc1_inv_trans_4x8_dc, 3,4,0, dest, linesize, block lea blockd, [blockq*3+64] ; 12 * dc + 64 sar blockd, 7 ; >> 7 - INV_TRANS_INIT + INV_TRANS_INIT 4 - INV_TRANS_PROCESS h + INV_TRANS_PROCESS d lea destq, [destq+linesizeq*4] - INV_TRANS_PROCESS h + INV_TRANS_PROCESS d RET -INIT_MMX mmxext -cglobal vc1_inv_trans_8x4_dc, 3,4,0, dest, linesize, block +cglobal vc1_inv_trans_8x4_dc, 3,4,6, dest, linesize, block movsx blockd, WORD [blockq] ; dc lea blockd, [blockq*3+1] ; 3 * dc + 1 sar blockd, 1 ; >> 1 @@ -100,22 +102,21 @@ cglobal vc1_inv_trans_8x4_dc, 3,4,0, dest, linesize, block lea blockd, [blockq+r3+64] ; 17 * dc + 64 sar blockd, 7 ; >> 7 - INV_TRANS_INIT + INV_TRANS_INIT 8 - INV_TRANS_PROCESS a + INV_TRANS_PROCESS q RET -INIT_MMX mmxext -cglobal vc1_inv_trans_8x8_dc, 3,3,0, dest, linesize, block +cglobal vc1_inv_trans_8x8_dc, 3,3,6, dest, linesize, block movsx blockd, WORD [blockq] ; dc lea blockd, [blockq*3+1] ; 3 * dc + 1 sar blockd, 1 ; >> 1 lea blockd, [blockq*3+16] ; 3 * dc + 16 sar blockd, 5 ; >> 5 - INV_TRANS_INIT + INV_TRANS_INIT 8 - INV_TRANS_PROCESS a + INV_TRANS_PROCESS q lea destq, [destq+linesizeq*4] - INV_TRANS_PROCESS a + INV_TRANS_PROCESS q RET diff --git a/tests/checkasm/vc1dsp.c b/tests/checkasm/vc1dsp.c index c8e8699e9f..52049a4aa3 100644 --- a/tests/checkasm/vc1dsp.c +++ b/tests/checkasm/vc1dsp.c @@ -310,7 +310,7 @@ static void check_inv_trans_adding(void) void (*func)(uint8_t *, ptrdiff_t, int16_t *) = *(void **)((intptr_t) &h + tests[k].offset); if (check_func(func, "vc1dsp.%s", tests[k].name)) { matrix *coeffs; - declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, ptrdiff_t, int16_t *); + declare_func(void, uint8_t *, ptrdiff_t, int16_t *); RANDOMIZE_BUFFER16(inv_trans_in, 8 * 8); RANDOMIZE_BUFFER8(inv_trans_out, 10 * 24); coeffs = generate_inverse_quantized_transform_coefficients(tests[k].width, tests[k].height); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]