Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Side by Side Diff: media/base/simd/convert_yuv_to_rgb_ssse3.asm

Issue 7003082: Implements RGB to YV12 conversion in YASM. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 ; Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 ; Use of this source code is governed by a BSD-style license that can be
3 ; found in the LICENSE file.
4
5 %include "x86inc.asm"
6
7 ;
8 ; A table used in this file.
9 ; static const int16 kSIMD_ConvertYUVtoARGB_kTable[] = {
10 ; -16, -128, -128, 128,
11 ; 298, 0, 409, 1,
12 ; 298, -100, -208, 1,
13 ; 298, 516, 0, 1,
14 ; };
15 ;
16 SECTION_RODATA
17
18 SIMD_ConvertYUVtoARGB_kTable:
19 dw -16, -128, -128, 128
20 dw 298, 0, 409, 1
21 dw 298, -100, -208, 1
22 dw 298, 516, 0, 1,
23
24 ;
25 ; This file uses SSE, SSE2, SSE3, and SSSE3, which are supported by all ATOM
26 ; processors.
27 ;
28 SECTION_TEXT
29 CPU SSE, SSE2, SSE3, SSSE3
30
31 ;
32 ; XMM registers representing constants. We must not use these registers as
33 ; destination operands.
34 ; for (int i = 0; i < 8; i += 4) {
35 ; xmm7.w[i] = -16; xmm7.w[i+1] = -128; xmm7.w[i+2] = -128; xmm7.w[i+3] = 128;
36 ; xmm6.w[i] = 298; xmm6.w[i+1] = 0; xmm6.w[i+2] = 409; xmm6.w[i+3] = 1;
37 ; xmm5.w[i] = 298; xmm5.w[i+1] = -100; xmm5.w[i+2] = -208; xmm5.w[i+3] = 1;
38 ; xmm4.w[i] = 298; xmm4.w[i+1] = 516; xmm4.w[i+2] = 0; xmm4.w[i+3] = 1;
39 ; }
40 ;
41 %define XMM_CONST_BIAS xmm7
42 %define XMM_CONST_R xmm6
43 %define XMM_CONST_G xmm5
44 %define XMM_CONST_B xmm4
45
46 ;
47 ; READ_YUV %1 (imm8)
48 ; Read YUV pixels and pack them. This macro stores the result pixels to xmm0 and
49 ; xmm1 as listed below. (This macro sets xmm0.w[3], xmm0.w[7], xmm1.w[3], and
50 ; xmm1.w[7] to 128 so we can add 128.)
51 ; xmm0.w[0] = Y(0) - 16; xmm0.w[1] = U(0) - 128;
52 ; xmm0.w[2] = V(0) - 128; xmm0.w[3] = 128;
53 ; xmm0.w[4] = Y(1) - 16; xmm0.w[5] = U(0) - 128;
54 ; xmm0.w[6] = V(0) - 128; xmm0.w[7] = 128;
55 ; xmm1.w[0] = Y(2) - 16; xmm1.w[1] = U(1) - 128;
56 ; xmm1.w[2] = V(1) - 128; xmm1.w[3] = 128;
57 ; xmm1.w[4] = Y(3) - 16; xmm1.w[5] = U(1) - 128;
58 ; xmm1.w[6] = V(1) - 128; xmm1.w[7] = 128;
59 ;
60 %macro READ_YUV 1
61 ; Create a zero register so we can used it for unpacking pixels.
62 pxor xmm2, xmm2
63
64 ; Read Y pixels.
65 ; xmm0.b[0] = Y(0); xmm0.b[4] = Y(1); xmm0.b[8] = Y(2); xmm0.b[12] = Y(3);
66 %if %1 == 1
67 movzx TEMPd, BYTE [Yq + WIDTHq * 2]
68 movd xmm0, TEMPd
69 %elif %1 == 2
70 movzx TEMPd, WORD [Yq + WIDTHq * 2]
71 movd xmm0, TEMPd
72 %elif %1 == 4
73 movd xmm0, DWORD [Yq + WIDTHq * 2]
74 %else
75 %error unsupported number of pixels.
76 %endif
77
78 ; Read U pixels.
79 ; xmm0.b[1] = U(0); xmm0.b[5] = U(0); xmm0.b[9] = U(1); xmm0.b[13] = U(1);
80 %if %1 == 1 || %1 == 2
81 movzx TEMPd, BYTE [Uq + WIDTHq]
82 %elif %1 == 4
83 movzx TEMPd, WORD [Uq + WIDTHq]
84 %else
85 %error unsupported number of pixels.
86 %endif
87 movd xmm1, TEMPd
88 punpcklbw xmm1, xmm1
89 punpcklbw xmm0, xmm1
90
91 ; Read V pixels.
92 ; xmm0.b[2] = V(0); xmm0.b[6] = V(0); xmm0.b[10] = V(1); xmm0.b[14] = V(1);
93 %if %1 == 1 || %1 == 2
94 movzx TEMPd, BYTE [Vq + WIDTHq]
95 %elif %1 == 4
96 movzx TEMPd, WORD [Vq + WIDTHq]
97 %else
98 %error unsupported number of pixels.
99 %endif
100 movd xmm1, TEMPd
101 punpcklbw xmm1, xmm1
102 punpcklbw xmm1, xmm2
103 punpcklwd xmm0, xmm1
104
105 ; Unpack the input 8-bit pixels to 16-bit words and remove their offsets.
106 %if %1 ==1 || %1 == 2
107 punpcklbw xmm0, xmm2
108
109 paddsw xmm0, XMM_CONST_BIAS
110 %elif %1 == 4
111 movdqa xmm1, xmm0
112 punpckhbw xmm1, xmm2
113 punpcklbw xmm0, xmm2
114
115 paddsw xmm0, XMM_CONST_BIAS
116 paddsw xmm1, XMM_CONST_BIAS
117 %else
118 %error unsupported number of pixels.
119 %endif
120 %endmacro
121
122 ;
123 ; CALC_R %1 (xmm), %2 (xmm), %3 (imm)
124 ; Calculate four red pixels from four packed YUV pixels stored in %2.
125 ;
126 %macro CALC_R 3
127 pmaddwd %1, XMM_CONST_R
128 %if %3 == 1 || %3 == 2
129 phaddd %1, %1
130 %elif %3 == 4
131 pmaddwd %2, XMM_CONST_R
132 phaddd %1, %2
133 %else
134 %error unsupported number of pixels.
135 %endif
136 psrad %1, 8
137
138 packssdw %1, %1
139 packuswb %1, %1
140 %endmacro
141
142 ;
143 ; CALC_G %1 (xmm), %2 (xmm), %3 (imm)
144 ; Calculate four green pixels from four packed YUV pixels stored in %2.
145 ;
146 %macro CALC_G 3
147 pmaddwd %1, XMM_CONST_G
148 %if %3 == 1 || %3 == 2
149 phaddd %1, %1
150 %elif %3 == 4
151 pmaddwd %2, XMM_CONST_G
152 phaddd %1, %2
153 %else
154 %error unsupported number of pixels.
155 %endif
156 psrad %1, 8
157
158 packssdw %1, %1
159 packuswb %1, %1
160 %endmacro
161
162 ;
163 ; CALC_B %1 (xmm), %2 (xmm), %3 (imm)
164 ; Calculate four blue pixels from four packed YUV pixels stored in %2.
165 ;
166 %macro CALC_B 3
167 pmaddwd %1, XMM_CONST_B
168 %if %3 == 1 || %3 == 2
169 phaddd %1, %1
170 %elif %3 == 4
171 pmaddwd %2, XMM_CONST_B
172 phaddd %1, %2
173 %else
174 %error unsupported number of pixels.
175 %endif
176 psrad %1, 8
177
178 packssdw %1, %1
179 packuswb %1, %1
180 %endmacro
181
182 ;
183 ; PACK_ARGB %1 (xmm), %2 (xmm), %3 (xmm)
184 ; Create four ARGB pixels from R pixels stored in %1, G pixels stored in %2, and
185 ; B pixels stored in %3, respecticely. This macro assumes the input pixels are
186 ; stored in the following format.
187 ; %1.b[0] = B(0); %1.b[1] = B(1); %1.b[2] = B(2); %1.b[3] = B(3);
188 ; %2.b[0] = G(0); %2.b[1] = G(1); %2.b[2] = G(2); %2.b[3] = G(3);
189 ; %3.b[0] = R(0); %3.b[1] = R(1); %3.b[2] = R(2); %3.b[3] = R(3);
190 ; This macro writes the output ARGB pixels in the following format:
191 ; %1.b[0] = B(0); %1.b[1] = G(0); %1.b[2] = R(0); %1.b[3] = 0 or 255;
192 ; %1.b[4] = B(1); %1.b[5] = G(1); %1.b[6] = R(1); %1.b[7] = 0 or 255;
193 ; %1.b[8] = B(1); %1.b[9] = G(2); %1.b[10] = R(2); %1.b[11] = 0 or 255;
194 ; %1.b[12] = B(1); %1.b[13] = G(3); %1.b[14] = R(3); %1.b[15] = 0 or 255;
195 ;
196 %macro PACK_ARGB 3
197 %if ALPHA == 255
198 pcmpeqd xmm3, xmm3
199 %elif ALPHA == 0
200 pxor xmm3, xmm3
201 %else
202 %error unsupported ALPHA value.
203 %endif
204 punpcklbw %1, %2
205 punpcklbw %3, xmm3
206 punpcklwd %1, %3
207 %endmacro
208
209 ;
210 ; PACK_RGB %1 (xmm), %2 (imm)
211 ; Packs one ARGB pixel to an RGB pixel.
212 ; for (int i = 0; i < %2; ++i) %1.b[i] = %1.b[i];
213 ; for (int i = %2; i < 15; ++i) %1.b[i] = %1.b[i + 1];
214 ;
215 %macro PACK_RGB 2
216 movdqa xmm1, %1
217 psrldq xmm1, %2
218 pslldq xmm1, %2
219 pxor %1, xmm1
220 psrldq xmm1, 1
221 por %1, xmm1
222 %endmacro
223
224 ;
225 ; WRITE_ARGB %1 (xmm), %2 (imm)
226 ; Write the specified number of ARGB pixels stored in the source xmm register to
227 ; the output buffer. When the output pixel format is RGB, we convert ARGB pixels
228 ; to RGB pixels and output them.
229 ;
230 %macro WRITE_ARGB 2
231
232 %if PIXELSIZE == 4
233
234 ; Write ARGB pixels to the destination buffer.
235 %if %2 == 1
236 movd DWORD [ARGBq + WIDTHq * 4 * 2], %1
237 %elif %2 == 2
238 movq QWORD [ARGBq + WIDTHq * 4 * 2], %1
239 %elif %2 == 4
240 movdqu DQWORD [ARGBq + WIDTHq * 4 * 2], %1
241 %else
242 %error unsupported number of pixels.
243 %endif
244
245 %elif PIXELSIZE == 3
246
247 ; Write RGB pixels to the destination buffer.
248 %if %2 == 1
249 ; Save the WIDTH register to xmm1. This macro breaks the register.
250 MOVq xmm1, WIDTHq
251
252 ; Write three bytes to the destination buffer. (We do not use maskmovdqu since
253 ; it cause out-of-bound reads. Instead, we copy the source register to TEMPd
254 ; and store it.)
255 lea WIDTHq, [WIDTHq + WIDTHq * 2]
256 movd TEMPd, %1
257 mov WORD [ARGBq + WIDTHq * 2], TEMPw
258 sar TEMPw, 16
259 mov BYTE [ARGBq + WIDTHq * 2 + 2], TEMPb
260
261 ; Restore the WIDTH register.
262 MOVq WIDTHq, xmm1
263 %elif %2 == 2
264 ; Pack two ARGB pixels to two RGB pixels.
265 PACK_RGB %1, 4
266
267 ; Save the WIDTH register to xmm1. This macro breaks the register.
268 MOVq xmm1, WIDTHq
269
270 ; Write six bytes to the destination buffer.
271 lea WIDTHq, [WIDTHq + WIDTHq * 2]
272 movd DWORD [ARGBq + WIDTHq * 2], %1
273 psrldq %1, 4
274 movd TEMPd, %1
275 mov WORD [ARGBq + WIDTHq * 2 + 4], TEMPw
276
277 ; Restore the WIDTH register.
278 MOVq WIDTHq, xmm1
279 %elif %2 == 4
280 ; Pack four ARGB pixels to four RGB pixels.
281 PACK_RGB xmm0, 12
282 PACK_RGB xmm0, 8
283 PACK_RGB xmm0, 4
284
285 ; Write twelve bytes to the destination buffer.
286 mov TEMPq, WIDTHq
287 lea TEMPq, [TEMPq + TEMPq * 2]
288 movq QWORD [ARGBq + TEMPq * 2], %1
289 psrldq %1, 8
290 movd DWORD [ARGBq + TEMPq * 2 + 8], %1
291 %else
292 %error unsupported number of pixels.
293 %endif
294
295 %else
296 %error unsupported PIXELSIZE value.
297 %endif
298
299 %endmacro
300
301 ;
302 ; void media::simd::ConvertYUVtoARGBRow(const uint8* y,
303 ; const uint8* u,
304 ; const uint8* v,
305 ; const uint8* argb,
306 ; int width);
307 ;
308 %ifdef MACHO
309 %define SYMBOL __ZN5media4simd19ConvertYUVtoARGBRowEPKhS2_S2_Phi
310 %elifdef ELF
311 %define SYMBOL _ZN5media4simd19ConvertYUVtoARGBRowEPKhS2_S2_Phi
312 %elifdef MSVC
313 %define SYMBOL ?ConvertYUVtoARGBRow@simd@media@@YAXPBE00PAEH@Z
314 %endif
315 %define PIXELSIZE 4
316 %define ALPHA 255
317
318 %include "convert_yuv_to_rgb_ssse3.inc"
319
320 ;
321 ; void media::simd::ConvertYUVtoRGBRow(const uint8* y,
322 ; const uint8* u,
323 ; const uint8* v,
324 ; const uint8* rgb,
325 ; int width);
326 ;
327 %ifdef MACHO
328 %define SYMBOL __ZN5media4simd18ConvertYUVtoRGBRowEPKhS2_S2_Phi
329 %elifdef ELF
330 %define SYMBOL _ZN5media4simd18ConvertYUVtoRGBRowEPKhS2_S2_Phi
331 %elifdef MSVC
332 %define SYMBOL ?ConvertYUVtoRGBRow@simd@media@@YAXPBE00PAEH@Z
333 %endif
334 %define PIXELSIZE 3
335 %define ALPHA 0
336 %include "convert_yuv_to_rgb_ssse3.inc"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698