PR #22774 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22774 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22774.patch
>From 5a07d0f08d38df9049eae3783836ecd6b801030a Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 10 Apr 2026 01:37:32 +0200 Subject: [PATCH 1/4] swscale/x86/scale: Remove always-false mmsize checks Forgotten in a05f22eaf393177b94432431c145cbc5ba10390a. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libswscale/x86/scale.asm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/libswscale/x86/scale.asm b/libswscale/x86/scale.asm index 85a96dc57e..5d4553cf49 100644 --- a/libswscale/x86/scale.asm +++ b/libswscale/x86/scale.asm @@ -103,9 +103,6 @@ cglobal hscale%1to%2_%4, %5, 10, %6, pos0, dst, w, srcmem, filter, fltpos, fltsi mov32 pos0q, dword [fltposq+wq*4+ 0] ; filterPos[0] mov32 pos1q, dword [fltposq+wq*4+ 4] ; filterPos[1] movlh m0, [srcq+pos0q*srcmul] ; src[filterPos[0] + {0,1,2,3}] -%if mmsize == 8 - movlh m1, [srcq+pos1q*srcmul] ; src[filterPos[1] + {0,1,2,3}] -%else ; mmsize == 16 %if %1 > 8 movhps m0, [srcq+pos1q*srcmul] ; src[filterPos[1] + {0,1,2,3}] %else ; %1 == 8 @@ -121,7 +118,6 @@ cglobal hscale%1to%2_%4, %5, 10, %6, pos0, dst, w, srcmem, filter, fltpos, fltsi punpckldq m0, m4 punpckldq m1, m5 %endif ; %1 == 8 -%endif ; mmsize == 8/16 %if %1 == 8 punpcklbw m0, m3 ; byte -> word punpcklbw m1, m3 ; byte -> word @@ -153,17 +149,11 @@ cglobal hscale%1to%2_%4, %5, 10, %6, pos0, dst, w, srcmem, filter, fltpos, fltsi mov32 pos0q, dword [fltposq+wq*2+0] ; filterPos[0] mov32 pos1q, dword [fltposq+wq*2+4] ; filterPos[1] movbh m0, [srcq+ pos0q *srcmul] ; src[filterPos[0] + {0,1,2,3,4,5,6,7}] -%if mmsize == 8 - movbh m1, [srcq+(pos0q+4)*srcmul] ; src[filterPos[0] + {4,5,6,7}] - movbh m4, [srcq+ pos1q *srcmul] ; src[filterPos[1] + {0,1,2,3}] - movbh m5, [srcq+(pos1q+4)*srcmul] ; src[filterPos[1] + {4,5,6,7}] -%else ; mmsize == 16 movbh m1, [srcq+ pos1q *srcmul] ; src[filterPos[1] + {0,1,2,3,4,5,6,7}] mov32 pos0q, dword [fltposq+wq*2+8] ; filterPos[2] mov32 pos1q, dword [fltposq+wq*2+12] ; filterPos[3] movbh m4, [srcq+ pos0q *srcmul] ; src[filterPos[2] + {0,1,2,3,4,5,6,7}] movbh m5, [srcq+ pos1q *srcmul] ; src[filterPos[3] + {0,1,2,3,4,5,6,7}] -%endif ; mmsize == 8/16 %if %1 == 8 punpcklbw m0, m3 ; byte -> word punpcklbw m1, m3 ; byte -> word -- 2.52.0 >From e72688d5717b59c0b0223e24a31bcd811c38a541 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 10 Apr 2026 02:15:51 +0200 Subject: [PATCH 2/4] swscale/x86/output: Simplify creating dither register Only the lower quadword needs to be rotated, because the register is zero-extended immediately afterwards anyway. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libswscale/x86/output.asm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm index f2e884780a..7d87dd919c 100644 --- a/libswscale/x86/output.asm +++ b/libswscale/x86/output.asm @@ -253,8 +253,10 @@ cglobal yuv2planeX_%1, %3, 8, %2, filter, fltsize, src, dst, w, dither, offset jz .no_rot %if mmsize == 16 punpcklqdq m_dith, m_dith -%endif ; mmsize == 16 + psrldq m_dith, 3 +%else PALIGNR m_dith, m_dith, 3, m0 +%endif ; mmsize == 16 .no_rot: %if mmsize == 16 punpcklbw m_dith, m6 -- 2.52.0 >From 35ae0a9622350235740f15eac0bdc75bdd3d20c6 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 10 Apr 2026 03:07:13 +0200 Subject: [PATCH 3/4] swscale/x86/output: Make xmm functions usable even without aligned stack x86-32 lacks one GPR, so it needs to be read from the stack. If the stack needs to be realigned, we can no longer access the original location of one argument, so just request a bit more stack size and copy said argument at a fixed offset from the new stack. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libswscale/x86/output.asm | 31 +++++++++++++++++++------------ libswscale/x86/swscale.c | 13 +++++-------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm index 7d87dd919c..bbe15510f8 100644 --- a/libswscale/x86/output.asm +++ b/libswscale/x86/output.asm @@ -137,7 +137,11 @@ SECTION .text mova m1, [yuv2yuvX_%1_start] mova m2, m1 %endif ; %1 == 8/9/10/16 +%if ARCH_X86_32 && !HAVE_ALIGNED_STACK && (%1 == 8) + mov cntr_reg, [rsp+32] +%else movsx cntr_reg, fltsizem +%endif .filterloop_%2_ %+ %%i: ; input pixels mov r6, [srcq+gprsize*cntr_reg-2*gprsize] @@ -233,15 +237,27 @@ SECTION .text %define movsx movsxd %endif -cglobal yuv2planeX_%1, %3, 8, %2, filter, fltsize, src, dst, w, dither, offset +%if %1 == 8 +%assign STACK_SIZE ARCH_X86_32*(32+mmsize*!HAVE_ALIGNED_STACK) +%else +%assign STACK_SIZE 0 +%endif + +cglobal yuv2planeX_%1, %3, 8, %2, -STACK_SIZE, filter, fltsize, src, dst, w, dither, offset %if %1 == 8 || %1 == 9 || %1 == 10 pxor m6, m6 %endif ; %1 == 8/9/10 %if %1 == 8 %if ARCH_X86_32 -%assign pad 0x2c - (stack_offset & 15) - SUB rsp, pad +%if !HAVE_ALIGNED_STACK + ; For 8-bit content on x86-32 we need the stack for both vector and GP regs. + ; If the stack is not suitably aligned, then x86inc aligns it for us, but + ; we can then no longer access the original location of fltsize, so copy + ; it here at a known offset of rsp. + mov [rsp+32], fltsized +%endif + %define m_dith m7 %else ; x86-64 %define m_dith m9 @@ -304,16 +320,7 @@ cglobal yuv2planeX_%1, %3, 8, %2, filter, fltsize, src, dst, w, dither, offset yuv2planeX_mainloop %1, u %endif ; mmsize == 8/16 -%if %1 == 8 -%if ARCH_X86_32 - ADD rsp, pad RET -%else ; x86-64 - RET -%endif ; x86-32/64 -%else ; %1 == 9/10/16 - RET -%endif ; %1 == 8/9/10/16 %endmacro %if ARCH_X86_32 && HAVE_ALIGNED_STACK == 0 diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index 85faf92c56..f3aaa704f6 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -540,12 +540,12 @@ av_cold void ff_sws_init_swscale_x86(SwsInternal *c) ff_hscale16to19_ ## filtersize ## _ ## opt1; \ } \ } while (0) -#define ASSIGN_VSCALEX_FUNC(vscalefn, opt, do_16_case, condition_8bit) \ +#define ASSIGN_VSCALEX_FUNC(vscalefn, opt, do_16_case) \ switch(c->dstBpc){ \ case 16: do_16_case; break; \ case 10: if (!isBE(c->opts.dst_format) && !isSemiPlanarYUV(c->opts.dst_format) && !isDataInHighBits(c->opts.dst_format)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \ case 9: if (!isBE(c->opts.dst_format)) vscalefn = ff_yuv2planeX_9_ ## opt; break; \ - case 8: if ((condition_8bit) && !c->use_mmx_vfilter) vscalefn = ff_yuv2planeX_8_ ## opt; break; \ + case 8: if (!c->use_mmx_vfilter) vscalefn = ff_yuv2planeX_8_ ## opt; break; \ } #define ASSIGN_VSCALE_FUNC(vscalefn, opt) \ switch(c->dstBpc){ \ @@ -572,8 +572,7 @@ switch(c->dstBpc){ \ if (EXTERNAL_SSE2(cpu_flags)) { ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse2, sse2); ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse2, sse2); - ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse2, , - HAVE_ALIGNED_STACK || ARCH_X86_64); + ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse2, ); if (!(c->opts.flags & SWS_ACCURATE_RND)) ASSIGN_VSCALE_FUNC(c->yuv2plane1, sse2); @@ -622,15 +621,13 @@ switch(c->dstBpc){ \ ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse4, ssse3); ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse4, ssse3); ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse4, - if (!isBE(c->opts.dst_format)) c->yuv2planeX = ff_yuv2planeX_16_sse4, - HAVE_ALIGNED_STACK || ARCH_X86_64); + if (!isBE(c->opts.dst_format)) c->yuv2planeX = ff_yuv2planeX_16_sse4); if (c->dstBpc == 16 && !isBE(c->opts.dst_format) && !(c->opts.flags & SWS_ACCURATE_RND)) c->yuv2plane1 = ff_yuv2plane1_16_sse4; } if (EXTERNAL_AVX(cpu_flags)) { - ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx, , - HAVE_ALIGNED_STACK || ARCH_X86_64); + ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx, ); if (!(c->opts.flags & SWS_ACCURATE_RND)) ASSIGN_VSCALE_FUNC(c->yuv2plane1, avx); -- 2.52.0 >From 96d4a7c8a0adef8fb75a2b4b840f4ebec9c0a9f0 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 10 Apr 2026 04:23:23 +0200 Subject: [PATCH 4/4] swscale/x86/output: Remove obsolete MMXEXT function Possible now that the SSE2 function is available even when the stack is not aligned. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libswscale/x86/output.asm | 63 +++++++-------------------------------- libswscale/x86/swscale.c | 9 ------ 2 files changed, 11 insertions(+), 61 deletions(-) diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm index bbe15510f8..e1b369c551 100644 --- a/libswscale/x86/output.asm +++ b/libswscale/x86/output.asm @@ -112,23 +112,10 @@ SECTION .text ;----------------------------------------------------------------------------- %macro yuv2planeX_mainloop 2 .pixelloop_%2: -%assign %%i 0 - ; the rep here is for the 8-bit output MMX case, where dither covers - ; 8 pixels but we can only handle 2 pixels per register, and thus 4 - ; pixels per iteration. In order to not have to keep track of where - ; we are w.r.t. dithering, we unroll the MMX/8-bit loop x2. -%if %1 == 8 -%assign %%repcnt 16/mmsize -%else -%assign %%repcnt 1 -%endif - -%rep %%repcnt - %if %1 == 8 %if ARCH_X86_32 - mova m2, [rsp+mmsize*(0+%%i)] - mova m1, [rsp+mmsize*(1+%%i)] + mova m2, [rsp] + mova m1, [rsp+mmsize] %else ; x86-64 mova m2, m8 mova m1, m_dith @@ -142,7 +129,7 @@ SECTION .text %else movsx cntr_reg, fltsizem %endif -.filterloop_%2_ %+ %%i: +.filterloop_%2: ; input pixels mov r6, [srcq+gprsize*cntr_reg-2*gprsize] %if %1 == 16 @@ -189,7 +176,7 @@ SECTION .text %endif ; %1 == 8/9/10/16 sub cntr_reg, 2 - jg .filterloop_%2_ %+ %%i + jg .filterloop_%2 %if %1 == 16 psrad m2, 31 - %1 @@ -210,10 +197,10 @@ SECTION .text %else ; %1 == 9/10 %if cpuflag(sse4) packusdw m2, m1 -%else ; mmxext/sse2 +%else ; sse2 packssdw m2, m1 pmaxsw m2, m6 -%endif ; mmxext/sse2/sse4/avx +%endif ; sse2/sse4/avx pminsw m2, [yuv2yuvX_%1_upper] %endif ; %1 == 9/10/16 mov%2 [dstq+r5*2], m2 @@ -222,8 +209,6 @@ SECTION .text add r5, mmsize/2 sub wd, mmsize/2 -%assign %%i %%i+2 -%endrep jg .pixelloop_%2 %endmacro @@ -267,14 +252,9 @@ cglobal yuv2planeX_%1, %3, 8, %2, -STACK_SIZE, filter, fltsize, src, dst, w, dit movq m_dith, [ditherq] ; dither test offsetd, offsetd jz .no_rot -%if mmsize == 16 punpcklqdq m_dith, m_dith psrldq m_dith, 3 -%else - PALIGNR m_dith, m_dith, 3, m0 -%endif ; mmsize == 16 .no_rot: -%if mmsize == 16 punpcklbw m_dith, m6 %if ARCH_X86_64 punpcklwd m8, m_dith, m6 @@ -289,45 +269,24 @@ cglobal yuv2planeX_%1, %3, 8, %2, -STACK_SIZE, filter, fltsize, src, dst, w, dit mova [rsp+ 0], m5 mova [rsp+16], m_dith %endif -%else ; mmsize == 8 - punpcklbw m5, m_dith, m6 - punpckhbw m_dith, m6 - punpcklwd m4, m5, m6 - punpckhwd m5, m6 - punpcklwd m3, m_dith, m6 - punpckhwd m_dith, m6 - pslld m4, 12 - pslld m5, 12 - pslld m3, 12 - pslld m_dith, 12 - mova [rsp+ 0], m4 - mova [rsp+ 8], m5 - mova [rsp+16], m3 - mova [rsp+24], m_dith -%endif ; mmsize == 8/16 %endif ; %1 == 8 xor r5, r5 -%if mmsize == 8 || %1 == 8 +%if %1 == 8 yuv2planeX_mainloop %1, a -%else ; mmsize == 16 +%else ; %1 != 8 test dstq, 15 jnz .unaligned yuv2planeX_mainloop %1, a RET .unaligned: yuv2planeX_mainloop %1, u -%endif ; mmsize == 8/16 +%endif ; %1 == 8 RET %endmacro -%if ARCH_X86_32 && HAVE_ALIGNED_STACK == 0 -INIT_MMX mmxext -yuv2planeX_fn 8, 0, 7 -%endif - INIT_XMM sse2 yuv2planeX_fn 8, 10, 7 yuv2planeX_fn 9, 7, 5 @@ -368,12 +327,12 @@ yuv2planeX_fn 10, 7, 5 %if cpuflag(sse4) ; avx/sse4 packusdw m0, m1 packusdw m2, m3 -%else ; mmx/sse2 +%else ; sse2 packssdw m0, m1 packssdw m2, m3 paddw m0, m5 paddw m2, m5 -%endif ; mmx/sse2/sse4/avx +%endif ; sse2/sse4/avx mov%2 [dstq+wq*2+mmsize*0], m0 mov%2 [dstq+wq*2+mmsize*1], m2 %else ; %1 == 9/10 diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index f3aaa704f6..9bd4f526ba 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -267,7 +267,6 @@ void ff_yuv2planeX_ ## size ## _ ## opt(const int16_t *filter, int filterSize, \ VSCALEX_FUNC(9, opt); \ VSCALEX_FUNC(10, opt) -VSCALEX_FUNC(8, mmxext); VSCALEX_FUNCS(sse2); VSCALEX_FUNCS(sse4); VSCALEX_FUNC(16, sse4); @@ -509,14 +508,6 @@ av_cold void ff_sws_init_swscale_x86(SwsInternal *c) c->yuv2planeX = yuv2yuvX_avx2; #endif } -#if ARCH_X86_32 && !HAVE_ALIGNED_STACK - // The better yuv2planeX_8 functions need aligned stack on x86-32, - // so we use MMXEXT in this case if they are not available. - if (EXTERNAL_MMXEXT(cpu_flags)) { - if (c->dstBpc == 8 && !c->use_mmx_vfilter) - c->yuv2planeX = ff_yuv2planeX_8_mmxext; - } -#endif /* ARCH_X86_32 && !HAVE_ALIGNED_STACK */ #define ASSIGN_SCALE_FUNC2(hscalefn, filtersize, opt1, opt2) do { \ if (c->srcBpc == 8) { \ -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
