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]

Reply via email to