swscale/x86/rgb2rgb : port shuffle 2103 mmxext to external asm and remove inline...
[ffmpeg.git] / libswscale / x86 / rgb_2_rgb.asm
1 ;******************************************************************************
2 ;* Copyright Nick Kurshev
3 ;* Copyright Michael (michaelni@gmx.at)
4 ;* Copyright 2018 Jokyo Images
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 pb_mask_shuffle2103_mmx times 8 dw 255
28 pb_shuffle2103: db 2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15
29 pb_shuffle0321: db 0, 3, 2, 1, 4, 7, 6, 5, 8, 11, 10, 9, 12, 15, 14, 13
30 pb_shuffle1230: db 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12
31 pb_shuffle3012: db 3, 0, 1, 2, 7, 4, 5, 6, 11, 8, 9, 10, 15, 12, 13, 14
32 pb_shuffle3210: db 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
33
34 SECTION .text
35
36 %macro RSHIFT_COPY 3
37 ; %1 dst ; %2 src ; %3 shift
38 %if cpuflag(avx)
39     psrldq  %1, %2, %3
40 %else
41     mova           %1, %2
42     RSHIFT         %1, %3
43 %endif
44 %endmacro
45
46 ;------------------------------------------------------------------------------
47 ; shuffle_bytes_2103_mmext (const uint8_t *src, uint8_t *dst, int src_size)
48 ;------------------------------------------------------------------------------
49 INIT_MMX mmxext
50 cglobal shuffle_bytes_2103, 3, 5, 8, src, dst, w, tmp, x
51     mova   m6, [pb_mask_shuffle2103_mmx]
52     mova   m7, m6
53     psllq  m7, 8
54
55     movsxdifnidn wq, wd
56     mov xq, wq
57
58     add        srcq, wq
59     add        dstq, wq
60     neg          wq
61
62 ;calc scalar loop
63     and xq, mmsize*2 -4
64     je .loop_simd
65
66 .loop_scalar:
67    mov          tmpb, [srcq + wq + 2]
68    mov [dstq+wq + 0], tmpb
69    mov          tmpb, [srcq + wq + 1]
70    mov [dstq+wq + 1], tmpb
71    mov          tmpb, [srcq + wq + 0]
72    mov [dstq+wq + 2], tmpb
73    mov          tmpb, [srcq + wq + 3]
74    mov [dstq+wq + 3], tmpb
75    add            wq, 4
76    sub            xq, 4
77    jg .loop_scalar
78
79 ;check if src_size < mmsize * 2
80 cmp wq, 0
81 jge .end
82
83 .loop_simd:
84     movu     m0, [srcq+wq]
85     movu     m1, [srcq+wq+8]
86
87     pshufw   m3, m0, 177
88     pshufw   m5, m1, 177
89
90     pand     m0, m7
91     pand     m3, m6
92
93     pand     m1, m7
94     pand     m5, m6
95
96     por      m0, m3
97     por      m1, m5
98
99     movu      [dstq+wq], m0
100     movu  [dstq+wq + 8], m1
101
102     add              wq, mmsize*2
103     jl .loop_simd
104
105 .end:
106     RET
107
108 ;------------------------------------------------------------------------------
109 ; shuffle_bytes_## (const uint8_t *src, uint8_t *dst, int src_size)
110 ;------------------------------------------------------------------------------
111 ; %1-4 index shuffle
112 %macro SHUFFLE_BYTES 4
113 cglobal shuffle_bytes_%1%2%3%4, 3, 5, 2, src, dst, w, tmp, x
114     VBROADCASTI128    m0, [pb_shuffle%1%2%3%4]
115     movsxdifnidn wq, wd
116     mov xq, wq
117
118     add        srcq, wq
119     add        dstq, wq
120     neg          wq
121
122 ;calc scalar loop
123     and xq, mmsize-4
124     je .loop_simd
125
126 .loop_scalar:
127    mov          tmpb, [srcq + wq + %1]
128    mov [dstq+wq + 0], tmpb
129    mov          tmpb, [srcq + wq + %2]
130    mov [dstq+wq + 1], tmpb
131    mov          tmpb, [srcq + wq + %3]
132    mov [dstq+wq + 2], tmpb
133    mov          tmpb, [srcq + wq + %4]
134    mov [dstq+wq + 3], tmpb
135    add            wq, 4
136    sub            xq, 4
137    jg .loop_scalar
138
139 ;check if src_size < mmsize
140 cmp wq, 0
141 jge .end
142
143 .loop_simd:
144     movu           m1, [srcq+wq]
145     pshufb         m1, m0
146     movu    [dstq+wq], m1
147     add            wq, mmsize
148     jl .loop_simd
149
150 .end:
151     RET
152 %endmacro
153
154 INIT_XMM ssse3
155 SHUFFLE_BYTES 2, 1, 0, 3
156 SHUFFLE_BYTES 0, 3, 2, 1
157 SHUFFLE_BYTES 1, 2, 3, 0
158 SHUFFLE_BYTES 3, 0, 1, 2
159 SHUFFLE_BYTES 3, 2, 1, 0
160
161 ;-----------------------------------------------------------------------------------------------
162 ; uyvytoyuv422(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
163 ;              const uint8_t *src, int width, int height,
164 ;              int lumStride, int chromStride, int srcStride)
165 ;-----------------------------------------------------------------------------------------------
166 %macro UYVY_TO_YUV422 0
167 cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_stride, src_stride, wtwo, whalf, tmp, x, back_w
168     pxor         m0, m0
169     pcmpeqw      m1, m1
170     psrlw        m1, 8
171
172     movsxdifnidn            wq, wd
173     movsxdifnidn   lum_strideq, lum_strided
174     movsxdifnidn chrom_strideq, chrom_strided
175     movsxdifnidn   src_strideq, src_strided
176
177     mov     back_wq, wq
178     mov      whalfq, wq
179     shr      whalfq, 1     ; whalf = width / 2
180
181     lea srcq, [srcq + wq * 2]
182     add    ydstq, wq
183     add    udstq, whalfq
184     add    vdstq, whalfq
185
186 .loop_line:
187     mov          xq, wq
188     mov       wtwoq, wq
189     add       wtwoq, wtwoq ; wtwo = width * 2
190
191     neg       wq
192     neg    wtwoq
193     neg   whalfq
194
195     ;calc scalar loop count
196     and       xq, mmsize * 2 - 1
197     je .loop_simd
198
199     .loop_scalar:
200         mov             tmpb, [srcq + wtwoq + 0]
201         mov [udstq + whalfq], tmpb
202
203         mov             tmpb, [srcq + wtwoq + 1]
204         mov     [ydstq + wq], tmpb
205
206         mov             tmpb, [srcq + wtwoq + 2]
207         mov [vdstq + whalfq], tmpb
208
209         mov             tmpb, [srcq + wtwoq + 3]
210         mov [ydstq + wq + 1], tmpb
211
212         add      wq, 2
213         add   wtwoq, 4
214         add  whalfq, 1
215         sub      xq, 2
216         jg .loop_scalar
217
218     ; check if simd loop is need
219     cmp      wq, 0
220     jge .end_line
221
222     .loop_simd:
223         movu    m2, [srcq + wtwoq             ]
224         movu    m3, [srcq + wtwoq + mmsize    ]
225         movu    m4, [srcq + wtwoq + mmsize * 2]
226         movu    m5, [srcq + wtwoq + mmsize * 3]
227
228         ; extract y part 1
229         RSHIFT_COPY    m6, m2, 1 ; UYVY UYVY -> YVYU YVY...
230         pand           m6, m1; YxYx YxYx...
231
232         RSHIFT_COPY    m7, m3, 1 ; UYVY UYVY -> YVYU YVY...
233         pand           m7, m1 ; YxYx YxYx...
234
235         packuswb       m6, m7 ; YYYY YYYY...
236         movu [ydstq + wq], m6
237
238         ; extract y part 2
239         RSHIFT_COPY    m6, m4, 1 ; UYVY UYVY -> YVYU YVY...
240         pand           m6, m1; YxYx YxYx...
241
242         RSHIFT_COPY    m7, m5, 1 ; UYVY UYVY -> YVYU YVY...
243         pand           m7, m1 ; YxYx YxYx...
244
245         packuswb                m6, m7 ; YYYY YYYY...
246         movu [ydstq + wq + mmsize], m6
247
248         ; extract uv
249         pand       m2, m1   ; UxVx...
250         pand       m3, m1   ; UxVx...
251         pand       m4, m1   ; UxVx...
252         pand       m5, m1   ; UxVx...
253
254         packuswb   m2, m3   ; UVUV...
255         packuswb   m4, m5   ; UVUV...
256
257         ; U
258         pand       m6, m2, m1 ; UxUx...
259         pand       m7, m4, m1 ; UxUx...
260
261         packuswb m6, m7 ; UUUU
262         movu   [udstq + whalfq], m6
263
264
265         ; V
266         psrlw      m2, 8  ; VxVx...
267         psrlw      m4, 8  ; VxVx...
268         packuswb   m2, m4 ; VVVV
269         movu   [vdstq + whalfq], m2
270
271         add   whalfq, mmsize
272         add    wtwoq, mmsize * 4
273         add       wq, mmsize * 2
274         jl .loop_simd
275
276     .end_line:
277         add        srcq, src_strideq
278         add        ydstq, lum_strideq
279         add        udstq, chrom_strideq
280         add        vdstq, chrom_strideq
281
282         ;restore initial state of line variable
283         mov           wq, back_wq
284         mov          xq, wq
285         mov      whalfq, wq
286         shr      whalfq, 1     ; whalf = width / 2
287         sub          hd, 1
288         jg .loop_line
289
290     RET
291 %endmacro
292
293 %if ARCH_X86_64
294 INIT_XMM sse2
295 UYVY_TO_YUV422
296
297 INIT_XMM avx
298 UYVY_TO_YUV422
299 %endif