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

Side by Side Diff: media/base/simd/convert_row_yuv.inc

Issue 7003082: Implements RGB to YV12 conversion in YASM. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 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
Property Changes:
Added: svn:eol-style
+ LF
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 ;
6 ; void media::simd::ConvertYUVtoRGBARow(const uint8* y,
fbarchard 2011/06/10 17:29:45 ConvertYUVtoRGBARow suggest ConvertYUVtoARGBRow F
7 ; const uint8* u,
8 ; const uint8* v,
9 ; uint8* rgba,
10 ; int width);
11 ; void media::simd::ConvertYUVtoRGBRow(const uint8* y,
12 ; const uint8* u,
13 ; const uint8* v,
14 ; uint8* rgb,
15 ; int width);
16 ;
17 ; Converts a row of YUV (4:1:1) pixels to the RGB colorspace. This function
18 ; reads YUV pixels from right to left, convert their colorspace to RGB, and
19 ; write the converted pixels to the output buffers. The following code snippet
20 ; represents the rough structure of this fucntion.
21 ;
22 ; if (width & 1) {
23 ; --width;
24 ; convert_one_pixel(y, u, v, rgba, width);
25 ; }
26 ; if (width & 2) {
27 ; width -= 2;
28 ; convert_two_pixels(y, u, v, rgba, width);
29 ; }
30 ; while (width) {
31 ; width -= 4;
32 ; convert_four_pixels(y, u, v, rgba, width);
33 ; }
34 ;
35 ; This function has pseudo-code snippets to describe its behaviors. For
36 ; simplicity, they use the following notations.
37 ;
38 ; #define Y(n) y[n] - 16
39 ; #define U(n) u[n] - 128
40 ; #define V(n) v[n] - 128
41 ; #define FIX(n) (n * (1 << SHIFT_BITS) * 0.5)
42 ; #define ToByte(n) ((n < 0) ? 0 : (n > 255 ? 255 : n))
43 ;
44 ; union {
45 ; int32 d[4];
46 ; int16 w[8];
47 ; int8 b[16];
48 ; } xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
49 ;
50 ; int ToByte(int n) {
51 ; if (n < 0) return n;
52 ; else if (n > 255) return 255;
53 ; return n;
54 ; }
55
56 ; Input Parameters
57 %ifdef __x86_64__
58 %ifdef WIN64
59 %define PARAM_Y(r) rcx
60 %define PARAM_U(r) rdx
61 %define PARAM_V(r) r8
62 %define PARAM_RGBA(r) r9
63 %define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2]
64 %else
65 %define PARAM_Y(r) rdi
66 %define PARAM_U(r) rsi
67 %define PARAM_V(r) rdx
68 %define PARAM_RGBA(r) rcx
69 %define PARAM_WIDTH(r) r8
70 %endif
71 %else
72 %define PARAM_Y(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 0]
73 %define PARAM_U(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 1]
74 %define PARAM_V(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 2]
75 %define PARAM_RGBA(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 3]
76 %define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 4]
77 %endif ; __x86_64__
78
79 ; Local variables used in this function.
80 %define INT_WIDTH32 eax
81 %define INT_WIDTH8 al
82
83 %define INT_PIXEL32 ebx
84 %define INT_PIXEL16 bx
85 %define INT_PIXEL8 bl
86
87 %ifdef __x86_64__
88 %define INT_WIDTH rax
89 %define INT_PIXEL rbx
90 %define PTR_Y PARAM_Y(_EBP_)
91 %define PTR_U PARAM_U(_EBP_)
92 %define PTR_V PARAM_V(_EBP_)
93 %define PTR_RGBA PARAM_RGBA(_EBP_)
94 %else
95 %define INT_WIDTH eax
96 %define INT_PIXEL ebx
97 %define PTR_RGBA ecx
98 %define PTR_Y edx
99 %define PTR_U esi
100 %define PTR_V edi
101 %endif
102
103 %define XMM_TABLE0 xmm7
104 %define XMM_TABLE1 xmm6
105 %define XMM_RGBA xmm5
106 %define XMM_ZERO xmm4
107
108 align 16
109 global EXTN(SYMBOL_NAME) PRIVATE
110
111 EXTN(SYMBOL_NAME):
112 push _EBP_
113 mov _EBP_, _ESP_
114
115 ; Save the resisters used in this function. We do not need to save eax, ecx,
116 ; or edx even though this function uses them. (Callers save them.)
117 push _EBX_
118 push _ESI_
119 push _EDI_
120
121 ; Copy the tables used in this function to xmm6 and xmm7.
122 lea _EAX_, [SIMD_ConvertYUVtoRGBA_kTable]
123 movdqa XMM_TABLE0, XMMWORD [_EAX_ + 0]
124 movdqa XMM_TABLE1, XMMWORD [_EAX_ + 16]
125
126 ; Copy the input parameters to registers. (We do not need to copy the input
127 ; pointers on x64 because x64 uses registers to provide the first five
128 ; parameters and we can use them.)
129 mov INT_WIDTH, PARAM_WIDTH(_EBP_)
130 %ifndef __x86_64__
131 mov PTR_RGBA, PARAM_RGBA(_EBP_)
132 mov PTR_Y, PARAM_Y(_EBP_)
133 mov PTR_U, PARAM_U(_EBP_)
134 mov PTR_V, PARAM_V(_EBP_)
135 %endif
136
137 .convert_one_pixel:
138 ; Divide the input width by 2 so it represents the offset for u or v. When
139 ; this width is odd, we read the rightmost Y pixel, U pixel, and V pixel to
140 ; convert its colorspace to RGB.
141 sar INT_WIDTH, 1
142 jnc .convert_two_pixels
143
144 movzx INT_PIXEL32, BYTE [PTR_Y + INT_WIDTH * 2]
145 movd xmm0, INT_PIXEL32
146 movzx INT_PIXEL32, BYTE [PTR_U + INT_WIDTH]
147 movd xmm1, INT_PIXEL32
148 movzx INT_PIXEL32, BYTE [PTR_V + INT_WIDTH]
149 movd xmm2, INT_PIXEL32
150
151 ; xmm0.w[0] = Y(0); xmm0.w[1] = U(0); xmm0.w[2] = V(0); xmm0.w[3] = FIX(0.5);
152 ; xmm0.w[4] = Y(1); xmm0.w[5] = U(0); xmm0.w[6] = V(0); xmm0.w[7] = FIX(0.5);
153 pxor XMM_ZERO, XMM_ZERO
154 punpcklbw xmm0, XMM_ZERO
155 punpcklwd xmm0, XMM_ZERO
156
157 punpcklbw xmm1, XMM_ZERO
158 punpcklwd xmm1, XMM_ZERO
159 pshufd xmm1, xmm1, 01010000B
160 pslld xmm1, 8
161 por xmm0, xmm1
162
163 punpcklbw xmm2, XMM_ZERO
164 punpcklwd xmm2, XMM_ZERO
165 pshufd xmm2, xmm2, 01010000B
166 pslld xmm2, 16
167 por xmm0, xmm2
168
169 punpcklbw xmm0, XMM_ZERO
170
171 pshufd xmm2, XMM_TABLE0, 01000100B
172 paddsw xmm0, xmm2
173
174 ; Set up the result pixels.
175 %if ALPHA == 0 || PIXELSIZE == 3
176 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0;
177 pxor XMM_RGBA, XMM_RGBA
178 %else
179 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0xFF000000;
180 pcmpeqd XMM_RGBA, XMM_RGBA
181 psrad XMM_RGBA, 24
182 pslld XMM_RGBA, 24
183 %endif
184
185 ; Calculate r[0].
186 ; xmm2.d[0] = FIX(1.164) * Y(0) + 0 * U(0);
187 ; xmm2.d[1] = FIX(1.596) * V(0) + FIX(0.5);
188 movdqa xmm2, xmm0
189 pshufd xmm3, XMM_TABLE0, 11101110B
190 pmaddwd xmm2, xmm3
191
192 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
193 pshufd xmm3, xmm2, 11011101B
194 pshufd xmm2, xmm2, 10001000B
195 paddd xmm2, xmm3
196 psrad xmm2, SHIFT_BITS
197
198 ; xmm5.b[02] = ToByte(xmm2.d[0]);
199 packssdw xmm2, xmm2
200 packuswb xmm2, xmm2
201 punpckhbw xmm2, XMM_ZERO
202 punpcklbw xmm2, XMM_ZERO
203 pslld xmm2, 16
204 por XMM_RGBA, xmm2
205
206 ; Calculate g[0].
207 ; xmm2.d[0] = FIX(1.164) * Y(0) + -FIX(0.391) * U(0);
208 ; xmm2.d[1] = -FIX(0.813) * V(0) + FIX(0.5);
209 movdqa xmm2, xmm0
210 pshufd xmm3, XMM_TABLE1, 01000100B
211 pmaddwd xmm2, xmm3
212
213 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
214 pshufd xmm3, xmm2, 11011101B
215 shufps xmm2, xmm2, 10001000B
216 paddd xmm2, xmm3
217 psrad xmm2, SHIFT_BITS
218
219 ; xmm5.b[01] = ToByte(xmm2.d[0]);
220 packssdw xmm2, xmm2
221 packuswb xmm2, xmm2
222 punpckhbw xmm2, XMM_ZERO
223 punpcklbw xmm2, XMM_ZERO
224 pslld xmm2, 8
225 por XMM_RGBA, xmm2
226
227 ; Calculate b[0].
228 ; xmm2.d[0] = FIX(1.164) * Y(0) + FIX(2.018) * U(0);
229 ; xmm2.d[1] = 0 * V(0) + FIX(0.5);
230 movdqa xmm2, xmm0
231 pshufd xmm3, XMM_TABLE1, 11101110B
232 pmaddwd xmm2, xmm3
233
234 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
235 pshufd xmm3, xmm2, 11011101B
236 shufps xmm2, xmm2, 10001000B
237 paddd xmm2, xmm3
238 psrad xmm2, SHIFT_BITS
239
240 ; xmm5.b[00] = ToByte(xmm2.d[0]);
241 packssdw xmm2, xmm2
242 packuswb xmm2, xmm2
243 punpckhbw xmm2, XMM_ZERO
244 punpcklbw xmm2, XMM_ZERO
245 por XMM_RGBA, xmm2
246
247 %if PIXELSIZE == 4
248 movd DWORD [PTR_RGBA + INT_WIDTH * 4 * 2], XMM_RGBA
249 %else
250 movd xmm0, INT_WIDTH32
251 lea INT_WIDTH, [INT_WIDTH + INT_WIDTH * 2]
252 movd INT_PIXEL32, XMM_RGBA
253 mov WORD [PTR_RGBA + INT_WIDTH * 2], INT_PIXEL16
254 sar INT_PIXEL32, 16
255 mov BYTE [PTR_RGBA + INT_WIDTH * 2 + 2], INT_PIXEL8
256 movd INT_WIDTH32, xmm0
257 %endif
258
259 .convert_two_pixels:
260 ; When the input width is not a multiple of four, we read the rightmost two Y
261 ; pixels, one U pixel, and one V pixel to convert their colorspace to RGB.
262 ; This code stores two RGBA pixels.
263 test INT_WIDTH8, 1
264 jz .convert_four_pixels
265 sub INT_WIDTH8, 2 / 2
266
267 movzx INT_PIXEL32, WORD [PTR_Y + INT_WIDTH * 2]
268 movd xmm0, INT_PIXEL32
269 movzx INT_PIXEL32, BYTE [PTR_U + INT_WIDTH]
270 movd xmm1, INT_PIXEL32
271 movzx INT_PIXEL32, BYTE [PTR_V + INT_WIDTH]
272 movd xmm2, INT_PIXEL32
273
274 ; xmm0.w[0] = Y(0); xmm0.w[1] = U(0); xmm0.w[2] = V(0); xmm0.w[3] = FIX(0.5);
275 ; xmm0.w[4] = Y(1); xmm0.w[5] = U(0); xmm0.w[6] = V(0); xmm0.w[7] = FIX(0.5);
276 pxor XMM_ZERO, XMM_ZERO
277 punpcklbw xmm0, XMM_ZERO
278 punpcklwd xmm0, XMM_ZERO
279
280 punpcklbw xmm1, XMM_ZERO
281 punpcklwd xmm1, XMM_ZERO
282 pshufd xmm1, xmm1, 01010000B
283 pslld xmm1, 8
284 por xmm0, xmm1
285
286 punpcklbw xmm2, XMM_ZERO
287 punpcklwd xmm2, XMM_ZERO
288 pshufd xmm2, xmm2, 01010000B
289 pslld xmm2, 16
290 por xmm0, xmm2
291
292 punpcklbw xmm0, XMM_ZERO
293
294 pshufd xmm2, XMM_TABLE0, 01000100B
295 paddsw xmm0, xmm2
296
297 ; Set up the result pixels.
298 %if ALPHA == 0 || PIXELSIZE == 3
299 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0;
300 pxor XMM_RGBA, XMM_RGBA
301 %else
302 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0xFF000000;
303 pcmpeqd XMM_RGBA, XMM_RGBA
304 psrad XMM_RGBA, 24
305 pslld XMM_RGBA, 24
306 %endif
307
308 ; Calculate r[0] and r[1].
309 ; xmm2.d[0] = FIX(1.164) * Y(0) + 0 * U(0);
310 ; xmm2.d[1] = FIX(1.596) * V(0) + FIX(0.5);
311 ; xmm2.d[2] = FIX(1.164) * Y(1) + 0 * U(0);
312 ; xmm2.d[3] = FIX(1.596) * V(0) + FIX(0.5);
313 movdqa xmm2, xmm0
314 pshufd xmm3, XMM_TABLE0, 11101110B
315 pmaddwd xmm2, xmm3
fbarchard 2011/06/10 17:29:45 would it make sense to do a pmaddubsw version? Us
316
317 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
318 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
319 pshufd xmm3, xmm2, 11011101B
320 pshufd xmm2, xmm2, 10001000B
321 paddd xmm2, xmm3
322 psrad xmm2, SHIFT_BITS
323
324 ; xmm5.b[02] = ToByte(xmm2.d[0]); xmm5.b[06] = ToByte(xmm2.d[1]);
325 packssdw xmm2, xmm2
326 packuswb xmm2, xmm2
327 punpckhbw xmm2, XMM_ZERO
328 punpcklbw xmm2, XMM_ZERO
329 pslld xmm2, 16
330 por XMM_RGBA, xmm2
331
332 ; Calculate g[0] and g[1].
333 ; xmm2.d[0] = FIX(1.164) * Y(0) + -FIX(0.391) * U(0);
334 ; xmm2.d[1] = -FIX(0.813) * V(0) + FIX(0.5);
335 ; xmm2.d[2] = FIX(1.164) * Y(1) + -FIX(0.391) * U(0);
336 ; xmm2.d[3] = -FIX(0.813) * V(0) + FIX(0.5);
337 movdqa xmm2, xmm0
338 pshufd xmm3, XMM_TABLE1, 01000100B
339 pmaddwd xmm2, xmm3
340
341 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
342 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
343 pshufd xmm3, xmm2, 11011101B
344 shufps xmm2, xmm2, 10001000B
345 paddd xmm2, xmm3
346 psrad xmm2, SHIFT_BITS
347
348 ; xmm5.b[01] = ToByte(xmm2.d[0]); xmm5.b[05] = ToByte(xmm2.d[1]);
349 packssdw xmm2, xmm2
350 packuswb xmm2, xmm2
351 punpckhbw xmm2, XMM_ZERO
352 punpcklbw xmm2, XMM_ZERO
353 pslld xmm2, 8
354 por XMM_RGBA, xmm2
355
356 ; Calculate b[0] and b[1].
357 ; xmm2.d[0] = FIX(1.164) * Y(0) + FIX(2.018) * U(0);
358 ; xmm2.d[1] = FIX(0.000) * V(0) + FIX(0.5);
359 ; xmm2.d[2] = FIX(1.164) * Y(1) + FIX(2.018) * U(0);
360 ; xmm2.d[3] = FIX(0.000) * V(0) + FIX(0.5);
361 movdqa xmm2, xmm0
362 pshufd xmm3, XMM_TABLE1, 11101110B
363 pmaddwd xmm2, xmm3
364
365 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
366 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
367 pshufd xmm3, xmm2, 11011101B
368 shufps xmm2, xmm2, 10001000B
369 paddd xmm2, xmm3
370 psrad xmm2, SHIFT_BITS
371
372 ; xmm5.b[00] = ToByte(xmm2.d[0]); xmm5.b[04] = ToByte(xmm2.d[1]);
373 packssdw xmm2, xmm2
374 packuswb xmm2, xmm2
375 punpckhbw xmm2, XMM_ZERO
376 punpcklbw xmm2, XMM_ZERO
377 por XMM_RGBA, xmm2
378
379 %if PIXELSIZE == 3
380 ; Pack two RGBA pixels to two RGB pixels.
381 movdqa xmm0, XMM_RGBA
382 psrldq xmm0, 4
383 pslldq xmm0, 4
384 pxor XMM_RGBA, xmm0
385
386 psrldq xmm0, 1
387 por XMM_RGBA, xmm0
388 %endif
389
390 %if PIXELSIZE == 4
391 movq MMWORD [PTR_RGBA + INT_WIDTH * 4 * 2], XMM_RGBA
392 %else
393 movd xmm0, INT_WIDTH
394 lea INT_WIDTH, [INT_WIDTH + INT_WIDTH * 2]
395 movd DWORD [PTR_RGBA + INT_WIDTH * 2], XMM_RGBA
396 psrldq XMM_RGBA, 4
397 movd INT_PIXEL32, XMM_RGBA
398 mov WORD [PTR_RGBA + INT_WIDTH * 2 + 4], INT_PIXEL16
399 movd INT_WIDTH, xmm0
400 %endif
401
402 .convert_four_pixels:
403 ; Read four Y pixels, two U pixels, and two V pixels to convert their
404 ; colorspace to RGB. This code stores four RGBA (or RGB) pixels.
405 test INT_WIDTH32, INT_WIDTH32
406 jz .convert_finish
407 sub INT_WIDTH32, 4 / 2
408
409 movd xmm0, DWORD [PTR_Y + INT_WIDTH * 2]
410 movzx INT_PIXEL32, WORD [PTR_U + INT_WIDTH]
411 movd xmm1, INT_PIXEL32
412 movzx INT_PIXEL32, WORD [PTR_V + INT_WIDTH]
413 movd xmm2, INT_PIXEL32
414
415 ; xmm0.w[0] = Y(0); xmm0.w[1] = U(0); xmm0.w[2] = V(0); xmm0.w[3] = FIX(0.5);
416 ; xmm0.w[4] = Y(1); xmm0.w[5] = U(0); xmm0.w[6] = V(0); xmm0.w[7] = FIX(0.5);
417 ; xmm1.w[0] = Y(2); xmm1.w[1] = U(1); xmm1.w[2] = V(1); xmm1.w[3] = FIX(0.5);
418 ; xmm1.w[4] = Y(3); xmm1.w[5] = U(1); xmm1.w[6] = V(1); xmm1.w[7] = FIX(0.5);
419 pxor XMM_ZERO, XMM_ZERO
420 punpcklbw xmm0, XMM_ZERO
421 punpcklwd xmm0, XMM_ZERO
422
423 punpcklbw xmm1, XMM_ZERO
424 punpcklwd xmm1, XMM_ZERO
425 pshufd xmm1, xmm1, 01010000B
426 pslld xmm1, 8
427 por xmm0, xmm1
428
429 punpcklbw xmm2, XMM_ZERO
430 punpcklwd xmm2, XMM_ZERO
431 pshufd xmm2, xmm2, 01010000B
432 pslld xmm2, 16
433 por xmm0, xmm2
434
435 movdqa xmm1, xmm0
436 punpckhbw xmm1, XMM_ZERO
437 punpcklbw xmm0, XMM_ZERO
438
439 pshufd xmm2, XMM_TABLE0, 01000100B
440 paddsw xmm0, xmm2
441 paddsw xmm1, xmm2
442
443 ; Set up the result pixels.
444 %if ALPHA == 0 || PIXELSIZE == 3
445 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0;
446 pxor XMM_RGBA, XMM_RGBA
447 %else
448 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0xFF000000;
449 pcmpeqd XMM_RGBA, XMM_RGBA
450 psrad XMM_RGBA, 24
451 pslld XMM_RGBA, 24
452 %endif
453
454 ; Calculate r[0], r[1], r[2], and r[3].
455 ; xmm2.d[0] = FIX(1.164) * Y(0) + 0 * U(0);
456 ; xmm2.d[1] = FIX(1.596) * V(0) + FIX(0.5);
457 ; xmm2.d[2] = FIX(1.164) * Y(1) + 0 * U(0);
458 ; xmm2.d[3] = FIX(1.596) * V(0) + FIX(0.5);
459 ; xmm3.d[0] = FIX(1.164) * Y(2) + 0 * U(0);
460 ; xmm3.d[1] = FIX(1.596) * V(1) + FIX(0.5);
461 ; xmm3.d[2] = FIX(1.164) * Y(2) + 0 * U(0);
462 ; xmm3.d[3] = FIX(1.596) * V(1) + FIX(0.5);
463 movdqa xmm2, xmm0
464 movdqa xmm3, xmm1
465 pshufd xmm4, XMM_TABLE0, 11101110B
466 pmaddwd xmm2, xmm4
467 pmaddwd xmm3, xmm4
468
469 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
470 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
471 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1]) / FIX(1);
472 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3]) / FIX(1);
473 movdqa xmm4, xmm2
474 shufps xmm4, xmm3, 10001000B
475 shufps xmm2, xmm3, 11011101B
476 paddd xmm2, xmm4
477 psrad xmm2, SHIFT_BITS
478
479 ; xmm5.b[02] = ToByte(xmm2.d[0]); xmm5.b[06] = ToByte(xmm2.d[1]);
480 ; xmm5.b[10] = ToByte(xmm2.d[2]); xmm5.b[14] = ToByte(xmm2.d[3]);
481 packssdw xmm2, xmm2
482 packuswb xmm2, xmm2
483 pxor XMM_ZERO, XMM_ZERO
484 punpckhbw xmm2, XMM_ZERO
485 punpcklbw xmm2, XMM_ZERO
486 pslld xmm2, 16
487 por XMM_RGBA, xmm2
488
489 ; Calculate g[0], g[1], g[2], and g[3].
490 ; xmm2.d[0] = FIX(1.164) * Y(0) + -FIX(0.391) * U(0);
491 ; xmm2.d[1] = -FIX(0.813) * V(0) + FIX(0.5);
492 ; xmm2.d[2] = FIX(1.164) * Y(1) + -FIX(0.391) * U(0);
493 ; xmm2.d[3] = -FIX(0.813) * V(0) + FIX(0.5);
494 ; xmm3.d[0] = FIX(1.164) * Y(2) + -FIX(0.391) * U(0);
495 ; xmm3.d[1] = -FIX(0.813) * V(1) + FIX(0.5);
496 ; xmm3.d[2] = FIX(1.164) * Y(2) + -FIX(0.391) * U(0);
497 ; xmm3.d[3] = -FIX(0.813) * V(1) + FIX(0.5);
498 movdqa xmm2, xmm0
499 movdqa xmm3, xmm1
500 pshufd xmm4, XMM_TABLE1, 01000100B
501 pmaddwd xmm2, xmm4
502 pmaddwd xmm3, xmm4
503
504 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
505 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
506 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1]) / FIX(1);
507 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3]) / FIX(1);
508 movdqa xmm4, xmm2
509 shufps xmm4, xmm3, 10001000B
510 shufps xmm2, xmm3, 11011101B
511 paddd xmm2, xmm4
512 psrad xmm2, SHIFT_BITS
513
514 ; xmm5.b[01] = ToByte(xmm2.d[0]); xmm5.b[05] = ToByte(xmm2.d[1]);
515 ; xmm5.b[09] = ToByte(xmm2.d[2]); xmm5.b[13] = ToByte(xmm2.d[3]);
516 packssdw xmm2, xmm2
517 packuswb xmm2, xmm2
518 pxor XMM_ZERO, XMM_ZERO
519 punpckhbw xmm2, XMM_ZERO
520 punpcklbw xmm2, XMM_ZERO
521 pslld xmm2, 8
522 por XMM_RGBA, xmm2
523
524 ; Calculate b[0], b[1], b[2], and b[3].
525 ; xmm2.d[0] = FIX(1.164) * Y(0) + FIX(2.018) * U(0);
526 ; xmm2.d[1] = FIX(0.000) * V(0) + FIX(0.5);
527 ; xmm2.d[2] = FIX(1.164) * Y(1) + FIX(2.018) * U(0);
528 ; xmm2.d[3] = FIX(0.000) * V(0) + FIX(0.5);
529 ; xmm3.d[0] = FIX(1.164) * Y(2) + FIX(2.018) * U(0);
530 ; xmm3.d[1] = FIX(0.000) * V(1) + FIX(0.5);
531 ; xmm3.d[2] = FIX(1.164) * Y(2) + FIX(2.018) * U(0);
532 ; xmm3.d[3] = FIX(0.000) * V(1) + FIX(0.5);
533 movdqa xmm2, xmm0
534 movdqa xmm3, xmm1
535 pshufd xmm4, XMM_TABLE1, 11101110B
536 pmaddwd xmm2, xmm4
537 pmaddwd xmm3, xmm4
538
539 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
540 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
541 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1]) / FIX(1);
542 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3]) / FIX(1);
543 movdqa xmm4, xmm2
544 shufps xmm4, xmm3, 10001000B
545 shufps xmm2, xmm3, 11011101B
546 paddd xmm2, xmm4
547 psrad xmm2, SHIFT_BITS
548
549 ; xmm5.b[00] = ToByte(xmm2.d[0]); xmm5.b[04] = ToByte(xmm2.d[1]);
550 ; xmm5.b[08] = ToByte(xmm2.d[2]); xmm5.b[12] = ToByte(xmm2.d[3]);
551 packssdw xmm2, xmm2
552 packuswb xmm2, xmm2
553 pxor XMM_ZERO, XMM_ZERO
554 punpckhbw xmm2, XMM_ZERO
555 punpcklbw xmm2, XMM_ZERO
556 por XMM_RGBA, xmm2
557
558 %if PIXELSIZE == 3
559 ; Pack four RGBA pixels to four RGB pixels.
560 movdqa xmm0, XMM_RGBA
561 psrldq xmm0, 4
562 pslldq xmm0, 4
563 movdqa xmm1, XMM_RGBA
564 psrldq xmm1, 8
565 pslldq xmm1, 8
566 movdqa xmm2, XMM_RGBA
567 psrldq xmm2, 12
568 pslldq xmm2, 12
569
570 pxor XMM_RGBA, xmm0
571 pxor xmm0, xmm1
572 pxor xmm1, xmm2
573
574 psrldq xmm0, 1
575 por XMM_RGBA, xmm0
576 psrldq xmm1, 2
577 por XMM_RGBA, xmm1
578 psrldq xmm2, 3
579 por XMM_RGBA, xmm2
580 %endif
581
582 %if PIXELSIZE == 4
583 movdqu XMMWORD [PTR_RGBA + INT_WIDTH * 4 * 2], XMM_RGBA
584 %else
585 mov _EBX_, INT_WIDTH
586 lea _EBX_, [_EBX_ + _EBX_ * 2]
587 movq MMWORD [PTR_RGBA + _EBX_ * 2], XMM_RGBA
588 psrldq XMM_RGBA, 8
589 movd DWORD [PTR_RGBA + _EBX_ * 2 + 8], XMM_RGBA
590 %endif
591 jmp .convert_four_pixels
fbarchard 2011/06/10 17:29:45 more efficient to put conditional loop at bottom.
592
593 .convert_finish:
594 ; Restore the registers used in this function, the stack frame, and the stack
595 ; pointer.
596 pop _EDI_
597 pop _ESI_
598 pop _EBX_
599
600 mov _ESP_, _EBP_
601 pop _EBP_
602
603 ret
604
605 ; For some reason, the OS X linker does not honor the request to align the
606 ; segment unless we do this.
607 align 16
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698