e734e31a7986a4b36d967cab1fee5ed145b766b9
[mesa.git] / src / mesa / main / format_pack.py
1 #!/usr/bin/env python
2
3 from mako.template import Template
4 from sys import argv
5
6 string = """/*
7 * Mesa 3-D graphics library
8 *
9 * Copyright (c) 2011 VMware, Inc.
10 * Copyright (c) 2014 Intel Corporation.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
32 /**
33 * Color, depth, stencil packing functions.
34 * Used to pack basic color, depth and stencil formats to specific
35 * hardware formats.
36 *
37 * There are both per-pixel and per-row packing functions:
38 * - The former will be used by swrast to write values to the color, depth,
39 * stencil buffers when drawing points, lines and masked spans.
40 * - The later will be used for image-oriented functions like glDrawPixels,
41 * glAccum, and glTexImage.
42 */
43
44 #include <stdint.h>
45
46 #include "colormac.h"
47 #include "format_pack.h"
48 #include "format_utils.h"
49 #include "macros.h"
50 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
51 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
52 #include "util/format_srgb.h"
53
54 #define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS))
55 #define PACK(SRC, OFFSET, BITS) (((SRC) & MAX_UINT(BITS)) << (OFFSET))
56
57 <%
58 import format_parser as parser
59
60 formats = parser.parse(argv[1])
61
62 rgb_formats = []
63 for f in formats:
64 if f.name == 'MESA_FORMAT_NONE':
65 continue
66 if f.colorspace not in ('rgb', 'srgb'):
67 continue
68
69 rgb_formats.append(f)
70 %>
71
72 /* ubyte packing functions */
73
74 %for f in rgb_formats:
75 %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'):
76 <% continue %>
77 %elif f.is_compressed():
78 <% continue %>
79 %endif
80
81 static inline void
82 pack_ubyte_${f.short_name()}(const GLubyte src[4], void *dst)
83 {
84 %for (i, c) in enumerate(f.channels):
85 <% i = f.swizzle.inverse()[i] %>
86 %if c.type == 'x':
87 <% continue %>
88 %endif
89
90 ${c.datatype()} ${c.name} =
91 %if not f.is_normalized() and f.is_int():
92 %if c.type == parser.SIGNED:
93 _mesa_unsigned_to_signed(src[${i}], ${c.size});
94 %else:
95 _mesa_unsigned_to_unsigned(src[${i}], ${c.size});
96 %endif
97 %elif c.type == parser.UNSIGNED:
98 %if f.colorspace == 'srgb' and c.name in 'rgb':
99 <% assert c.size == 8 %>
100 util_format_linear_to_srgb_8unorm(src[${i}]);
101 %else:
102 _mesa_unorm_to_unorm(src[${i}], 8, ${c.size});
103 %endif
104 %elif c.type == parser.SIGNED:
105 _mesa_unorm_to_snorm(src[${i}], 8, ${c.size});
106 %elif c.type == parser.FLOAT:
107 %if c.size == 32:
108 _mesa_unorm_to_float(src[${i}], 8);
109 %elif c.size == 16:
110 _mesa_unorm_to_half(src[${i}], 8);
111 %else:
112 <% assert False %>
113 %endif
114 %else:
115 <% assert False %>
116 %endif
117 %endfor
118
119 %if f.layout == parser.ARRAY:
120 ${f.datatype()} *d = (${f.datatype()} *)dst;
121 %for (i, c) in enumerate(f.channels):
122 %if c.type == 'x':
123 <% continue %>
124 %endif
125 d[${i}] = ${c.name};
126 %endfor
127 %elif f.layout == parser.PACKED:
128 ${f.datatype()} d = 0;
129 %for (i, c) in enumerate(f.channels):
130 %if c.type == 'x':
131 <% continue %>
132 %endif
133 d |= PACK(${c.name}, ${c.shift}, ${c.size});
134 %endfor
135 (*(${f.datatype()} *)dst) = d;
136 %else:
137 <% assert False %>
138 %endif
139 }
140 %endfor
141
142 static inline void
143 pack_ubyte_r9g9b9e5_float(const GLubyte src[4], void *dst)
144 {
145 GLuint *d = (GLuint *) dst;
146 GLfloat rgb[3];
147 rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8);
148 rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8);
149 rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8);
150 *d = float3_to_rgb9e5(rgb);
151 }
152
153 static inline void
154 pack_ubyte_r11g11b10_float(const GLubyte src[4], void *dst)
155 {
156 GLuint *d = (GLuint *) dst;
157 GLfloat rgb[3];
158 rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8);
159 rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8);
160 rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8);
161 *d = float3_to_r11g11b10f(rgb);
162 }
163
164 /* uint packing functions */
165
166 %for f in rgb_formats:
167 %if not f.is_int():
168 <% continue %>
169 %elif f.is_normalized():
170 <% continue %>
171 %elif f.is_compressed():
172 <% continue %>
173 %endif
174
175 static inline void
176 pack_uint_${f.short_name()}(const GLuint src[4], void *dst)
177 {
178 %for (i, c) in enumerate(f.channels):
179 <% i = f.swizzle.inverse()[i] %>
180 %if c.type == 'x':
181 <% continue %>
182 %endif
183
184 ${c.datatype()} ${c.name} =
185 %if c.type == parser.SIGNED:
186 _mesa_signed_to_signed(src[${i}], ${c.size});
187 %elif c.type == parser.UNSIGNED:
188 _mesa_unsigned_to_unsigned(src[${i}], ${c.size});
189 %else:
190 assert(!"Invalid type: only integer types are allowed");
191 %endif
192 %endfor
193
194 %if f.layout == parser.ARRAY:
195 ${f.datatype()} *d = (${f.datatype()} *)dst;
196 %for (i, c) in enumerate(f.channels):
197 %if c.type == 'x':
198 <% continue %>
199 %endif
200 d[${i}] = ${c.name};
201 %endfor
202 %elif f.layout == parser.PACKED:
203 ${f.datatype()} d = 0;
204 %for (i, c) in enumerate(f.channels):
205 %if c.type == 'x':
206 <% continue %>
207 %endif
208 d |= PACK(${c.name}, ${c.shift}, ${c.size});
209 %endfor
210 (*(${f.datatype()} *)dst) = d;
211 %else:
212 <% assert False %>
213 %endif
214 }
215 %endfor
216
217 /* int packing functions */
218
219 %for f in rgb_formats:
220 %if not f.is_int():
221 <% continue %>
222 %elif f.is_normalized():
223 <% continue %>
224 %elif f.is_compressed():
225 <% continue %>
226 %endif
227
228 static inline void
229 pack_int_${f.short_name()}(const GLint src[4], void *dst)
230 {
231 %for (i, c) in enumerate(f.channels):
232 <% i = f.swizzle.inverse()[i] %>
233 %if c.type == 'x':
234 <% continue %>
235 %endif
236
237 ${c.datatype()} ${c.name} =
238 %if c.type == parser.SIGNED:
239 _mesa_signed_to_signed(src[${i}], ${c.size});
240 %elif c.type == parser.UNSIGNED:
241 _mesa_unsigned_to_unsigned(src[${i}], ${c.size});
242 %else:
243 assert(!"Invalid type: only integer types are allowed");
244 %endif
245 %endfor
246
247 %if f.layout == parser.ARRAY:
248 ${f.datatype()} *d = (${f.datatype()} *)dst;
249 %for (i, c) in enumerate(f.channels):
250 %if c.type == 'x':
251 <% continue %>
252 %endif
253 d[${i}] = ${c.name};
254 %endfor
255 %elif f.layout == parser.PACKED:
256 ${f.datatype()} d = 0;
257 %for (i, c) in enumerate(f.channels):
258 %if c.type == 'x':
259 <% continue %>
260 %endif
261 d |= PACK(${c.name}, ${c.shift}, ${c.size});
262 %endfor
263 (*(${f.datatype()} *)dst) = d;
264 %else:
265 <% assert False %>
266 %endif
267 }
268 %endfor
269
270 /* float packing functions */
271
272 %for f in rgb_formats:
273 %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'):
274 <% continue %>
275 %elif f.is_int() and not f.is_normalized():
276 <% continue %>
277 %elif f.is_compressed():
278 <% continue %>
279 %endif
280
281 static inline void
282 pack_float_${f.short_name()}(const GLfloat src[4], void *dst)
283 {
284 %for (i, c) in enumerate(f.channels):
285 <% i = f.swizzle.inverse()[i] %>
286 %if c.type == 'x':
287 <% continue %>
288 %endif
289
290 ${c.datatype()} ${c.name} =
291 %if c.type == parser.UNSIGNED:
292 %if f.colorspace == 'srgb' and c.name in 'rgb':
293 <% assert c.size == 8 %>
294 util_format_linear_float_to_srgb_8unorm(src[${i}]);
295 %else:
296 _mesa_float_to_unorm(src[${i}], ${c.size});
297 %endif
298 %elif c.type == parser.SIGNED:
299 _mesa_float_to_snorm(src[${i}], ${c.size});
300 %elif c.type == parser.FLOAT:
301 %if c.size == 32:
302 src[${i}];
303 %elif c.size == 16:
304 _mesa_float_to_half(src[${i}]);
305 %else:
306 <% assert False %>
307 %endif
308 %else:
309 <% assert False %>
310 %endif
311 %endfor
312
313 %if f.layout == parser.ARRAY:
314 ${f.datatype()} *d = (${f.datatype()} *)dst;
315 %for (i, c) in enumerate(f.channels):
316 %if c.type == 'x':
317 <% continue %>
318 %endif
319 d[${i}] = ${c.name};
320 %endfor
321 %elif f.layout == parser.PACKED:
322 ${f.datatype()} d = 0;
323 %for (i, c) in enumerate(f.channels):
324 %if c.type == 'x':
325 <% continue %>
326 %endif
327 d |= PACK(${c.name}, ${c.shift}, ${c.size});
328 %endfor
329 (*(${f.datatype()} *)dst) = d;
330 %else:
331 <% assert False %>
332 %endif
333 }
334 %endfor
335
336 static inline void
337 pack_float_r9g9b9e5_float(const GLfloat src[4], void *dst)
338 {
339 GLuint *d = (GLuint *) dst;
340 *d = float3_to_rgb9e5(src);
341 }
342
343 static inline void
344 pack_float_r11g11b10_float(const GLfloat src[4], void *dst)
345 {
346 GLuint *d = (GLuint *) dst;
347 *d = float3_to_r11g11b10f(src);
348 }
349
350 /**
351 * Return a function that can pack a GLubyte rgba[4] color.
352 */
353 gl_pack_ubyte_rgba_func
354 _mesa_get_pack_ubyte_rgba_function(mesa_format format)
355 {
356 switch (format) {
357 %for f in rgb_formats:
358 %if f.is_compressed():
359 <% continue %>
360 %endif
361
362 case ${f.name}:
363 return pack_ubyte_${f.short_name()};
364 %endfor
365 default:
366 return NULL;
367 }
368 }
369
370 /**
371 * Return a function that can pack a GLfloat rgba[4] color.
372 */
373 gl_pack_float_rgba_func
374 _mesa_get_pack_float_rgba_function(mesa_format format)
375 {
376 switch (format) {
377 %for f in rgb_formats:
378 %if f.is_compressed():
379 <% continue %>
380 %elif f.is_int() and not f.is_normalized():
381 <% continue %>
382 %endif
383
384 case ${f.name}:
385 return pack_float_${f.short_name()};
386 %endfor
387 default:
388 return NULL;
389 }
390 }
391
392 /**
393 * Pack a row of GLubyte rgba[4] values to the destination.
394 */
395 void
396 _mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n,
397 const GLubyte src[][4], void *dst)
398 {
399 GLuint i;
400 GLubyte *d = dst;
401
402 switch (format) {
403 %for f in rgb_formats:
404 %if f.is_compressed():
405 <% continue %>
406 %endif
407
408 case ${f.name}:
409 for (i = 0; i < n; ++i) {
410 pack_ubyte_${f.short_name()}(src[i], d);
411 d += ${f.block_size() / 8};
412 }
413 break;
414 %endfor
415 default:
416 assert(!"Invalid format");
417 }
418 }
419
420 /**
421 * Pack a row of GLuint rgba[4] values to the destination.
422 */
423 void
424 _mesa_pack_uint_rgba_row(mesa_format format, GLuint n,
425 const GLuint src[][4], void *dst)
426 {
427 GLuint i;
428 GLubyte *d = dst;
429
430 switch (format) {
431 %for f in rgb_formats:
432 %if not f.is_int():
433 <% continue %>
434 %elif f.is_normalized():
435 <% continue %>
436 %elif f.is_compressed():
437 <% continue %>
438 %endif
439
440 case ${f.name}:
441 for (i = 0; i < n; ++i) {
442 pack_uint_${f.short_name()}(src[i], d);
443 d += ${f.block_size() / 8};
444 }
445 break;
446 %endfor
447 default:
448 assert(!"Invalid format");
449 }
450 }
451
452 /**
453 * Pack a row of GLint rgba[4] values to the destination.
454 */
455 void
456 _mesa_pack_int_rgba_row(mesa_format format, GLuint n,
457 const GLint src[][4], void *dst)
458 {
459 GLuint i;
460 GLubyte *d = dst;
461
462 switch (format) {
463 %for f in rgb_formats:
464 %if not f.is_int():
465 <% continue %>
466 %elif f.is_normalized():
467 <% continue %>
468 %elif f.is_compressed():
469 <% continue %>
470 %endif
471
472 case ${f.name}:
473 for (i = 0; i < n; ++i) {
474 pack_int_${f.short_name()}(src[i], d);
475 d += ${f.block_size() / 8};
476 }
477 break;
478 %endfor
479 default:
480 assert(!"Invalid format");
481 }
482 }
483
484 /**
485 * Pack a row of GLfloat rgba[4] values to the destination.
486 */
487 void
488 _mesa_pack_float_rgba_row(mesa_format format, GLuint n,
489 const GLfloat src[][4], void *dst)
490 {
491 GLuint i;
492 GLubyte *d = dst;
493
494 switch (format) {
495 %for f in rgb_formats:
496 %if f.is_compressed():
497 <% continue %>
498 %elif f.is_int() and not f.is_normalized():
499 <% continue %>
500 %endif
501
502 case ${f.name}:
503 for (i = 0; i < n; ++i) {
504 pack_float_${f.short_name()}(src[i], d);
505 d += ${f.block_size() / 8};
506 }
507 break;
508 %endfor
509 default:
510 assert(!"Invalid format");
511 }
512 }
513
514 /**
515 * Pack a 2D image of ubyte RGBA pixels in the given format.
516 * \param srcRowStride source image row stride in bytes
517 * \param dstRowStride destination image row stride in bytes
518 */
519 void
520 _mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height,
521 const GLubyte *src, GLint srcRowStride,
522 void *dst, GLint dstRowStride)
523 {
524 GLubyte *dstUB = dst;
525 GLuint i;
526
527 if (srcRowStride == width * 4 * sizeof(GLubyte) &&
528 dstRowStride == _mesa_format_row_stride(format, width)) {
529 /* do whole image at once */
530 _mesa_pack_ubyte_rgba_row(format, width * height,
531 (const GLubyte (*)[4]) src, dst);
532 }
533 else {
534 /* row by row */
535 for (i = 0; i < height; i++) {
536 _mesa_pack_ubyte_rgba_row(format, width,
537 (const GLubyte (*)[4]) src, dstUB);
538 src += srcRowStride;
539 dstUB += dstRowStride;
540 }
541 }
542 }
543
544
545 /** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */
546 struct z32f_x24s8
547 {
548 float z;
549 uint32_t x24s8;
550 };
551
552
553 /**
554 ** Pack float Z pixels
555 **/
556
557 static void
558 pack_float_S8_UINT_Z24_UNORM(const GLfloat *src, void *dst)
559 {
560 /* don't disturb the stencil values */
561 GLuint *d = ((GLuint *) dst);
562 const GLdouble scale = (GLdouble) 0xffffff;
563 GLuint s = *d & 0xff;
564 GLuint z = (GLuint) (*src * scale);
565 assert(z <= 0xffffff);
566 *d = (z << 8) | s;
567 }
568
569 static void
570 pack_float_Z24_UNORM_S8_UINT(const GLfloat *src, void *dst)
571 {
572 /* don't disturb the stencil values */
573 GLuint *d = ((GLuint *) dst);
574 const GLdouble scale = (GLdouble) 0xffffff;
575 GLuint s = *d & 0xff000000;
576 GLuint z = (GLuint) (*src * scale);
577 assert(z <= 0xffffff);
578 *d = s | z;
579 }
580
581 static void
582 pack_float_Z_UNORM16(const GLfloat *src, void *dst)
583 {
584 GLushort *d = ((GLushort *) dst);
585 const GLfloat scale = (GLfloat) 0xffff;
586 *d = (GLushort) (*src * scale);
587 }
588
589 static void
590 pack_float_Z_UNORM32(const GLfloat *src, void *dst)
591 {
592 GLuint *d = ((GLuint *) dst);
593 const GLdouble scale = (GLdouble) 0xffffffff;
594 *d = (GLuint) (*src * scale);
595 }
596
597 static void
598 pack_float_Z_FLOAT32(const GLfloat *src, void *dst)
599 {
600 GLfloat *d = (GLfloat *) dst;
601 *d = *src;
602 }
603
604 gl_pack_float_z_func
605 _mesa_get_pack_float_z_func(mesa_format format)
606 {
607 switch (format) {
608 case MESA_FORMAT_S8_UINT_Z24_UNORM:
609 case MESA_FORMAT_X8_UINT_Z24_UNORM:
610 return pack_float_S8_UINT_Z24_UNORM;
611 case MESA_FORMAT_Z24_UNORM_S8_UINT:
612 case MESA_FORMAT_Z24_UNORM_X8_UINT:
613 return pack_float_Z24_UNORM_S8_UINT;
614 case MESA_FORMAT_Z_UNORM16:
615 return pack_float_Z_UNORM16;
616 case MESA_FORMAT_Z_UNORM32:
617 return pack_float_Z_UNORM32;
618 case MESA_FORMAT_Z_FLOAT32:
619 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
620 return pack_float_Z_FLOAT32;
621 default:
622 _mesa_problem(NULL,
623 "unexpected format in _mesa_get_pack_float_z_func()");
624 return NULL;
625 }
626 }
627
628
629
630 /**
631 ** Pack uint Z pixels. The incoming src value is always in
632 ** the range [0, 2^32-1].
633 **/
634
635 static void
636 pack_uint_S8_UINT_Z24_UNORM(const GLuint *src, void *dst)
637 {
638 /* don't disturb the stencil values */
639 GLuint *d = ((GLuint *) dst);
640 GLuint s = *d & 0xff;
641 GLuint z = *src & 0xffffff00;
642 *d = z | s;
643 }
644
645 static void
646 pack_uint_Z24_UNORM_S8_UINT(const GLuint *src, void *dst)
647 {
648 /* don't disturb the stencil values */
649 GLuint *d = ((GLuint *) dst);
650 GLuint s = *d & 0xff000000;
651 GLuint z = *src >> 8;
652 *d = s | z;
653 }
654
655 static void
656 pack_uint_Z_UNORM16(const GLuint *src, void *dst)
657 {
658 GLushort *d = ((GLushort *) dst);
659 *d = *src >> 16;
660 }
661
662 static void
663 pack_uint_Z_UNORM32(const GLuint *src, void *dst)
664 {
665 GLuint *d = ((GLuint *) dst);
666 *d = *src;
667 }
668
669 static void
670 pack_uint_Z_FLOAT32(const GLuint *src, void *dst)
671 {
672 GLuint *d = ((GLuint *) dst);
673 const GLdouble scale = 1.0 / (GLdouble) 0xffffffff;
674 *d = (GLuint) (*src * scale);
675 assert(*d >= 0.0f);
676 assert(*d <= 1.0f);
677 }
678
679 static void
680 pack_uint_Z_FLOAT32_X24S8(const GLuint *src, void *dst)
681 {
682 GLfloat *d = ((GLfloat *) dst);
683 const GLdouble scale = 1.0 / (GLdouble) 0xffffffff;
684 *d = (GLfloat) (*src * scale);
685 assert(*d >= 0.0f);
686 assert(*d <= 1.0f);
687 }
688
689 gl_pack_uint_z_func
690 _mesa_get_pack_uint_z_func(mesa_format format)
691 {
692 switch (format) {
693 case MESA_FORMAT_S8_UINT_Z24_UNORM:
694 case MESA_FORMAT_X8_UINT_Z24_UNORM:
695 return pack_uint_S8_UINT_Z24_UNORM;
696 case MESA_FORMAT_Z24_UNORM_S8_UINT:
697 case MESA_FORMAT_Z24_UNORM_X8_UINT:
698 return pack_uint_Z24_UNORM_S8_UINT;
699 case MESA_FORMAT_Z_UNORM16:
700 return pack_uint_Z_UNORM16;
701 case MESA_FORMAT_Z_UNORM32:
702 return pack_uint_Z_UNORM32;
703 case MESA_FORMAT_Z_FLOAT32:
704 return pack_uint_Z_FLOAT32;
705 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
706 return pack_uint_Z_FLOAT32_X24S8;
707 default:
708 _mesa_problem(NULL, "unexpected format in _mesa_get_pack_uint_z_func()");
709 return NULL;
710 }
711 }
712
713
714 /**
715 ** Pack ubyte stencil pixels
716 **/
717
718 static void
719 pack_ubyte_stencil_Z24_S8(const GLubyte *src, void *dst)
720 {
721 /* don't disturb the Z values */
722 GLuint *d = ((GLuint *) dst);
723 GLuint s = *src;
724 GLuint z = *d & 0xffffff00;
725 *d = z | s;
726 }
727
728 static void
729 pack_ubyte_stencil_S8_Z24(const GLubyte *src, void *dst)
730 {
731 /* don't disturb the Z values */
732 GLuint *d = ((GLuint *) dst);
733 GLuint s = *src << 24;
734 GLuint z = *d & 0xffffff;
735 *d = s | z;
736 }
737
738 static void
739 pack_ubyte_stencil_S8(const GLubyte *src, void *dst)
740 {
741 GLubyte *d = (GLubyte *) dst;
742 *d = *src;
743 }
744
745 static void
746 pack_ubyte_stencil_Z32_FLOAT_X24S8(const GLubyte *src, void *dst)
747 {
748 GLfloat *d = ((GLfloat *) dst);
749 d[1] = *src;
750 }
751
752
753 gl_pack_ubyte_stencil_func
754 _mesa_get_pack_ubyte_stencil_func(mesa_format format)
755 {
756 switch (format) {
757 case MESA_FORMAT_S8_UINT_Z24_UNORM:
758 return pack_ubyte_stencil_Z24_S8;
759 case MESA_FORMAT_Z24_UNORM_S8_UINT:
760 return pack_ubyte_stencil_S8_Z24;
761 case MESA_FORMAT_S_UINT8:
762 return pack_ubyte_stencil_S8;
763 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
764 return pack_ubyte_stencil_Z32_FLOAT_X24S8;
765 default:
766 _mesa_problem(NULL,
767 "unexpected format in _mesa_pack_ubyte_stencil_func()");
768 return NULL;
769 }
770 }
771
772
773
774 void
775 _mesa_pack_float_z_row(mesa_format format, GLuint n,
776 const GLfloat *src, void *dst)
777 {
778 switch (format) {
779 case MESA_FORMAT_S8_UINT_Z24_UNORM:
780 case MESA_FORMAT_X8_UINT_Z24_UNORM:
781 {
782 /* don't disturb the stencil values */
783 GLuint *d = ((GLuint *) dst);
784 const GLdouble scale = (GLdouble) 0xffffff;
785 GLuint i;
786 for (i = 0; i < n; i++) {
787 GLuint s = d[i] & 0xff;
788 GLuint z = (GLuint) (src[i] * scale);
789 assert(z <= 0xffffff);
790 d[i] = (z << 8) | s;
791 }
792 }
793 break;
794 case MESA_FORMAT_Z24_UNORM_S8_UINT:
795 case MESA_FORMAT_Z24_UNORM_X8_UINT:
796 {
797 /* don't disturb the stencil values */
798 GLuint *d = ((GLuint *) dst);
799 const GLdouble scale = (GLdouble) 0xffffff;
800 GLuint i;
801 for (i = 0; i < n; i++) {
802 GLuint s = d[i] & 0xff000000;
803 GLuint z = (GLuint) (src[i] * scale);
804 assert(z <= 0xffffff);
805 d[i] = s | z;
806 }
807 }
808 break;
809 case MESA_FORMAT_Z_UNORM16:
810 {
811 GLushort *d = ((GLushort *) dst);
812 const GLfloat scale = (GLfloat) 0xffff;
813 GLuint i;
814 for (i = 0; i < n; i++) {
815 d[i] = (GLushort) (src[i] * scale);
816 }
817 }
818 break;
819 case MESA_FORMAT_Z_UNORM32:
820 {
821 GLuint *d = ((GLuint *) dst);
822 const GLdouble scale = (GLdouble) 0xffffffff;
823 GLuint i;
824 for (i = 0; i < n; i++) {
825 d[i] = (GLuint) (src[i] * scale);
826 }
827 }
828 break;
829 case MESA_FORMAT_Z_FLOAT32:
830 memcpy(dst, src, n * sizeof(GLfloat));
831 break;
832 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
833 {
834 struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
835 GLuint i;
836 for (i = 0; i < n; i++) {
837 d[i].z = src[i];
838 }
839 }
840 break;
841 default:
842 _mesa_problem(NULL, "unexpected format in _mesa_pack_float_z_row()");
843 }
844 }
845
846
847 /**
848 * The incoming Z values are always in the range [0, 0xffffffff].
849 */
850 void
851 _mesa_pack_uint_z_row(mesa_format format, GLuint n,
852 const GLuint *src, void *dst)
853 {
854 switch (format) {
855 case MESA_FORMAT_S8_UINT_Z24_UNORM:
856 case MESA_FORMAT_X8_UINT_Z24_UNORM:
857 {
858 /* don't disturb the stencil values */
859 GLuint *d = ((GLuint *) dst);
860 GLuint i;
861 for (i = 0; i < n; i++) {
862 GLuint s = d[i] & 0xff;
863 GLuint z = src[i] & 0xffffff00;
864 d[i] = z | s;
865 }
866 }
867 break;
868 case MESA_FORMAT_Z24_UNORM_S8_UINT:
869 case MESA_FORMAT_Z24_UNORM_X8_UINT:
870 {
871 /* don't disturb the stencil values */
872 GLuint *d = ((GLuint *) dst);
873 GLuint i;
874 for (i = 0; i < n; i++) {
875 GLuint s = d[i] & 0xff000000;
876 GLuint z = src[i] >> 8;
877 d[i] = s | z;
878 }
879 }
880 break;
881 case MESA_FORMAT_Z_UNORM16:
882 {
883 GLushort *d = ((GLushort *) dst);
884 GLuint i;
885 for (i = 0; i < n; i++) {
886 d[i] = src[i] >> 16;
887 }
888 }
889 break;
890 case MESA_FORMAT_Z_UNORM32:
891 memcpy(dst, src, n * sizeof(GLfloat));
892 break;
893 case MESA_FORMAT_Z_FLOAT32:
894 {
895 GLuint *d = ((GLuint *) dst);
896 const GLdouble scale = 1.0 / (GLdouble) 0xffffffff;
897 GLuint i;
898 for (i = 0; i < n; i++) {
899 d[i] = (GLuint) (src[i] * scale);
900 assert(d[i] >= 0.0f);
901 assert(d[i] <= 1.0f);
902 }
903 }
904 break;
905 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
906 {
907 struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
908 const GLdouble scale = 1.0 / (GLdouble) 0xffffffff;
909 GLuint i;
910 for (i = 0; i < n; i++) {
911 d[i].z = (GLfloat) (src[i] * scale);
912 assert(d[i].z >= 0.0f);
913 assert(d[i].z <= 1.0f);
914 }
915 }
916 break;
917 default:
918 _mesa_problem(NULL, "unexpected format in _mesa_pack_uint_z_row()");
919 }
920 }
921
922
923 void
924 _mesa_pack_ubyte_stencil_row(mesa_format format, GLuint n,
925 const GLubyte *src, void *dst)
926 {
927 switch (format) {
928 case MESA_FORMAT_S8_UINT_Z24_UNORM:
929 {
930 /* don't disturb the Z values */
931 GLuint *d = ((GLuint *) dst);
932 GLuint i;
933 for (i = 0; i < n; i++) {
934 GLuint s = src[i];
935 GLuint z = d[i] & 0xffffff00;
936 d[i] = z | s;
937 }
938 }
939 break;
940 case MESA_FORMAT_Z24_UNORM_S8_UINT:
941 {
942 /* don't disturb the Z values */
943 GLuint *d = ((GLuint *) dst);
944 GLuint i;
945 for (i = 0; i < n; i++) {
946 GLuint s = src[i] << 24;
947 GLuint z = d[i] & 0xffffff;
948 d[i] = s | z;
949 }
950 }
951 break;
952 case MESA_FORMAT_S_UINT8:
953 memcpy(dst, src, n * sizeof(GLubyte));
954 break;
955 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
956 {
957 struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
958 GLuint i;
959 for (i = 0; i < n; i++) {
960 d[i].x24s8 = src[i];
961 }
962 }
963 break;
964 default:
965 _mesa_problem(NULL, "unexpected format in _mesa_pack_ubyte_stencil_row()");
966 }
967 }
968
969
970 /**
971 * Incoming Z/stencil values are always in uint_24_8 format.
972 */
973 void
974 _mesa_pack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n,
975 const GLuint *src, void *dst)
976 {
977 switch (format) {
978 case MESA_FORMAT_S8_UINT_Z24_UNORM:
979 memcpy(dst, src, n * sizeof(GLuint));
980 break;
981 case MESA_FORMAT_Z24_UNORM_S8_UINT:
982 {
983 GLuint *d = ((GLuint *) dst);
984 GLuint i;
985 for (i = 0; i < n; i++) {
986 GLuint s = src[i] << 24;
987 GLuint z = src[i] >> 8;
988 d[i] = s | z;
989 }
990 }
991 break;
992 case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
993 {
994 const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
995 struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
996 GLuint i;
997 for (i = 0; i < n; i++) {
998 GLfloat z = (GLfloat) ((src[i] >> 8) * scale);
999 d[i].z = z;
1000 d[i].x24s8 = src[i];
1001 }
1002 }
1003 break;
1004 default:
1005 _mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row",
1006 _mesa_get_format_name(format));
1007 return;
1008 }
1009 }
1010
1011
1012
1013 /**
1014 * Convert a boolean color mask to a packed color where each channel of
1015 * the packed value at dst will be 0 or ~0 depending on the colorMask.
1016 */
1017 void
1018 _mesa_pack_colormask(mesa_format format, const GLubyte colorMask[4], void *dst)
1019 {
1020 GLfloat maskColor[4];
1021
1022 switch (_mesa_get_format_datatype(format)) {
1023 case GL_UNSIGNED_NORMALIZED:
1024 /* simple: 1.0 will convert to ~0 in the right bit positions */
1025 maskColor[0] = colorMask[0] ? 1.0f : 0.0f;
1026 maskColor[1] = colorMask[1] ? 1.0f : 0.0f;
1027 maskColor[2] = colorMask[2] ? 1.0f : 0.0f;
1028 maskColor[3] = colorMask[3] ? 1.0f : 0.0f;
1029 _mesa_pack_float_rgba_row(format, 1,
1030 (const GLfloat (*)[4]) maskColor, dst);
1031 break;
1032 case GL_SIGNED_NORMALIZED:
1033 case GL_FLOAT:
1034 /* These formats are harder because it's hard to know the floating
1035 * point values that will convert to ~0 for each color channel's bits.
1036 * This solution just generates a non-zero value for each color channel
1037 * then fixes up the non-zero values to be ~0.
1038 * Note: we'll need to add special case code if we ever have to deal
1039 * with formats with unequal color channel sizes, like R11_G11_B10.
1040 * We issue a warning below for channel sizes other than 8,16,32.
1041 */
1042 {
1043 GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */
1044 GLuint bytes = _mesa_get_format_bytes(format);
1045 GLuint i;
1046
1047 /* this should put non-zero values into the channels of dst */
1048 maskColor[0] = colorMask[0] ? -1.0f : 0.0f;
1049 maskColor[1] = colorMask[1] ? -1.0f : 0.0f;
1050 maskColor[2] = colorMask[2] ? -1.0f : 0.0f;
1051 maskColor[3] = colorMask[3] ? -1.0f : 0.0f;
1052 _mesa_pack_float_rgba_row(format, 1,
1053 (const GLfloat (*)[4]) maskColor, dst);
1054
1055 /* fix-up the dst channels by converting non-zero values to ~0 */
1056 if (bits == 8) {
1057 GLubyte *d = (GLubyte *) dst;
1058 for (i = 0; i < bytes; i++) {
1059 d[i] = d[i] ? 0xff : 0x0;
1060 }
1061 }
1062 else if (bits == 16) {
1063 GLushort *d = (GLushort *) dst;
1064 for (i = 0; i < bytes / 2; i++) {
1065 d[i] = d[i] ? 0xffff : 0x0;
1066 }
1067 }
1068 else if (bits == 32) {
1069 GLuint *d = (GLuint *) dst;
1070 for (i = 0; i < bytes / 4; i++) {
1071 d[i] = d[i] ? 0xffffffffU : 0x0;
1072 }
1073 }
1074 else {
1075 _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()");
1076 return;
1077 }
1078 }
1079 break;
1080 default:
1081 _mesa_problem(NULL, "unexpected format data type in gen_color_mask()");
1082 return;
1083 }
1084 }
1085 """
1086
1087 template = Template(string);
1088
1089 print template.render(argv = argv[0:])