vf_blend: Add SSE2 optimization for multiply
[ffmpeg.git] / libavfilter / x86 / vf_blend.asm
1 ;*****************************************************************************
2 ;* x86-optimized functions for blend filter
3 ;*
4 ;* Copyright (C) 2015 Paul B Mahol
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* FFmpeg is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_RODATA
26
27 pw_1:   times 8 dw 1
28 pw_128: times 8 dw 128
29 pw_255: times 8 dw 255
30 pb_127: times 16 db 127
31 pb_128: times 16 db 128
32 pb_255: times 16 db 255
33
34 SECTION .text
35
36 %macro BLEND_INIT 2
37 %if ARCH_X86_64
38 cglobal blend_%1, 6, 9, %2, top, top_linesize, bottom, bottom_linesize, dst, dst_linesize, width, end, x
39     mov    widthd, dword widthm
40 %else
41 cglobal blend_%1, 5, 7, %2, top, top_linesize, bottom, bottom_linesize, dst, end, x
42 %define dst_linesizeq r5mp
43 %define widthq r6mp
44 %endif
45     mov      endd, dword r8m
46     add      topq, widthq
47     add   bottomq, widthq
48     add      dstq, widthq
49     sub      endd, dword r7m ; start
50     neg    widthq
51 %endmacro
52
53 %macro BLEND_END 0
54     add          topq, top_linesizeq
55     add       bottomq, bottom_linesizeq
56     add          dstq, dst_linesizeq
57     sub          endd, 1
58     jg .nextrow
59 REP_RET
60 %endmacro
61
62 %macro BLEND_SIMPLE 2
63 BLEND_INIT %1, 2
64 .nextrow:
65     mov        xq, widthq
66
67     .loop:
68         movu            m0, [topq + xq]
69         movu            m1, [bottomq + xq]
70         p%2             m0, m1
71         mova   [dstq + xq], m0
72         add             xq, mmsize
73     jl .loop
74 BLEND_END
75 %endmacro
76
77 INIT_XMM sse2
78 BLEND_SIMPLE xor,      xor
79 BLEND_SIMPLE or,       or
80 BLEND_SIMPLE and,      and
81 BLEND_SIMPLE addition, addusb
82 BLEND_SIMPLE subtract, subusb
83 BLEND_SIMPLE darken,   minub
84 BLEND_SIMPLE lighten,  maxub
85
86 BLEND_INIT difference128, 4
87     pxor       m2, m2
88     mova       m3, [pw_128]
89 .nextrow:
90     mov        xq, widthq
91
92     .loop:
93         movh            m0, [topq + xq]
94         movh            m1, [bottomq + xq]
95         punpcklbw       m0, m2
96         punpcklbw       m1, m2
97         paddw           m0, m3
98         psubw           m0, m1
99         packuswb        m0, m0
100         movh   [dstq + xq], m0
101         add             xq, mmsize / 2
102     jl .loop
103 BLEND_END
104
105 BLEND_INIT multiply, 4
106     pxor       m2, m2
107     mova       m3, [pw_1]
108 .nextrow:
109     mov        xq, widthq
110
111     .loop:
112                                              ;     word
113                                              ;     |--|
114         movh            m0, [topq + xq]      ; 0000xxxx
115         movh            m1, [bottomq + xq]
116         punpcklbw       m0, m2               ; 00xx00xx
117         punpcklbw       m1, m2
118
119         pmullw          m0, m1               ; xxxxxxxx  a * b
120         paddw           m0, m3
121         mova            m1, m0
122         psrlw           m1, 8
123         paddw           m0, m1
124         psrlw           m0, 8                ; 00xx00xx  a * b / 255
125
126         packuswb        m0, m0               ; 0000xxxx
127         movh   [dstq + xq], m0
128         add             xq, mmsize / 2
129
130     jl .loop
131 BLEND_END
132
133 BLEND_INIT average, 3
134     pxor       m2, m2
135 .nextrow:
136     mov        xq, widthq
137
138     .loop:
139         movh            m0, [topq + xq]
140         movh            m1, [bottomq + xq]
141         punpcklbw       m0, m2
142         punpcklbw       m1, m2
143         paddw           m0, m1
144         psrlw           m0, 1
145         packuswb        m0, m0
146         movh   [dstq + xq], m0
147         add             xq, mmsize / 2
148     jl .loop
149 BLEND_END
150
151 BLEND_INIT addition128, 4
152     pxor       m2, m2
153     mova       m3, [pw_128]
154 .nextrow:
155     mov        xq, widthq
156
157     .loop:
158         movh            m0, [topq + xq]
159         movh            m1, [bottomq + xq]
160         punpcklbw       m0, m2
161         punpcklbw       m1, m2
162         paddw           m0, m1
163         psubw           m0, m3
164         packuswb        m0, m0
165         movh   [dstq + xq], m0
166         add             xq, mmsize / 2
167     jl .loop
168 BLEND_END
169
170 BLEND_INIT hardmix, 5
171     mova       m2, [pb_255]
172     mova       m3, [pb_128]
173     mova       m4, [pb_127]
174 .nextrow:
175     mov        xq, widthq
176
177     .loop:
178         movu            m0, [topq + xq]
179         movu            m1, [bottomq + xq]
180         pxor            m1, m4
181         pxor            m0, m3
182         pcmpgtb         m1, m0
183         pxor            m1, m2
184         mova   [dstq + xq], m1
185         add             xq, mmsize
186     jl .loop
187 BLEND_END
188
189 BLEND_INIT phoenix, 4
190     mova       m3, [pb_255]
191 .nextrow:
192     mov        xq, widthq
193
194     .loop:
195         movu            m0, [topq + xq]
196         movu            m1, [bottomq + xq]
197         mova            m2, m0
198         pminub          m0, m1
199         pmaxub          m1, m2
200         mova            m2, m3
201         psubusb         m2, m1
202         paddusb         m2, m0
203         mova   [dstq + xq], m2
204         add             xq, mmsize
205     jl .loop
206 BLEND_END
207
208 %macro BLEND_ABS 0
209 BLEND_INIT difference, 3
210     pxor       m2, m2
211 .nextrow:
212     mov        xq, widthq
213
214     .loop:
215         movh            m0, [topq + xq]
216         movh            m1, [bottomq + xq]
217         punpcklbw       m0, m2
218         punpcklbw       m1, m2
219         psubw           m0, m1
220         ABS1            m0, m1
221         packuswb        m0, m0
222         movh   [dstq + xq], m0
223         add             xq, mmsize / 2
224     jl .loop
225 BLEND_END
226
227 BLEND_INIT negation, 5
228     pxor       m2, m2
229     mova       m4, [pw_255]
230 .nextrow:
231     mov        xq, widthq
232
233     .loop:
234         movh            m0, [topq + xq]
235         movh            m1, [bottomq + xq]
236         punpcklbw       m0, m2
237         punpcklbw       m1, m2
238         mova            m3, m4
239         psubw           m3, m0
240         psubw           m3, m1
241         ABS1            m3, m1
242         mova            m0, m4
243         psubw           m0, m3
244         packuswb        m0, m0
245         movh   [dstq + xq], m0
246         add             xq, mmsize / 2
247     jl .loop
248 BLEND_END
249 %endmacro
250
251 INIT_XMM sse2
252 BLEND_ABS
253 INIT_XMM ssse3
254 BLEND_ABS