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