util/u_format: move utility function from r600g
[mesa.git] / src / gallium / auxiliary / util / u_format.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 above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * @file
30 * Pixel format accessor functions.
31 *
32 * @author Jose Fonseca <jfonseca@vmware.com>
33 */
34
35 #include "u_math.h"
36 #include "u_memory.h"
37 #include "u_format.h"
38 #include "u_format_s3tc.h"
39 #include "u_surface.h"
40
41 #include "pipe/p_defines.h"
42
43
44 boolean
45 util_format_is_float(enum pipe_format format)
46 {
47 const struct util_format_description *desc = util_format_description(format);
48 unsigned i;
49
50 assert(desc);
51 if (!desc) {
52 return FALSE;
53 }
54
55 i = util_format_get_first_non_void_channel(format);
56 if (i == -1) {
57 return FALSE;
58 }
59
60 return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE;
61 }
62
63
64 /** Test if the format contains RGB, but not alpha */
65 boolean
66 util_format_has_alpha(enum pipe_format format)
67 {
68 const struct util_format_description *desc =
69 util_format_description(format);
70
71 return (desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
72 desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
73 desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1;
74 }
75
76
77 boolean
78 util_format_is_luminance(enum pipe_format format)
79 {
80 const struct util_format_description *desc =
81 util_format_description(format);
82
83 if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
84 desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
85 desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
86 desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
87 desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X &&
88 desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_1) {
89 return TRUE;
90 }
91 return FALSE;
92 }
93
94 boolean
95 util_format_is_pure_integer(enum pipe_format format)
96 {
97 const struct util_format_description *desc = util_format_description(format);
98 int i;
99
100 /* Find the first non-void channel. */
101 i = util_format_get_first_non_void_channel(format);
102 if (i == -1)
103 return FALSE;
104
105 return desc->channel[i].pure_integer ? TRUE : FALSE;
106 }
107
108 boolean
109 util_format_is_pure_sint(enum pipe_format format)
110 {
111 const struct util_format_description *desc = util_format_description(format);
112 int i;
113
114 i = util_format_get_first_non_void_channel(format);
115 if (i == -1)
116 return FALSE;
117
118 return (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED && desc->channel[i].pure_integer) ? TRUE : FALSE;
119 }
120
121 boolean
122 util_format_is_pure_uint(enum pipe_format format)
123 {
124 const struct util_format_description *desc = util_format_description(format);
125 int i;
126
127 i = util_format_get_first_non_void_channel(format);
128 if (i == -1)
129 return FALSE;
130
131 return (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED && desc->channel[i].pure_integer) ? TRUE : FALSE;
132 }
133
134 /**
135 * Returns true if all non-void channels are normalized signed.
136 */
137 boolean
138 util_format_is_snorm(enum pipe_format format)
139 {
140 const struct util_format_description *desc = util_format_description(format);
141 int i;
142
143 if (desc->is_mixed)
144 return FALSE;
145
146 i = util_format_get_first_non_void_channel(format);
147 if (i == -1)
148 return FALSE;
149
150 return desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED &&
151 !desc->channel[i].pure_integer &&
152 desc->channel[i].normalized;
153 }
154
155 boolean
156 util_format_is_luminance_alpha(enum pipe_format format)
157 {
158 const struct util_format_description *desc =
159 util_format_description(format);
160
161 if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
162 desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
163 desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
164 desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
165 desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X &&
166 desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_Y) {
167 return TRUE;
168 }
169 return FALSE;
170 }
171
172
173 boolean
174 util_format_is_intensity(enum pipe_format format)
175 {
176 const struct util_format_description *desc =
177 util_format_description(format);
178
179 if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
180 desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
181 desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
182 desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
183 desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X &&
184 desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) {
185 return TRUE;
186 }
187 return FALSE;
188 }
189
190 boolean
191 util_format_is_subsampled_422(enum pipe_format format)
192 {
193 const struct util_format_description *desc =
194 util_format_description(format);
195
196 return desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED &&
197 desc->block.width == 2 &&
198 desc->block.height == 1 &&
199 desc->block.bits == 32;
200 }
201
202 boolean
203 util_format_is_supported(enum pipe_format format, unsigned bind)
204 {
205 if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) {
206 return FALSE;
207 }
208
209 #ifndef TEXTURE_FLOAT_ENABLED
210 if ((bind & PIPE_BIND_RENDER_TARGET) &&
211 format != PIPE_FORMAT_R9G9B9E5_FLOAT &&
212 format != PIPE_FORMAT_R11G11B10_FLOAT &&
213 util_format_is_float(format)) {
214 return FALSE;
215 }
216 #endif
217
218 return TRUE;
219 }
220
221
222 /**
223 * Calculates the MRD for the depth format. MRD is used in depth bias
224 * for UNORM and unbound depth buffers. When the depth buffer is floating
225 * point, the depth bias calculation does not use the MRD. However, the
226 * default MRD will be 1.0 / ((1 << 24) - 1).
227 */
228 double
229 util_get_depth_format_mrd(const struct util_format_description *desc)
230 {
231 /*
232 * Depth buffer formats without a depth component OR scenarios
233 * without a bound depth buffer default to D24.
234 */
235 double mrd = 1.0 / ((1 << 24) - 1);
236 unsigned depth_channel;
237
238 assert(desc);
239
240 /*
241 * Some depth formats do not store the depth component in the first
242 * channel, detect the format and adjust the depth channel. Get the
243 * swizzled depth component channel.
244 */
245 depth_channel = desc->swizzle[0];
246
247 if (desc->channel[depth_channel].type == UTIL_FORMAT_TYPE_UNSIGNED &&
248 desc->channel[depth_channel].normalized) {
249 int depth_bits;
250
251 depth_bits = desc->channel[depth_channel].size;
252 mrd = 1.0 / ((1ULL << depth_bits) - 1);
253 }
254
255 return mrd;
256 }
257
258
259 void
260 util_format_read_4f(enum pipe_format format,
261 float *dst, unsigned dst_stride,
262 const void *src, unsigned src_stride,
263 unsigned x, unsigned y, unsigned w, unsigned h)
264 {
265 const struct util_format_description *format_desc;
266 const uint8_t *src_row;
267 float *dst_row;
268
269 format_desc = util_format_description(format);
270
271 assert(x % format_desc->block.width == 0);
272 assert(y % format_desc->block.height == 0);
273
274 src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
275 dst_row = dst;
276
277 format_desc->unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h);
278 }
279
280
281 void
282 util_format_write_4f(enum pipe_format format,
283 const float *src, unsigned src_stride,
284 void *dst, unsigned dst_stride,
285 unsigned x, unsigned y, unsigned w, unsigned h)
286 {
287 const struct util_format_description *format_desc;
288 uint8_t *dst_row;
289 const float *src_row;
290
291 format_desc = util_format_description(format);
292
293 assert(x % format_desc->block.width == 0);
294 assert(y % format_desc->block.height == 0);
295
296 dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
297 src_row = src;
298
299 format_desc->pack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h);
300 }
301
302
303 void
304 util_format_read_4ub(enum pipe_format format, uint8_t *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)
305 {
306 const struct util_format_description *format_desc;
307 const uint8_t *src_row;
308 uint8_t *dst_row;
309
310 format_desc = util_format_description(format);
311
312 assert(x % format_desc->block.width == 0);
313 assert(y % format_desc->block.height == 0);
314
315 src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
316 dst_row = dst;
317
318 format_desc->unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h);
319 }
320
321
322 void
323 util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)
324 {
325 const struct util_format_description *format_desc;
326 uint8_t *dst_row;
327 const uint8_t *src_row;
328
329 format_desc = util_format_description(format);
330
331 assert(x % format_desc->block.width == 0);
332 assert(y % format_desc->block.height == 0);
333
334 dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
335 src_row = src;
336
337 format_desc->pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h);
338 }
339
340 void
341 util_format_read_4ui(enum pipe_format format,
342 unsigned *dst, unsigned dst_stride,
343 const void *src, unsigned src_stride,
344 unsigned x, unsigned y, unsigned w, unsigned h)
345 {
346 const struct util_format_description *format_desc;
347 const uint8_t *src_row;
348 uint32_t *dst_row;
349
350 format_desc = util_format_description(format);
351
352 assert(x % format_desc->block.width == 0);
353 assert(y % format_desc->block.height == 0);
354
355 src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
356 dst_row = dst;
357
358 format_desc->unpack_rgba_uint(dst_row, dst_stride, src_row, src_stride, w, h);
359 }
360
361 void
362 util_format_write_4ui(enum pipe_format format,
363 const unsigned int *src, unsigned src_stride,
364 void *dst, unsigned dst_stride,
365 unsigned x, unsigned y, unsigned w, unsigned h)
366 {
367 const struct util_format_description *format_desc;
368 uint8_t *dst_row;
369 const uint32_t *src_row;
370
371 format_desc = util_format_description(format);
372
373 assert(x % format_desc->block.width == 0);
374 assert(y % format_desc->block.height == 0);
375
376 dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
377 src_row = src;
378
379 format_desc->pack_rgba_uint(dst_row, dst_stride, src_row, src_stride, w, h);
380 }
381
382 void
383 util_format_read_4i(enum pipe_format format,
384 int *dst, unsigned dst_stride,
385 const void *src, unsigned src_stride,
386 unsigned x, unsigned y, unsigned w, unsigned h)
387 {
388 const struct util_format_description *format_desc;
389 const uint8_t *src_row;
390 int32_t *dst_row;
391
392 format_desc = util_format_description(format);
393
394 assert(x % format_desc->block.width == 0);
395 assert(y % format_desc->block.height == 0);
396
397 src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8);
398 dst_row = dst;
399
400 format_desc->unpack_rgba_sint(dst_row, dst_stride, src_row, src_stride, w, h);
401 }
402
403 void
404 util_format_write_4i(enum pipe_format format,
405 const int *src, unsigned src_stride,
406 void *dst, unsigned dst_stride,
407 unsigned x, unsigned y, unsigned w, unsigned h)
408 {
409 const struct util_format_description *format_desc;
410 uint8_t *dst_row;
411 const int32_t *src_row;
412
413 format_desc = util_format_description(format);
414
415 assert(x % format_desc->block.width == 0);
416 assert(y % format_desc->block.height == 0);
417
418 dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8);
419 src_row = src;
420
421 format_desc->pack_rgba_sint(dst_row, dst_stride, src_row, src_stride, w, h);
422 }
423
424 boolean
425 util_is_format_compatible(const struct util_format_description *src_desc,
426 const struct util_format_description *dst_desc)
427 {
428 unsigned chan;
429
430 if (src_desc->format == dst_desc->format) {
431 return TRUE;
432 }
433
434 if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
435 dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
436 return FALSE;
437 }
438
439 if (src_desc->block.bits != dst_desc->block.bits ||
440 src_desc->nr_channels != dst_desc->nr_channels ||
441 src_desc->colorspace != dst_desc->colorspace) {
442 return FALSE;
443 }
444
445 for (chan = 0; chan < 4; ++chan) {
446 if (src_desc->channel[chan].size !=
447 dst_desc->channel[chan].size) {
448 return FALSE;
449 }
450 }
451
452 for (chan = 0; chan < 4; ++chan) {
453 enum util_format_swizzle swizzle = dst_desc->swizzle[chan];
454
455 if (swizzle < 4) {
456 if (src_desc->swizzle[chan] != swizzle) {
457 return FALSE;
458 }
459 if ((src_desc->channel[swizzle].type !=
460 dst_desc->channel[swizzle].type) ||
461 (src_desc->channel[swizzle].normalized !=
462 dst_desc->channel[swizzle].normalized)) {
463 return FALSE;
464 }
465 }
466 }
467
468 return TRUE;
469 }
470
471
472 boolean
473 util_format_fits_8unorm(const struct util_format_description *format_desc)
474 {
475 unsigned chan;
476
477 /*
478 * After linearized sRGB values require more than 8bits.
479 */
480
481 if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
482 return FALSE;
483 }
484
485 switch (format_desc->layout) {
486
487 case UTIL_FORMAT_LAYOUT_S3TC:
488 /*
489 * These are straight forward.
490 */
491 return TRUE;
492 case UTIL_FORMAT_LAYOUT_RGTC:
493 if (format_desc->format == PIPE_FORMAT_RGTC1_SNORM ||
494 format_desc->format == PIPE_FORMAT_RGTC2_SNORM ||
495 format_desc->format == PIPE_FORMAT_LATC1_SNORM ||
496 format_desc->format == PIPE_FORMAT_LATC2_SNORM)
497 return FALSE;
498 return TRUE;
499
500 case UTIL_FORMAT_LAYOUT_PLAIN:
501 /*
502 * For these we can find a generic rule.
503 */
504
505 for (chan = 0; chan < format_desc->nr_channels; ++chan) {
506 switch (format_desc->channel[chan].type) {
507 case UTIL_FORMAT_TYPE_VOID:
508 break;
509 case UTIL_FORMAT_TYPE_UNSIGNED:
510 if (!format_desc->channel[chan].normalized ||
511 format_desc->channel[chan].size > 8) {
512 return FALSE;
513 }
514 break;
515 default:
516 return FALSE;
517 }
518 }
519 return TRUE;
520
521 default:
522 /*
523 * Handle all others on a case by case basis.
524 */
525
526 switch (format_desc->format) {
527 case PIPE_FORMAT_R1_UNORM:
528 case PIPE_FORMAT_UYVY:
529 case PIPE_FORMAT_YUYV:
530 case PIPE_FORMAT_R8G8_B8G8_UNORM:
531 case PIPE_FORMAT_G8R8_G8B8_UNORM:
532 return TRUE;
533
534 default:
535 return FALSE;
536 }
537 }
538 }
539
540
541 boolean
542 util_format_translate(enum pipe_format dst_format,
543 void *dst, unsigned dst_stride,
544 unsigned dst_x, unsigned dst_y,
545 enum pipe_format src_format,
546 const void *src, unsigned src_stride,
547 unsigned src_x, unsigned src_y,
548 unsigned width, unsigned height)
549 {
550 const struct util_format_description *dst_format_desc;
551 const struct util_format_description *src_format_desc;
552 uint8_t *dst_row;
553 const uint8_t *src_row;
554 unsigned x_step, y_step;
555 unsigned dst_step;
556 unsigned src_step;
557
558 dst_format_desc = util_format_description(dst_format);
559 src_format_desc = util_format_description(src_format);
560
561 if (util_is_format_compatible(src_format_desc, dst_format_desc)) {
562 /*
563 * Trivial case.
564 */
565
566 util_copy_rect(dst, dst_format, dst_stride, dst_x, dst_y,
567 width, height, src, (int)src_stride,
568 src_x, src_y);
569 return TRUE;
570 }
571
572 assert(dst_x % dst_format_desc->block.width == 0);
573 assert(dst_y % dst_format_desc->block.height == 0);
574 assert(src_x % src_format_desc->block.width == 0);
575 assert(src_y % src_format_desc->block.height == 0);
576
577 dst_row = (uint8_t *)dst + dst_y*dst_stride + dst_x*(dst_format_desc->block.bits/8);
578 src_row = (const uint8_t *)src + src_y*src_stride + src_x*(src_format_desc->block.bits/8);
579
580 /*
581 * This works because all pixel formats have pixel blocks with power of two
582 * sizes.
583 */
584
585 y_step = MAX2(dst_format_desc->block.height, src_format_desc->block.height);
586 x_step = MAX2(dst_format_desc->block.width, src_format_desc->block.width);
587 assert(y_step % dst_format_desc->block.height == 0);
588 assert(y_step % src_format_desc->block.height == 0);
589
590 dst_step = y_step / dst_format_desc->block.height * dst_stride;
591 src_step = y_step / src_format_desc->block.height * src_stride;
592
593 /*
594 * TODO: double formats will loose precision
595 * TODO: Add a special case for formats that are mere swizzles of each other
596 */
597
598 if (src_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ||
599 dst_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
600 float *tmp_z = NULL;
601 uint8_t *tmp_s = NULL;
602
603 assert(x_step == 1);
604 assert(y_step == 1);
605
606 if (src_format_desc->unpack_z_float &&
607 dst_format_desc->pack_z_float) {
608 tmp_z = MALLOC(width * sizeof *tmp_z);
609 }
610
611 if (src_format_desc->unpack_s_8uint &&
612 dst_format_desc->pack_s_8uint) {
613 tmp_s = MALLOC(width * sizeof *tmp_s);
614 }
615
616 while (height--) {
617 if (tmp_z) {
618 src_format_desc->unpack_z_float(tmp_z, 0, src_row, src_stride, width, 1);
619 dst_format_desc->pack_z_float(dst_row, dst_stride, tmp_z, 0, width, 1);
620 }
621
622 if (tmp_s) {
623 src_format_desc->unpack_s_8uint(tmp_s, 0, src_row, src_stride, width, 1);
624 dst_format_desc->pack_s_8uint(dst_row, dst_stride, tmp_s, 0, width, 1);
625 }
626
627 dst_row += dst_step;
628 src_row += src_step;
629 }
630
631 FREE(tmp_s);
632
633 FREE(tmp_z);
634
635 return TRUE;
636 }
637
638 if (util_format_fits_8unorm(src_format_desc) ||
639 util_format_fits_8unorm(dst_format_desc)) {
640 unsigned tmp_stride;
641 uint8_t *tmp_row;
642
643 if (!src_format_desc->unpack_rgba_8unorm ||
644 !dst_format_desc->pack_rgba_8unorm) {
645 return FALSE;
646 }
647
648 tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
649 tmp_row = MALLOC(y_step * tmp_stride);
650 if (!tmp_row)
651 return FALSE;
652
653 while (height >= y_step) {
654 src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, y_step);
655 dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
656
657 dst_row += dst_step;
658 src_row += src_step;
659 height -= y_step;
660 }
661
662 if (height) {
663 src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, height);
664 dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
665 }
666
667 FREE(tmp_row);
668 }
669 else {
670 unsigned tmp_stride;
671 float *tmp_row;
672
673 if (!src_format_desc->unpack_rgba_float ||
674 !dst_format_desc->pack_rgba_float) {
675 return FALSE;
676 }
677
678 tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
679 tmp_row = MALLOC(y_step * tmp_stride);
680 if (!tmp_row)
681 return FALSE;
682
683 while (height >= y_step) {
684 src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, y_step);
685 dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
686
687 dst_row += dst_step;
688 src_row += src_step;
689 height -= y_step;
690 }
691
692 if (height) {
693 src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, height);
694 dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
695 }
696
697 FREE(tmp_row);
698 }
699 return TRUE;
700 }
701
702 void util_format_compose_swizzles(const unsigned char swz1[4],
703 const unsigned char swz2[4],
704 unsigned char dst[4])
705 {
706 unsigned i;
707
708 for (i = 0; i < 4; i++) {
709 dst[i] = swz2[i] <= UTIL_FORMAT_SWIZZLE_W ?
710 swz1[swz2[i]] : swz2[i];
711 }
712 }
713
714 void util_format_apply_color_swizzle(union pipe_color_union *dst,
715 const union pipe_color_union *src,
716 const unsigned char swz[4],
717 const boolean is_integer)
718 {
719 unsigned c;
720
721 if (is_integer) {
722 for (c = 0; c < 4; ++c) {
723 switch (swz[c]) {
724 case PIPE_SWIZZLE_RED: dst->ui[c] = src->ui[0]; break;
725 case PIPE_SWIZZLE_GREEN: dst->ui[c] = src->ui[1]; break;
726 case PIPE_SWIZZLE_BLUE: dst->ui[c] = src->ui[2]; break;
727 case PIPE_SWIZZLE_ALPHA: dst->ui[c] = src->ui[3]; break;
728 default:
729 dst->ui[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1 : 0;
730 break;
731 }
732 }
733 } else {
734 for (c = 0; c < 4; ++c) {
735 switch (swz[c]) {
736 case PIPE_SWIZZLE_RED: dst->f[c] = src->f[0]; break;
737 case PIPE_SWIZZLE_GREEN: dst->f[c] = src->f[1]; break;
738 case PIPE_SWIZZLE_BLUE: dst->f[c] = src->f[2]; break;
739 case PIPE_SWIZZLE_ALPHA: dst->f[c] = src->f[3]; break;
740 default:
741 dst->f[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1.0f : 0.0f;
742 break;
743 }
744 }
745 }
746 }
747
748 void util_format_swizzle_4f(float *dst, const float *src,
749 const unsigned char swz[4])
750 {
751 unsigned i;
752
753 for (i = 0; i < 4; i++) {
754 if (swz[i] <= UTIL_FORMAT_SWIZZLE_W)
755 dst[i] = src[swz[i]];
756 else if (swz[i] == UTIL_FORMAT_SWIZZLE_0)
757 dst[i] = 0;
758 else if (swz[i] == UTIL_FORMAT_SWIZZLE_1)
759 dst[i] = 1;
760 }
761 }
762
763 void util_format_unswizzle_4f(float *dst, const float *src,
764 const unsigned char swz[4])
765 {
766 unsigned i;
767
768 for (i = 0; i < 4; i++) {
769 switch (swz[i]) {
770 case UTIL_FORMAT_SWIZZLE_X:
771 dst[0] = src[i];
772 break;
773 case UTIL_FORMAT_SWIZZLE_Y:
774 dst[1] = src[i];
775 break;
776 case UTIL_FORMAT_SWIZZLE_Z:
777 dst[2] = src[i];
778 break;
779 case UTIL_FORMAT_SWIZZLE_W:
780 dst[3] = src[i];
781 break;
782 }
783 }
784 }