PR #24346 opened by zuxy URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24346 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24346.patch
Deprecate use of MMX registers in h264's weight/bi-weight prediction >From 995aa0dedf238d7ec10abbca8f2be992a5fabbb4 Mon Sep 17 00:00:00 2001 From: Zuxy Meng <[email protected]> Date: Fri, 21 Aug 2026 22:04:57 -0700 Subject: [PATCH 1/2] avcodec/x86/h264_weight: Remove MMX SSE2/SSSE3 impl. of MMX weight/bi-weight functions. Identical or slightly better performance: biweight_4x16_8_mmxext: 26.3 ( 2.37x) biweight_4x16_8_sse2: 24.4 ( 2.54x) biweight_4x16_8_ssse3: 19.7 ( 3.13x) weight_4x16_8_mmxext: 20.0 ( 2.34x) weight_4x16_8_sse2: 19.5 ( 2.33x) Signed-off-by: Zuxy Meng <[email protected]> --- libavcodec/x86/h264_weight.asm | 79 ++++++++++++++++++++-------------- libavcodec/x86/h264dsp_init.c | 13 ++---- tests/checkasm/h264dsp.c | 9 ++-- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index 5524f3e28c..acd6cfbfdd 100644 --- a/libavcodec/x86/h264_weight.asm +++ b/libavcodec/x86/h264_weight.asm @@ -44,21 +44,21 @@ SECTION .text movd m6, r3d pslld m5, m6 psrld m5, 1 -%if mmsize == 16 pshuflw m3, m3, 0 pshuflw m5, m5, 0 punpcklqdq m3, m3 punpcklqdq m5, m5 -%else - pshufw m3, m3, 0 - pshufw m5, m5, 0 -%endif pxor m7, m7 %endmacro -%macro WEIGHT_OP 2 +%macro WEIGHT_OP 3 +%if %3 == 4 + movd m0, [r0+%1] + movd m1, [r0+%2] +%else movh m0, [r0+%1] movh m1, [r0+%2] +%endif punpcklbw m0, m7 punpcklbw m1, m7 pmullw m0, m3 @@ -70,11 +70,11 @@ SECTION .text packuswb m0, m1 %endmacro -%macro WEIGHT_FUNC_MM 2 -cglobal h264_weight_%1, 6, 6, %2 +%macro WEIGHT_FUNC_MM 1 +cglobal h264_weight_%1, 6, 6, 8 WEIGHT_SETUP .nextrow: - WEIGHT_OP 0, mmsize/2 + WEIGHT_OP 0, mmsize/2, %1 mova [r0], m0 add r0, r1 dec r2d @@ -83,21 +83,22 @@ cglobal h264_weight_%1, 6, 6, %2 %endmacro INIT_XMM sse2 -WEIGHT_FUNC_MM 16, 8 +WEIGHT_FUNC_MM 16 -%macro WEIGHT_FUNC_HALF_MM 2 -cglobal h264_weight_%1, 6, 6, %2 +%macro WEIGHT_FUNC_HALF_MM 1 +cglobal h264_weight_%1, 6, 6, 8 WEIGHT_SETUP sar r2d, 1 lea r3, [r1*2] .nextrow: - WEIGHT_OP 0, r1 + WEIGHT_OP 0, r1, %1 +%if %1 > 4 movh [r0], m0 -%if mmsize == 16 movhps [r0+r1], m0 %else - psrlq m0, 32 - movh [r0+r1], m0 + movd [r0], m0 + psrldq m0, 8 + movd [r0+r1], m0 %endif add r0, r3 dec r2d @@ -105,10 +106,10 @@ cglobal h264_weight_%1, 6, 6, %2 RET %endmacro -INIT_MMX mmxext -WEIGHT_FUNC_HALF_MM 4, 0 INIT_XMM sse2 -WEIGHT_FUNC_HALF_MM 8, 8 +WEIGHT_FUNC_HALF_MM 4 +INIT_XMM sse2 +WEIGHT_FUNC_HALF_MM 8 %macro BIWEIGHT_SETUP 0 %if ARCH_X86_64 @@ -149,18 +150,12 @@ WEIGHT_FUNC_HALF_MM 8, 8 punpcklqdq m5, m5 %else -%if mmsize == 16 pshuflw m3, m3, 0 pshuflw m4, m4, 0 pshuflw m5, m5, 0 punpcklqdq m3, m3 punpcklqdq m4, m4 punpcklqdq m5, m5 -%else - pshufw m3, m3, 0 - pshufw m4, m4, 0 - pshufw m5, m5, 0 -%endif pxor m7, m7 %endif %endmacro @@ -206,6 +201,28 @@ BIWEIGHT_FUNC_MM 16, 8 cglobal h264_biweight_%1, 7, 8, %2 BIWEIGHT_SETUP movifnidn r3d, r3m +%if %1 == 4 + ; for 4 with sse2, process 1 row at a time +.nextrow: + movd m0, [r0] + movd m1, [r1] +%if cpuflag(ssse3) + punpcklbw m0, m1 + pmaddubsw m0, m4 +%else + punpcklbw m0, m7 + punpcklbw m1, m7 + pmullw m0, m3 + pmullw m1, m4 + paddsw m0, m1 +%endif + paddsw m0, m5 + psraw m0, m6 + packuswb m0, m0 + movd [r0], m0 + add r0, r2 + add r1, r2 +%else sar r3d, 1 lea r4, [r2*2] .nextrow: @@ -213,21 +230,19 @@ cglobal h264_biweight_%1, 7, 8, %2 BIWEIGHT_STEPA 1, 2, r2 BIWEIGHT_STEPB movh [r0], m0 -%if mmsize == 16 movhps [r0+r2], m0 -%else - psrlq m0, 32 - movh [r0+r2], m0 -%endif add r0, r4 add r1, r4 +%endif dec r3d jnz .nextrow RET %endmacro -INIT_MMX mmxext -BIWEIGHT_FUNC_HALF_MM 4, 0 +INIT_XMM sse2 +BIWEIGHT_FUNC_HALF_MM 4, 8 +INIT_XMM ssse3 +BIWEIGHT_FUNC_HALF_MM 4, 7 INIT_XMM sse2 BIWEIGHT_FUNC_HALF_MM 8, 8 diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c index d853219fb1..654316c2af 100644 --- a/libavcodec/x86/h264dsp_init.c +++ b/libavcodec/x86/h264dsp_init.c @@ -140,10 +140,6 @@ void ff_h264_biweight_ ## W ## _ ## OPT(uint8_t *dst, uint8_t *src, \ int log2_denom, int weightd, \ int weights, int offset); -#define H264_BIWEIGHT_MMX(W) \ - H264_WEIGHT(W, mmxext) \ - H264_BIWEIGHT(W, mmxext) - #define H264_BIWEIGHT_SSE(W) \ H264_WEIGHT(W, sse2) \ H264_BIWEIGHT(W, sse2) \ @@ -151,7 +147,7 @@ void ff_h264_biweight_ ## W ## _ ## OPT(uint8_t *dst, uint8_t *src, \ H264_BIWEIGHT_SSE(16) H264_BIWEIGHT_SSE(8) -H264_BIWEIGHT_MMX(4) +H264_BIWEIGHT_SSE(4) #define H264_WEIGHT_10(W, DEPTH, OPT) \ void ff_h264_weight_ ## W ## _ ## DEPTH ## _ ## OPT(uint8_t *dst, \ @@ -198,10 +194,6 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, } if (EXTERNAL_MMXEXT(cpu_flags)) { c->idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext; - - c->weight_pixels_tab[2] = ff_h264_weight_4_mmxext; - - c->biweight_pixels_tab[2] = ff_h264_biweight_4_mmxext; } if (EXTERNAL_SSE2(cpu_flags)) { c->idct8_add = ff_h264_idct8_add_8_sse2; @@ -215,9 +207,11 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, c->weight_pixels_tab[0] = ff_h264_weight_16_sse2; c->weight_pixels_tab[1] = ff_h264_weight_8_sse2; + c->weight_pixels_tab[2] = ff_h264_weight_4_sse2; c->biweight_pixels_tab[0] = ff_h264_biweight_16_sse2; c->biweight_pixels_tab[1] = ff_h264_biweight_8_sse2; + c->biweight_pixels_tab[2] = ff_h264_biweight_4_sse2; c->v_loop_filter_luma = ff_deblock_v_luma_8_sse2; c->h_loop_filter_luma = ff_deblock_h_luma_8_sse2; @@ -244,6 +238,7 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, if (EXTERNAL_SSSE3(cpu_flags)) { c->biweight_pixels_tab[0] = ff_h264_biweight_16_ssse3; c->biweight_pixels_tab[1] = ff_h264_biweight_8_ssse3; + c->biweight_pixels_tab[2] = ff_h264_biweight_4_ssse3; } if (EXTERNAL_AVX(cpu_flags)) { c->v_loop_filter_luma = ff_deblock_v_luma_8_avx; diff --git a/tests/checkasm/h264dsp.c b/tests/checkasm/h264dsp.c index cc2d7524da..30478f2956 100644 --- a/tests/checkasm/h264dsp.c +++ b/tests/checkasm/h264dsp.c @@ -510,8 +510,8 @@ static void check_weight(void) LOCAL_ALIGNED_16(uint8_t, dst0, [32 * 32 * 2]); LOCAL_ALIGNED_16(uint8_t, dst1, [32 * 32 * 2]); H264DSPContext h; - declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, ptrdiff_t stride, - int height, int log2_denom, int weight, int offset); + declare_func(void, uint8_t *dst, ptrdiff_t stride, int height, + int log2_denom, int weight, int offset); for (int bit_depth = 8; bit_depth <= 10; bit_depth += 2) { ff_h264dsp_init(&h, bit_depth, 1); @@ -562,9 +562,8 @@ static void check_biweight(void) LOCAL_ALIGNED_16(uint8_t, src0, [32 * 32 * 2]); LOCAL_ALIGNED_16(uint8_t, src1, [32 * 32 * 2]); H264DSPContext h; - declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, - ptrdiff_t stride, int height, int log2_denom, - int weightd, int weights, int offset); + declare_func(void, uint8_t *dst, uint8_t *src, ptrdiff_t stride, int height, + int log2_denom, int weightd, int weights, int offset); for (int bit_depth = 8; bit_depth <= 10; bit_depth += 2) { uint32_t mask = pixel_mask[bit_depth - 8]; -- 2.52.0 >From 03c738adaa5d86560e548b292bfdafd4c2aab987 Mon Sep 17 00:00:00 2001 From: Zuxy Meng <[email protected]> Date: Sat, 22 Aug 2026 17:58:36 -0700 Subject: [PATCH 2/2] avcodec/x86/h264_weight: less callee saved XMM registers in Windows Tweak usage of XMM regisers so that Windows can save less upon function entry. Signed-off-by: Zuxy Meng <[email protected]> --- libavcodec/x86/h264_weight.asm | 80 ++++++++++++++-------------- libavcodec/x86/h264_weight_10bit.asm | 28 ++++++---- 2 files changed, 58 insertions(+), 50 deletions(-) diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index acd6cfbfdd..751c910b71 100644 --- a/libavcodec/x86/h264_weight.asm +++ b/libavcodec/x86/h264_weight.asm @@ -41,14 +41,14 @@ SECTION .text inc r5 movd m3, r4d movd m5, r5d - movd m6, r3d - pslld m5, m6 + movd m2, r3d + pslld m5, m2 psrld m5, 1 pshuflw m3, m3, 0 pshuflw m5, m5, 0 punpcklqdq m3, m3 punpcklqdq m5, m5 - pxor m7, m7 + pxor m4, m4 %endmacro %macro WEIGHT_OP 3 @@ -59,19 +59,19 @@ SECTION .text movh m0, [r0+%1] movh m1, [r0+%2] %endif - punpcklbw m0, m7 - punpcklbw m1, m7 + punpcklbw m0, m4 + punpcklbw m1, m4 pmullw m0, m3 pmullw m1, m3 paddsw m0, m5 paddsw m1, m5 - psraw m0, m6 - psraw m1, m6 + psraw m0, m2 + psraw m1, m2 packuswb m0, m1 %endmacro %macro WEIGHT_FUNC_MM 1 -cglobal h264_weight_%1, 6, 6, 8 +cglobal h264_weight_%1, 6, 6, 6 WEIGHT_SETUP .nextrow: WEIGHT_OP 0, mmsize/2, %1 @@ -86,7 +86,7 @@ INIT_XMM sse2 WEIGHT_FUNC_MM 16 %macro WEIGHT_FUNC_HALF_MM 1 -cglobal h264_weight_%1, 6, 6, 8 +cglobal h264_weight_%1, 6, 6, 6 WEIGHT_SETUP sar r2d, 1 lea r3, [r1*2] @@ -135,12 +135,12 @@ WEIGHT_FUNC_HALF_MM 8 movd m4, r5d movd m0, r6d %else - movd m3, r5d + movd m6, r5d movd m4, r6d %endif movd m5, off_regd - movd m6, r4d - pslld m5, m6 + movd m3, r4d + pslld m5, m3 psrld m5, 1 %if cpuflag(ssse3) punpcklbw m4, m0 @@ -150,22 +150,22 @@ WEIGHT_FUNC_HALF_MM 8 punpcklqdq m5, m5 %else - pshuflw m3, m3, 0 + pshuflw m6, m6, 0 pshuflw m4, m4, 0 pshuflw m5, m5, 0 - punpcklqdq m3, m3 + punpcklqdq m6, m6 punpcklqdq m4, m4 punpcklqdq m5, m5 - pxor m7, m7 + pxor m2, m2 %endif %endmacro %macro BIWEIGHT_STEPA 3 movh m%1, [r0+%3] movh m%2, [r1+%3] - punpcklbw m%1, m7 - punpcklbw m%2, m7 - pmullw m%1, m3 + punpcklbw m%1, m2 + punpcklbw m%2, m2 + pmullw m%1, m6 pmullw m%2, m4 paddsw m%1, m%2 %endmacro @@ -173,18 +173,18 @@ WEIGHT_FUNC_HALF_MM 8 %macro BIWEIGHT_STEPB 0 paddsw m0, m5 paddsw m1, m5 - psraw m0, m6 - psraw m1, m6 + psraw m0, m3 + psraw m1, m3 packuswb m0, m1 %endmacro -%macro BIWEIGHT_FUNC_MM 2 -cglobal h264_biweight_%1, 7, 8, %2 +%macro BIWEIGHT_FUNC_MM 1 +cglobal h264_biweight_%1, 7, 8, 8 BIWEIGHT_SETUP movifnidn r3d, r3m .nextrow: BIWEIGHT_STEPA 0, 1, 0 - BIWEIGHT_STEPA 1, 2, mmsize/2 + BIWEIGHT_STEPA 1, 7, mmsize/2 BIWEIGHT_STEPB mova [r0], m0 add r0, r2 @@ -195,7 +195,7 @@ cglobal h264_biweight_%1, 7, 8, %2 %endmacro INIT_XMM sse2 -BIWEIGHT_FUNC_MM 16, 8 +BIWEIGHT_FUNC_MM 16 %macro BIWEIGHT_FUNC_HALF_MM 2 cglobal h264_biweight_%1, 7, 8, %2 @@ -210,14 +210,14 @@ cglobal h264_biweight_%1, 7, 8, %2 punpcklbw m0, m1 pmaddubsw m0, m4 %else - punpcklbw m0, m7 - punpcklbw m1, m7 - pmullw m0, m3 + punpcklbw m0, m2 + punpcklbw m1, m2 + pmullw m0, m6 pmullw m1, m4 paddsw m0, m1 %endif paddsw m0, m5 - psraw m0, m6 + psraw m0, m3 packuswb m0, m0 movd [r0], m0 add r0, r2 @@ -227,7 +227,7 @@ cglobal h264_biweight_%1, 7, 8, %2 lea r4, [r2*2] .nextrow: BIWEIGHT_STEPA 0, 1, 0 - BIWEIGHT_STEPA 1, 2, r2 + BIWEIGHT_STEPA 1, 7, r2 BIWEIGHT_STEPB movh [r0], m0 movhps [r0+r2], m0 @@ -240,9 +240,9 @@ cglobal h264_biweight_%1, 7, 8, %2 %endmacro INIT_XMM sse2 -BIWEIGHT_FUNC_HALF_MM 4, 8 -INIT_XMM ssse3 BIWEIGHT_FUNC_HALF_MM 4, 7 +INIT_XMM ssse3 +BIWEIGHT_FUNC_HALF_MM 4, 6 INIT_XMM sse2 BIWEIGHT_FUNC_HALF_MM 8, 8 @@ -251,22 +251,22 @@ BIWEIGHT_FUNC_HALF_MM 8, 8 pmaddubsw m2, m4 paddsw m0, m5 paddsw m2, m5 - psraw m0, m6 - psraw m2, m6 + psraw m0, m3 + psraw m2, m3 packuswb m0, m2 %endmacro INIT_XMM ssse3 -cglobal h264_biweight_16, 7, 8, 8 +cglobal h264_biweight_16, 7, 8, 6 BIWEIGHT_SETUP movifnidn r3d, r3m .nextrow: movh m0, [r0] movh m2, [r0+8] - movh m3, [r1+8] + movh m1, [r1+8] punpcklbw m0, [r1] - punpcklbw m2, m3 + punpcklbw m2, m1 BIWEIGHT_SSSE3_OP mova [r0], m0 add r0, r2 @@ -276,7 +276,7 @@ cglobal h264_biweight_16, 7, 8, 8 RET INIT_XMM ssse3 -cglobal h264_biweight_8, 7, 8, 8 +cglobal h264_biweight_8, 7, 8, 6 BIWEIGHT_SETUP movifnidn r3d, r3m sar r3d, 1 @@ -285,10 +285,10 @@ cglobal h264_biweight_8, 7, 8, 8 .nextrow: movh m0, [r0] movh m1, [r1] - movh m2, [r0+r2] - movh m3, [r1+r2] punpcklbw m0, m1 - punpcklbw m2, m3 + movh m2, [r0+r2] + movh m1, [r1+r2] + punpcklbw m2, m1 BIWEIGHT_SSSE3_OP movh [r0], m0 movhps [r0+r2], m0 diff --git a/libavcodec/x86/h264_weight_10bit.asm b/libavcodec/x86/h264_weight_10bit.asm index 7b7e367c9d..2044da7489 100644 --- a/libavcodec/x86/h264_weight_10bit.asm +++ b/libavcodec/x86/h264_weight_10bit.asm @@ -41,7 +41,11 @@ SECTION .text ;----------------------------------------------------------------------------- %macro WEIGHT_PROLOGUE 0 .prologue: - PROLOGUE 0,6,8 +%if cpuflag(sse4) + PROLOGUE 0,6,6 +%else + PROLOGUE 0,6,7 +%endif movifnidn r0, r0mp movifnidn r1d, r1m movifnidn r2d, r2m @@ -63,31 +67,31 @@ SECTION .text mova m4, [pw_pixel_max] paddw m2, [sq_1] ; log2_denom+1 %if notcpuflag(sse4) - pxor m7, m7 + pxor m6, m6 %endif %endmacro %macro WEIGHT_OP 1-2 %if %0==1 mova m5, [r0+%1] - punpckhwd m6, m5, m0 + punpckhwd m1, m5, m0 punpcklwd m5, m0 %else movq m5, [r0+%1] - movq m6, [r0+%2] + movq m1, [r0+%2] punpcklwd m5, m0 - punpcklwd m6, m0 + punpcklwd m1, m0 %endif pmaddwd m5, m3 - pmaddwd m6, m3 + pmaddwd m1, m3 psrad m5, m2 - psrad m6, m2 + psrad m1, m2 %if cpuflag(sse4) - packusdw m5, m6 + packusdw m5, m1 pminuw m5, m4 %else - packssdw m5, m6 - CLIPW m5, m7, m4 + packssdw m5, m1 + CLIPW m5, m6, m4 %endif %endmacro @@ -166,7 +170,11 @@ DECLARE_REG_TMP 7 %macro BIWEIGHT_PROLOGUE 0 .prologue: +%if cpuflag(sse4) + PROLOGUE 0,8,7 +%else PROLOGUE 0,8,8 +%endif movifnidn r0, r0mp movifnidn r1, r1mp movifnidn r2d, r2m -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
