50b5f8a19771417b5c7de0819f568a37d02688fe
[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 %macro MULTIPLY 3 ; a, b, pw_1
106     pmullw          %1, %2               ; xxxxxxxx  a * b
107     paddw           %1, %3
108     mova            %2, %1
109     psrlw           %2, 8
110     paddw           %1, %2
111     psrlw           %1, 8                ; 00xx00xx  a * b / 255
112 %endmacro
113
114 BLEND_INIT multiply, 4
115     pxor       m2, m2
116     mova       m3, [pw_1]
117 .nextrow:
118     mov        xq, widthq
119
120     .loop:
121                                              ;     word
122                                              ;     |--|
123         movh            m0, [topq + xq]      ; 0000xxxx
124         movh            m1, [bottomq + xq]
125         punpcklbw       m0, m2               ; 00xx00xx
126         punpcklbw       m1, m2
127
128         MULTIPLY        m0, m1, m3
129
130         packuswb        m0, m0               ; 0000xxxx
131         movh   [dstq + xq], m0
132         add             xq, mmsize / 2
133
134     jl .loop
135 BLEND_END
136
137 BLEND_INIT average, 3
138     pxor       m2, m2
139 .nextrow:
140     mov        xq, widthq
141
142     .loop:
143         movh            m0, [topq + xq]
144         movh            m1, [bottomq + xq]
145         punpcklbw       m0, m2
146         punpcklbw       m1, m2
147         paddw           m0, m1
148         psrlw           m0, 1
149         packuswb        m0, m0
150         movh   [dstq + xq], m0
151         add             xq, mmsize / 2
152     jl .loop
153 BLEND_END
154
155 BLEND_INIT addition128, 4
156     pxor       m2, m2
157     mova       m3, [pw_128]
158 .nextrow:
159     mov        xq, widthq
160
161     .loop:
162         movh            m0, [topq + xq]
163         movh            m1, [bottomq + xq]
164         punpcklbw       m0, m2
165         punpcklbw       m1, m2
166         paddw           m0, m1
167         psubw           m0, m3
168         packuswb        m0, m0
169         movh   [dstq + xq], m0
170         add             xq, mmsize / 2
171     jl .loop
172 BLEND_END
173
174 BLEND_INIT hardmix, 5
175     mova       m2, [pb_255]
176     mova       m3, [pb_128]
177     mova       m4, [pb_127]
178 .nextrow:
179     mov        xq, widthq
180
181     .loop:
182         movu            m0, [topq + xq]
183         movu            m1, [bottomq + xq]
184         pxor            m1, m4
185         pxor            m0, m3
186         pcmpgtb         m1, m0
187         pxor            m1, m2
188         mova   [dstq + xq], m1
189         add             xq, mmsize
190     jl .loop
191 BLEND_END
192
193 BLEND_INIT phoenix, 4
194     mova       m3, [pb_255]
195 .nextrow:
196     mov        xq, widthq
197
198     .loop:
199         movu            m0, [topq + xq]
200         movu            m1, [bottomq + xq]
201         mova            m2, m0
202         pminub          m0, m1
203         pmaxub          m1, m2
204         mova            m2, m3
205         psubusb         m2, m1
206         paddusb         m2, m0
207         mova   [dstq + xq], m2
208         add             xq, mmsize
209     jl .loop
210 BLEND_END
211
212 %macro BLEND_ABS 0
213 BLEND_INIT difference, 3
214     pxor       m2, m2
215 .nextrow:
216     mov        xq, widthq
217
218     .loop:
219         movh            m0, [topq + xq]
220         movh            m1, [bottomq + xq]
221         punpcklbw       m0, m2
222         punpcklbw       m1, m2
223         psubw           m0, m1
224         ABS1            m0, m1
225         packuswb        m0, m0
226         movh   [dstq + xq], m0
227         add             xq, mmsize / 2
228     jl .loop
229 BLEND_END
230
231 BLEND_INIT negation, 5
232     pxor       m2, m2
233     mova       m4, [pw_255]
234 .nextrow:
235     mov        xq, widthq
236
237     .loop:
238         movh            m0, [topq + xq]
239         movh            m1, [bottomq + xq]
240         punpcklbw       m0, m2
241         punpcklbw       m1, m2
242         mova            m3, m4
243         psubw           m3, m0
244         psubw           m3, m1
245         ABS1            m3, m1
246         mova            m0, m4
247         psubw           m0, m3
248         packuswb        m0, m0
249         movh   [dstq + xq], m0
250         add             xq, mmsize / 2
251     jl .loop
252 BLEND_END
253 %endmacro
254
255 INIT_XMM sse2
256 BLEND_ABS
257 INIT_XMM ssse3
258 BLEND_ABS