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

Side by Side Diff: media/base/simd/convert_rgb_to_yuv_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 int8 kSIMD_ConvertARGBtoYUV_kTable[16 + 4] = {
10 ; 25, 2, 66, 0, 0, 127, 0, 0, 112, -74, -38, 0, -18, -94, 112, 0,
11 ; 128, 0, 128, 0,
12 ; };
13 ;
14 SECTION_RODATA
15
16 SIMD_ConvertARGBtoYUV_kTable:
17 db 25, 2, 66, 0
Alpha Left Google 2011/09/01 13:24:45 Please add comments here for what these constants
18 db 0, 127, 0, 0
19 db 112, -74, -38, 0
20 db -18, -94, 112, 0
21 dw 128, 128
22
Alpha Left Google 2011/09/01 13:24:45 It looks like this is the UV offset, please add co
23 ;
24 ; This file uses SSE, SSE2, SSE3, and SSSE3, which are supported by all ATOM
25 ; processors.
26 ;
27 SECTION_TEXT
28 CPU SSE, SSE3, SSE3, SSSE3
29
30 ;
31 ; XMM registers representing constants. We must not use these registers as
32 ; destination operands.
33 ; for (int i = 0; i < 16; i += 4) {
34 ; xmm7.b[i] = 25; xmm7.b[i+1] = 2; xmm7.b[i+2] = 66; xmm7.b[i+3] = 0;
35 ; xmm6.b[i] = 0; xmm6.b[i+1] = 127; xmm6.b[i+2] = 0; xmm6.b[i+3] = 0;
36 ; xmm5.b[i] = 112; xmm5.b[i+1] = -74; xmm5.b[i+2] = -38; xmm5.b[i+3] = 0;
37 ; xmm4.b[i] = -18; xmm4.b[i+1] = -94; xmm4.b[i+2] = 112; xmm4.b[i+3] = 0;
38 ; }
39 ;
40 %define XMM_CONST_Y0 xmm7
41 %define XMM_CONST_Y1 xmm6
42 %define XMM_CONST_U xmm5
43 %define XMM_CONST_V xmm4
44 %define XMM_CONST_128 xmm3
45
46 ;
47 ; LOAD_XMM %1 (xmm), %2 (imm32)
48 ; Loads an immediate value to an XMM register.
49 ; %1.d[0] = %1.d[1] = %1.d[2] = %1.d[3] = %2;
50 ;
51 %macro LOAD_XMM 2
52 mov TEMPd, %2
53 movd %1, TEMPd
54 pshufd %1, %1, 00000000B
55 %endmacro
56
57 ;
58 ; UNPACKRGB %1 (xmm), %2 (imm8)
59 ; Unpacks one RGB pixel in the specified XMM register.
60 ; for (int i = 15; i > %2; --i) %1.b[i] = %1.b[i - 1];
61 ; %1.b[%2] = 0;
62 ; for (int i = %2 - 1; i >= 0; --i) %1.b[i] = %1.b[i];
63 ;
64 %macro UNPACKRGB 2
65 movdqa xmm1, %1
66 psrldq xmm1, %2
67 pslldq xmm1, %2
68 pxor %1, xmm1
69 pslldq xmm1, 1
70 por %1, xmm1
71 %endmacro
72
73 ;
74 ; READ_ARGB %1 (xmm), %2 (imm)
75 ; Read the specified number of ARGB (or RGB) pixels from the source and store
76 ; them to the destination xmm register. If the input format is RGB, we read RGB
77 ; pixels and convert them to ARGB pixels. (For this case, the alpha values of
78 ; the output pixels become 0.)
79 ;
80 %macro READ_ARGB 2
81
82 %if PIXELSIZE == 4
83
84 ; Read ARGB pixels from the source. (This macro assumes the input buffer may
85 ; not be aligned to a 16-byte boundary.)
86 %if %2 == 1
87 movd %1, DWORD [ARGBq + WIDTHq * 4 * 2]
88 %elif %2 == 2
89 movq %1, QWORD [ARGBq + WIDTHq * 4 * 2]
90 %elif %2 == 4
91 movdqu %1, DQWORD [ARGBq + WIDTHq * 4 * 2]
92 %else
93 %error unsupported number of pixels.
94 %endif
95
96 %elif PIXELSIZE == 3
97
98 ; Read RGB pixels from the source and convert them to ARGB pixels.
99 %if %2 == 1
100 ; Read one RGB pixel and convert it to one ARGB pixel.
101 ; Save the WIDTH register to xmm1. (This macro needs to break it.)
102 MOVq xmm1, WIDTHq
103
104 ; Once read three bytes from the source to TEMPd, and copy it to the
105 ; destination xmm register.
106 lea WIDTHq, [WIDTHq + WIDTHq * 2]
107 movzx TEMPd, BYTE [ARGBq + WIDTHq * 2 + 2]
108 shl TEMPd, 16
109 mov TEMPw, WORD [ARGBq + WIDTHq * 2]
110 movd %1, TEMPd
111
112 ; Restore the WIDTH register.
113 MOVq WIDTHq, xmm1
114 %elif %2 == 2
115 ; Read two RGB pixels and convert them to two ARGB pixels.
116 ; Read six bytes from the source to the destination xmm register.
117 mov TEMPq, WIDTHq
118 lea TEMPq, [TEMPq + TEMPq * 2]
119 movd %1, DWORD [ARGBq + TEMPq * 2]
120 pinsrw %1, WORD [ARGBq + TEMPq * 2 + 4], 3
121
122 ; Fill the alpha values of these RGB pixels with 0 and convert them to two
123 ; ARGB pixels.
124 UNPACKRGB %1, 3
125 %elif %2 == 4
126 ; Read four RGB pixels and convert them to four ARGB pixels.
127 ; Read twelve bytes from the source to the destination xmm register.
128 mov TEMPq, WIDTHq
129 lea TEMPq, [TEMPq + TEMPq * 2]
130 movq %1, QWORD [ARGBq + TEMPq * 2]
131 movd xmm1, DWORD [ARGBq + TEMPq * 2 + 8]
132 shufps %1, xmm1, 01000100B
133
134 ; Fill the alpha values of these RGB pixels with 0 and convert them to four
135 ; ARGB pixels.
136 UNPACKRGB %1, 3
137 UNPACKRGB %1, 4 + 3
138 UNPACKRGB %1, 4 + 4 + 3
139 %else
140 %error unsupported number of pixels.
141 %endif
142
143 %else
144 %error unsupported PIXELSIZE value.
145 %endif
146
147 %endmacro
148
149 ;
150 ; CALC_Y %1 (xmm), %2 (xmm)
151 ; Calculates four Y values from four ARGB pixels stored in %2.
152 ; %1.b[0] = ToByte((25 * B(0) + 129 * G(0) + 66 * R(0) + 128) / 256 + 16);
153 ; %1.b[1] = ToByte((25 * B(1) + 129 * G(1) + 66 * R(1) + 128) / 256 + 16);
154 ; %1.b[2] = ToByte((25 * B(2) + 129 * G(2) + 66 * R(2) + 128) / 256 + 16);
155 ; %1.b[3] = ToByte((25 * B(3) + 129 * G(3) + 66 * R(3) + 128) / 256 + 16);
156 ;
157 %macro CALC_Y 2
158 ; To avoid signed saturation, we divide this conversion formula into two
159 ; formulae and store their results into two XMM registers %1 and xmm2.
160 ; %1.w[0] = 25 * %2.b[0] + 2 * %2.b[1] + 66 * %2.b[2] + 0 * %2.b[3];
161 ; %1.w[1] = 25 * %2.b[4] + 2 * %2.b[5] + 66 * %2.b[6] + 0 * %2.b[7];
162 ; %1.w[2] = 25 * %2.b[8] + 2 * %2.b[9] + 66 * %2.b[10] + 0 * %2.b[11];
163 ; %1.w[3] = 25 * %2.b[12] + 2 * %2.b[13] + 66 * %2.b[14] + 0 * %2.b[15];
164 ; xmm2.w[0] = 0 * %2.b[0] + 127 * %2.b[1] + 0 * %2.b[2] + 0 * %2.b[3];
165 ; xmm2.w[1] = 0 * %2.b[4] + 127 * %2.b[5] + 0 * %2.b[6] + 0 * %2.b[7];
166 ; xmm2.w[2] = 0 * %2.b[8] + 127 * %2.b[9] + 0 * %2.b[10] + 0 * %2.b[11];
167 ; xmm2.w[3] = 0 * %2.b[12] + 127 * %2.b[13] + 0 * %2.b[14] + 0 * %2.b[15];
168 movdqa %1, %2
169 pmaddubsw %1, XMM_CONST_Y0
170 phaddsw %1, %1
171 movdqa xmm2, %2
172 pmaddubsw xmm2, XMM_CONST_Y1
173 phaddsw xmm2, xmm2
174
175 ; %1.b[0] = ToByte((%1.w[0] + xmm2.w[0] + 128) / 256 + 16);
176 ; %1.b[1] = ToByte((%1.w[1] + xmm2.w[1] + 128) / 256 + 16);
177 ; %1.b[2] = ToByte((%1.w[2] + xmm2.w[2] + 128) / 256 + 16);
178 ; %1.b[3] = ToByte((%1.w[3] + xmm2.w[3] + 128) / 256 + 16);
179 paddw %1, xmm2
180 movdqa xmm2, XMM_CONST_128
181 paddw %1, xmm2
182 psrlw %1, 8
183 psrlw xmm2, 3
184 paddw %1, xmm2
185 packuswb %1, %1
186 %endmacro
187
188 ;
189 ; INIT_UV %1 (r32), %2 (reg) %3 (imm)
190 ;
191 %macro INIT_UV 3
192
193 %if SUBSAMPLING == 1 && LINE == 1
194 %if %3 == 1 || %3 == 2
195 movzx %1, BYTE [%2 + WIDTHq]
196 %elif %3 == 4
197 movzx %1, WORD [%2 + WIDTHq]
198 %else
199 %error unsupported number of pixels.
200 %endif
201 %endif
202
203 %endmacro
204
205 ;
206 ; CALC_UV %1 (xmm), %2 (xmm), %3 (xmm), %4 (r32)
207 ; Calculates two U (or V) values from four ARGB pixels stored in %2.
208 ; if %3 == XMM_CONST_U
209 ; if (SUBSAMPLING) {
210 ; %1.b[0] = ToByte((112 * B(0) - 74 * G(0) - 38 * R(0) + 128) / 256 + 128);
211 ; %1.b[0] = ToByte((112 * B(0) - 74 * G(0) - 38 * R(0) + 128) / 256 + 128);
212 ; %1.b[1] = ToByte((112 * B(2) - 74 * G(2) - 38 * R(2) + 128) / 256 + 128);
213 ; %1.b[1] = ToByte((112 * B(2) - 74 * G(2) - 38 * R(2) + 128) / 256 + 128);
214 ; } else {
215 ; %1.b[0] = ToByte((112 * B(0) - 74 * G(0) - 38 * R(0) + 128) / 256 + 128);
216 ; %1.b[1] = ToByte((112 * B(2) - 74 * G(2) - 38 * R(2) + 128) / 256 + 128);
217 ; }
218 ; if %3 == XMM_CONST_V
219 ; %1.b[0] = ToByte((-18 * B(0) - 94 * G(0) + 112 * R(0) + 128) / 256 + 128);
220 ; %1.b[1] = ToByte((-18 * B(2) - 94 * G(2) + 112 * R(2) + 128) / 256 + 128);
221 ;
222 %macro CALC_UV 4
223 ; for (int i = 0; i < 4; ++i) {
224 ; %1.w[i] = 0;
225 ; for (int j = 0; j < 4; ++j)
226 ; %1.w[i] += %3.b[i * 4 + j] + %2.b[i * 4 + j];
227 ; }
228 movdqa %1, %2
229 pmaddubsw %1, %3
230 phaddsw %1, %1
231
232 %if SUBSAMPLING == 1
233 ; %1.w[0] = (%1.w[0] + %1.w[1] + 1) / 2;
234 ; %1.w[1] = (%1.w[1] + %1.w[0] + 1) / 2;
235 ; %1.w[2] = (%1.w[2] + %1.w[3] + 1) / 2;
236 ; %1.w[3] = (%1.w[3] + %1.w[2] + 1) / 2;
237 pshuflw xmm2, %1, 10110001B
238 pavgw %1, xmm2
239 %endif
240
241 ; %1.b[0] = ToByte((%1.w[0] + 128) / 256 + 128);
242 ; %1.b[1] = ToByte((%1.w[2] + 128) / 256 + 128);
243 pshuflw %1, %1, 10001000B
244 paddw %1, XMM_CONST_128
245 psraw %1, 8
246 paddw %1, XMM_CONST_128
247 packuswb %1, %1
248
249 %if SUBSAMPLING == 1 && LINE == 1
250 ; %1.b[0] = (%1.b[0] + %3.b[0] + 1) / 2;
251 ; %1.b[1] = (%1.b[1] + %3.b[1] + 1) / 2;
252 movd xmm2, %4
253 pavgb %1, xmm2
254 %endif
255 %endmacro
256
257 ;
258 ; void media::simd::ConvertARGBtoYUVRow(const uint8* argb,
259 ; uint8* y,
260 ; uint8* u,
261 ; uint8* v,
262 ; int width);
263 ;
264 %ifdef MACHO
265 %define SYMBOL __ZN5media4simd19ConvertARGBtoYUVRowEPKhPhS3_S3_i
266 %elifdef ELF
267 %define SYMBOL _ZN5media4simd19ConvertARGBtoYUVRowEPKhPhS3_S3_i
268 %elifdef MSVC
269 %define SYMBOL ?ConvertARGBtoYUVRow@simd@media@@YAXPBEPAE11H@Z
270 %endif
271 %define PIXELSIZE 4
272 %define SUBSAMPLING 0
273 %define LINE 0
274 %include "convert_rgb_to_yuv_ssse3.inc"
275
276 ;
277 ; void media::simd::ConvertRGBToYUVRow(const uint8* rgb,
278 ; uint8* y,
279 ; uint8* u,
280 ; uint8* v,
281 ; int width);
282 ;
283 %ifdef MACHO
284 %define SYMBOL __ZN5media4simd18ConvertRGBtoYUVRowEPKhPhS3_S3_i
285 %elifdef ELF
286 %define SYMBOL _ZN5media4simd18ConvertRGBtoYUVRowEPKhPhS3_S3_i
287 %elifdef MSVC
288 %define SYMBOL ?ConvertRGBtoYUVRow@simd@media@@YAXPBEPAE11H@Z
289 %endif
290 %define PIXELSIZE 3
291 %define SUBSAMPLING 0
292 %define LINE 0
293 %include "convert_rgb_to_yuv_ssse3.inc"
294
295 ;
296 ; void media::simd::ConvertARGBtoYUVEven(const uint8* argb,
297 ; uint8* y,
298 ; uint8* u,
299 ; uint8* v,
300 ; int width);
301 ;
302 %ifdef MACHO
303 %define SYMBOL __ZN5media4simd19ConvertARGBtoYUVEvenEPKhPhS3_S3_i
304 %elifdef ELF
305 %define SYMBOL _ZN5media4simd19ConvertARGBtoYUVEvenEPKhPhS3_S3_i
306 %elifdef MSVC
307 %define SYMBOL ?ConvertARGBtoYUVEven@simd@media@@YAXPBEPAE11H@Z
308 %endif
309 %define PIXELSIZE 4
310 %define SUBSAMPLING 1
311 %define LINE 0
312 %include "convert_rgb_to_yuv_ssse3.inc"
313
314 ;
315 ; void media::simd::ConvertARGBtoYUVOdd(const uint8* argb,
316 ; uint8* y,
317 ; uint8* u,
318 ; uint8* v,
319 ; int width);
320 ;
321 %ifdef MACHO
322 %define SYMBOL __ZN5media4simd19ConvertARGBtoYUVOddEPKhPhS3_S3_i
323 %elifdef ELF
324 %define SYMBOL _ZN5media4simd19ConvertARGBtoYUVOddEPKhPhS3_S3_i
325 %elifdef MSVC
326 %define SYMBOL ?ConvertARGBtoYUVOdd@simd@media@@YAXPBEPAE11H@Z
327 %endif
328 %define PIXELSIZE 4
329 %define SUBSAMPLING 1
330 %define LINE 1
331 %include "convert_rgb_to_yuv_ssse3.inc"
332
333 ;
334 ; void media::simd::ConvertRGBToYUVEven(const uint8* rgb,
335 ; uint8* y,
336 ; uint8* u,
337 ; uint8* v,
338 ; int width);
339 ;
340 %ifdef MACHO
341 %define SYMBOL __ZN5media4simd18ConvertRGBtoYUVEvenEPKhPhS3_S3_i
342 %elifdef ELF
343 %define SYMBOL _ZN5media4simd18ConvertRGBtoYUVEvenEPKhPhS3_S3_i
344 %elifdef MSVC
345 %define SYMBOL ?ConvertRGBtoYUVEven@simd@media@@YAXPBEPAE11H@Z
346 %endif
347 %define PIXELSIZE 3
348 %define SUBSAMPLING 1
349 %define LINE 0
350 %include "convert_rgb_to_yuv_ssse3.inc"
351
352 ;
353 ; void media::simd::ConvertRGBToYUVOdd(const uint8* rgb,
354 ; uint8* y,
355 ; uint8* u,
356 ; uint8* v,
357 ; int width);
358 ;
359 %ifdef MACHO
360 %define SYMBOL __ZN5media4simd18ConvertRGBtoYUVOddEPKhPhS3_S3_i
361 %elifdef ELF
362 %define SYMBOL _ZN5media4simd18ConvertRGBtoYUVOddEPKhPhS3_S3_i
363 %elifdef MSVC
364 %define SYMBOL ?ConvertRGBtoYUVOdd@simd@media@@YAXPBEPAE11H@Z
365 %endif
366 %define PIXELSIZE 3
367 %define SUBSAMPLING 1
368 %define LINE 1
369 %include "convert_rgb_to_yuv_ssse3.inc"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698