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