gallivm: Remove unnecessary headers.
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_format_yuv.c
1 /**************************************************************************
2 *
3 * Copyright 2010 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28
29 /**
30 * @file
31 * YUV pixel format manipulation.
32 *
33 * @author Jose Fonseca <jfonseca@vmware.com>
34 */
35
36
37 #include "util/u_format.h"
38
39 #include "lp_bld_arit.h"
40 #include "lp_bld_type.h"
41 #include "lp_bld_const.h"
42 #include "lp_bld_conv.h"
43 #include "lp_bld_gather.h"
44 #include "lp_bld_format.h"
45
46
47 /**
48 * Extract Y, U, V channels from packed UYVY.
49 * @param packed is a <n x i32> vector with the packed UYVY blocks
50 * @param i is a <n x i32> vector with the x pixel coordinate (0 or 1)
51 */
52 static void
53 uyvy_to_yuv_soa(LLVMBuilderRef builder,
54 unsigned n,
55 LLVMValueRef packed,
56 LLVMValueRef i,
57 LLVMValueRef *y,
58 LLVMValueRef *u,
59 LLVMValueRef *v)
60 {
61 struct lp_type type;
62 LLVMValueRef shift, mask;
63
64 memset(&type, 0, sizeof type);
65 type.width = 32;
66 type.length = n;
67
68 assert(lp_check_value(type, packed));
69 assert(lp_check_value(type, i));
70
71 /*
72 * y = (uyvy >> 16*i) & 0xff
73 * u = (uyvy ) & 0xff
74 * v = (uyvy >> 16 ) & 0xff
75 */
76
77 shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), "");
78 shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(type, 8), "");
79 *y = LLVMBuildLShr(builder, packed, shift, "");
80 *u = packed;
81 *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 16), "");
82
83 mask = lp_build_const_int_vec(type, 0xff);
84
85 *y = LLVMBuildAnd(builder, *y, mask, "y");
86 *u = LLVMBuildAnd(builder, *u, mask, "u");
87 *v = LLVMBuildAnd(builder, *v, mask, "v");
88 }
89
90
91 /**
92 * Extract Y, U, V channels from packed YUYV.
93 * @param packed is a <n x i32> vector with the packed YUYV blocks
94 * @param i is a <n x i32> vector with the x pixel coordinate (0 or 1)
95 */
96 static void
97 yuyv_to_yuv_soa(LLVMBuilderRef builder,
98 unsigned n,
99 LLVMValueRef packed,
100 LLVMValueRef i,
101 LLVMValueRef *y,
102 LLVMValueRef *u,
103 LLVMValueRef *v)
104 {
105 struct lp_type type;
106 LLVMValueRef shift, mask;
107
108 memset(&type, 0, sizeof type);
109 type.width = 32;
110 type.length = n;
111
112 assert(lp_check_value(type, packed));
113 assert(lp_check_value(type, i));
114
115 /*
116 * y = (yuyv >> 16*i) & 0xff
117 * u = (yuyv >> 8 ) & 0xff
118 * v = (yuyv >> 24 ) & 0xff
119 */
120
121 shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), "");
122 *y = LLVMBuildLShr(builder, packed, shift, "");
123 *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 8), "");
124 *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 24), "");
125
126 mask = lp_build_const_int_vec(type, 0xff);
127
128 *y = LLVMBuildAnd(builder, *y, mask, "y");
129 *u = LLVMBuildAnd(builder, *u, mask, "u");
130 *v = LLVMBuildAnd(builder, *v, mask, "v");
131 }
132
133
134 static INLINE void
135 yuv_to_rgb_soa(LLVMBuilderRef builder,
136 unsigned n,
137 LLVMValueRef y, LLVMValueRef u, LLVMValueRef v,
138 LLVMValueRef *r, LLVMValueRef *g, LLVMValueRef *b)
139 {
140 struct lp_type type;
141 struct lp_build_context bld;
142
143 LLVMValueRef c0;
144 LLVMValueRef c8;
145 LLVMValueRef c16;
146 LLVMValueRef c128;
147 LLVMValueRef c255;
148
149 LLVMValueRef cy;
150 LLVMValueRef cug;
151 LLVMValueRef cub;
152 LLVMValueRef cvr;
153 LLVMValueRef cvg;
154
155 memset(&type, 0, sizeof type);
156 type.sign = TRUE;
157 type.width = 32;
158 type.length = n;
159
160 lp_build_context_init(&bld, builder, type);
161
162 assert(lp_check_value(type, y));
163 assert(lp_check_value(type, u));
164 assert(lp_check_value(type, v));
165
166 /*
167 * Constants
168 */
169
170 c0 = lp_build_const_int_vec(type, 0);
171 c8 = lp_build_const_int_vec(type, 8);
172 c16 = lp_build_const_int_vec(type, 16);
173 c128 = lp_build_const_int_vec(type, 128);
174 c255 = lp_build_const_int_vec(type, 255);
175
176 cy = lp_build_const_int_vec(type, 298);
177 cug = lp_build_const_int_vec(type, -100);
178 cub = lp_build_const_int_vec(type, 516);
179 cvr = lp_build_const_int_vec(type, 409);
180 cvg = lp_build_const_int_vec(type, -208);
181
182 /*
183 * y -= 16;
184 * u -= 128;
185 * v -= 128;
186 */
187
188 y = LLVMBuildSub(builder, y, c16, "");
189 u = LLVMBuildSub(builder, u, c128, "");
190 v = LLVMBuildSub(builder, v, c128, "");
191
192 /*
193 * r = 298 * _y + 409 * _v + 128;
194 * g = 298 * _y - 100 * _u - 208 * _v + 128;
195 * b = 298 * _y + 516 * _u + 128;
196 */
197
198 y = LLVMBuildMul(builder, y, cy, "");
199 y = LLVMBuildAdd(builder, y, c128, "");
200
201 *r = LLVMBuildMul(builder, v, cvr, "");
202 *g = LLVMBuildAdd(builder,
203 LLVMBuildMul(builder, u, cug, ""),
204 LLVMBuildMul(builder, v, cvg, ""),
205 "");
206 *b = LLVMBuildMul(builder, u, cub, "");
207
208 *r = LLVMBuildAdd(builder, *r, y, "");
209 *g = LLVMBuildAdd(builder, *g, y, "");
210 *b = LLVMBuildAdd(builder, *b, y, "");
211
212 /*
213 * r >>= 8;
214 * g >>= 8;
215 * b >>= 8;
216 */
217
218 *r = LLVMBuildAShr(builder, *r, c8, "r");
219 *g = LLVMBuildAShr(builder, *g, c8, "g");
220 *b = LLVMBuildAShr(builder, *b, c8, "b");
221
222 /*
223 * Clamp
224 */
225
226 *r = lp_build_clamp(&bld, *r, c0, c255);
227 *g = lp_build_clamp(&bld, *g, c0, c255);
228 *b = lp_build_clamp(&bld, *b, c0, c255);
229 }
230
231
232 static LLVMValueRef
233 rgb_to_rgba_aos(LLVMBuilderRef builder,
234 unsigned n,
235 LLVMValueRef r, LLVMValueRef g, LLVMValueRef b)
236 {
237 struct lp_type type;
238 LLVMValueRef a;
239 LLVMValueRef rgba;
240
241 memset(&type, 0, sizeof type);
242 type.sign = TRUE;
243 type.width = 32;
244 type.length = n;
245
246 assert(lp_check_value(type, r));
247 assert(lp_check_value(type, g));
248 assert(lp_check_value(type, b));
249
250 /*
251 * Make a 4 x unorm8 vector
252 */
253
254 r = r;
255 g = LLVMBuildShl(builder, g, lp_build_const_int_vec(type, 8), "");
256 b = LLVMBuildShl(builder, b, lp_build_const_int_vec(type, 16), "");
257 a = lp_build_const_int_vec(type, 0xff000000);
258
259 rgba = r;
260 rgba = LLVMBuildOr(builder, rgba, g, "");
261 rgba = LLVMBuildOr(builder, rgba, b, "");
262 rgba = LLVMBuildOr(builder, rgba, a, "");
263
264 rgba = LLVMBuildBitCast(builder, rgba,
265 LLVMVectorType(LLVMInt8Type(), 4*n), "");
266
267 return rgba;
268 }
269
270
271 /**
272 * Convert from <n x i32> packed UYVY to <4n x i8> RGBA AoS
273 */
274 static LLVMValueRef
275 uyvy_to_rgba_aos(LLVMBuilderRef builder,
276 unsigned n,
277 LLVMValueRef packed,
278 LLVMValueRef i)
279 {
280 LLVMValueRef y, u, v;
281 LLVMValueRef r, g, b;
282 LLVMValueRef rgba;
283
284 uyvy_to_yuv_soa(builder, n, packed, i, &y, &u, &v);
285 yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b);
286 rgba = rgb_to_rgba_aos(builder, n, r, g, b);
287
288 return rgba;
289 }
290
291
292 /**
293 * Convert from <n x i32> packed YUYV to <4n x i8> RGBA AoS
294 */
295 static LLVMValueRef
296 yuyv_to_rgba_aos(LLVMBuilderRef builder,
297 unsigned n,
298 LLVMValueRef packed,
299 LLVMValueRef i)
300 {
301 LLVMValueRef y, u, v;
302 LLVMValueRef r, g, b;
303 LLVMValueRef rgba;
304
305 yuyv_to_yuv_soa(builder, n, packed, i, &y, &u, &v);
306 yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b);
307 rgba = rgb_to_rgba_aos(builder, n, r, g, b);
308
309 return rgba;
310 }
311
312
313 /**
314 * Convert from <n x i32> packed RG_BG to <4n x i8> RGBA AoS
315 */
316 static LLVMValueRef
317 rgbg_to_rgba_aos(LLVMBuilderRef builder,
318 unsigned n,
319 LLVMValueRef packed,
320 LLVMValueRef i)
321 {
322 LLVMValueRef r, g, b;
323 LLVMValueRef rgba;
324
325 uyvy_to_yuv_soa(builder, n, packed, i, &g, &r, &b);
326 rgba = rgb_to_rgba_aos(builder, n, r, g, b);
327
328 return rgba;
329 }
330
331
332 /**
333 * Convert from <n x i32> packed GR_GB to <4n x i8> RGBA AoS
334 */
335 static LLVMValueRef
336 grgb_to_rgba_aos(LLVMBuilderRef builder,
337 unsigned n,
338 LLVMValueRef packed,
339 LLVMValueRef i)
340 {
341 LLVMValueRef r, g, b;
342 LLVMValueRef rgba;
343
344 yuyv_to_yuv_soa(builder, n, packed, i, &g, &r, &b);
345 rgba = rgb_to_rgba_aos(builder, n, r, g, b);
346
347 return rgba;
348 }
349
350
351 /**
352 * @param n is the number of pixels processed
353 * @param packed is a <n x i32> vector with the packed YUYV blocks
354 * @param i is a <n x i32> vector with the x pixel coordinate (0 or 1)
355 * @return a <4*n x i8> vector with the pixel RGBA values in AoS
356 */
357 LLVMValueRef
358 lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder,
359 const struct util_format_description *format_desc,
360 unsigned n,
361 LLVMValueRef base_ptr,
362 LLVMValueRef offset,
363 LLVMValueRef i,
364 LLVMValueRef j)
365 {
366 LLVMValueRef packed;
367 LLVMValueRef rgba;
368
369 assert(format_desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED);
370 assert(format_desc->block.bits == 32);
371 assert(format_desc->block.width == 2);
372 assert(format_desc->block.height == 1);
373
374 packed = lp_build_gather(builder, n, 32, 32, base_ptr, offset);
375
376 (void)j;
377
378 switch (format_desc->format) {
379 case PIPE_FORMAT_UYVY:
380 rgba = uyvy_to_rgba_aos(builder, n, packed, i);
381 break;
382 case PIPE_FORMAT_YUYV:
383 rgba = yuyv_to_rgba_aos(builder, n, packed, i);
384 break;
385 case PIPE_FORMAT_R8G8_B8G8_UNORM:
386 rgba = rgbg_to_rgba_aos(builder, n, packed, i);
387 break;
388 case PIPE_FORMAT_G8R8_G8B8_UNORM:
389 rgba = grgb_to_rgba_aos(builder, n, packed, i);
390 break;
391 default:
392 assert(0);
393 rgba = LLVMGetUndef(LLVMVectorType(LLVMInt8Type(), 4*n));
394 break;
395 }
396
397 return rgba;
398 }
399