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 "errors.h"
47#include "format_unpack.h"
48#include "format_utils.h"
49#include "macros.h"
50#include "util/format_rgb9e5.h"
51#include "util/format_r11g11b10f.h"
52#include "util/format_srgb.h"
53
54#define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS))
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/* float unpacking 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_int() and not f.is_normalized():
77      <% continue %>
78   %elif f.is_compressed():
79      <% continue %>
80   %endif
81
82static inline void
83unpack_float_${f.short_name()}(const void *void_src, GLfloat dst[4])
84{
85   ${f.datatype()} *src = (${f.datatype()} *)void_src;
86   %if f.layout == parser.PACKED:
87      %for c in f.channels:
88         %if c.type != 'x':
89            ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size});
90         %endif
91      %endfor
92   %elif f.layout == parser.ARRAY:
93      %for (i, c) in enumerate(f.channels):
94         %if c.type != 'x':
95            ${c.datatype()} ${c.name} = src[${i}];
96         %endif
97      %endfor
98   %else:
99      <% assert False %>
100   %endif
101
102   %for i in range(4):
103      <% s = f.swizzle[i] %>
104      %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W:
105         <% c = f.channels[s] %>
106         %if c.type == parser.UNSIGNED:
107            %if f.colorspace == 'srgb' and c.name in 'rgb':
108               <% assert c.size == 8 %>
109               dst[${i}] = util_format_srgb_8unorm_to_linear_float(${c.name});
110            %else:
111               dst[${i}] = _mesa_unorm_to_float(${c.name}, ${c.size});
112            %endif
113         %elif c.type == parser.SIGNED:
114            dst[${i}] = _mesa_snorm_to_float(${c.name}, ${c.size});
115         %elif c.type == parser.FLOAT:
116            %if c.size == 32:
117               dst[${i}] = ${c.name};
118            %elif c.size == 16:
119               dst[${i}] = _mesa_half_to_float(${c.name});
120            %else:
121               <% assert False %>
122            %endif
123         %else:
124            <% assert False %>
125         %endif
126      %elif s == parser.Swizzle.SWIZZLE_ZERO:
127         dst[${i}] = 0.0f;
128      %elif s == parser.Swizzle.SWIZZLE_ONE:
129         dst[${i}] = 1.0f;
130      %else:
131         <% assert False %>
132      %endif
133   %endfor
134}
135%endfor
136
137static void
138unpack_float_r9g9b9e5_float(const void *src, GLfloat dst[4])
139{
140   rgb9e5_to_float3(*(const GLuint *)src, dst);
141   dst[3] = 1.0f;
142}
143
144static void
145unpack_float_r11g11b10_float(const void *src, GLfloat dst[4])
146{
147   r11g11b10f_to_float3(*(const GLuint *)src, dst);
148   dst[3] = 1.0f;
149}
150
151static void
152unpack_float_ycbcr(const void *src, GLfloat dst[][4], GLuint n)
153{
154   GLuint i;
155   for (i = 0; i < n; i++) {
156      const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */
157      const GLushort *src1 = src0 + 1;         /* odd */
158      const GLubyte y0 = (*src0 >> 8) & 0xff;  /* luminance */
159      const GLubyte cb = *src0 & 0xff;         /* chroma U */
160      const GLubyte y1 = (*src1 >> 8) & 0xff;  /* luminance */
161      const GLubyte cr = *src1 & 0xff;         /* chroma V */
162      const GLubyte y = (i & 1) ? y1 : y0;     /* choose even/odd luminance */
163      GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128);
164      GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128);
165      GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128);
166      r *= (1.0F / 255.0F);
167      g *= (1.0F / 255.0F);
168      b *= (1.0F / 255.0F);
169      dst[i][0] = CLAMP(r, 0.0F, 1.0F);
170      dst[i][1] = CLAMP(g, 0.0F, 1.0F);
171      dst[i][2] = CLAMP(b, 0.0F, 1.0F);
172      dst[i][3] = 1.0F;
173   }
174}
175
176static void
177unpack_float_ycbcr_rev(const void *src, GLfloat dst[][4], GLuint n)
178{
179   GLuint i;
180   for (i = 0; i < n; i++) {
181      const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */
182      const GLushort *src1 = src0 + 1;         /* odd */
183      const GLubyte y0 = *src0 & 0xff;         /* luminance */
184      const GLubyte cr = (*src0 >> 8) & 0xff;  /* chroma V */
185      const GLubyte y1 = *src1 & 0xff;         /* luminance */
186      const GLubyte cb = (*src1 >> 8) & 0xff;  /* chroma U */
187      const GLubyte y = (i & 1) ? y1 : y0;     /* choose even/odd luminance */
188      GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128);
189      GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128);
190      GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128);
191      r *= (1.0F / 255.0F);
192      g *= (1.0F / 255.0F);
193      b *= (1.0F / 255.0F);
194      dst[i][0] = CLAMP(r, 0.0F, 1.0F);
195      dst[i][1] = CLAMP(g, 0.0F, 1.0F);
196      dst[i][2] = CLAMP(b, 0.0F, 1.0F);
197      dst[i][3] = 1.0F;
198   }
199}
200
201/* ubyte packing functions */
202
203%for f in rgb_formats:
204   %if not f.is_normalized():
205      <% continue %>
206   %endif
207
208static inline void
209unpack_ubyte_${f.short_name()}(const void *void_src, GLubyte dst[4])
210{
211   ${f.datatype()} *src = (${f.datatype()} *)void_src;
212   %if f.layout == parser.PACKED:
213      %for c in f.channels:
214         %if c.type != 'x':
215            ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size});
216         %endif
217      %endfor
218   %elif f.layout == parser.ARRAY:
219      %for (i, c) in enumerate(f.channels):
220         %if c.type != 'x':
221            ${c.datatype()} ${c.name} = src[${i}];
222         %endif
223      %endfor
224   %else:
225      <% assert False %>
226   %endif
227
228   %for i in range(4):
229      <% s = f.swizzle[i] %>
230      %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W:
231         <% c = f.channels[s] %>
232         %if c.type == parser.UNSIGNED:
233            %if f.colorspace == 'srgb' and c.name in 'rgb':
234               <% assert c.size == 8 %>
235               dst[${i}] = util_format_srgb_to_linear_8unorm(${c.name});
236            %else:
237               dst[${i}] = _mesa_unorm_to_unorm(${c.name}, ${c.size}, 8);
238            %endif
239         %elif c.type == parser.SIGNED:
240            dst[${i}] = _mesa_snorm_to_unorm(${c.name}, ${c.size}, 8);
241         %elif c.type == parser.FLOAT:
242            %if c.size == 32:
243               dst[${i}] = _mesa_float_to_unorm(${c.name}, 8);
244            %elif c.size == 16:
245               dst[${i}] = _mesa_half_to_unorm(${c.name}, 8);
246            %else:
247               <% assert False %>
248            %endif
249         %else:
250            <% assert False %>
251         %endif
252      %elif s == parser.Swizzle.SWIZZLE_ZERO:
253         dst[${i}] = 0;
254      %elif s == parser.Swizzle.SWIZZLE_ONE:
255         dst[${i}] = 255;
256      %else:
257         <% assert False %>
258      %endif
259   %endfor
260}
261%endfor
262
263/* integer packing functions */
264
265%for f in rgb_formats:
266   %if not f.is_int():
267      <% continue %>
268   %elif f.is_normalized():
269      <% continue %>
270   %endif
271
272static inline void
273unpack_int_${f.short_name()}(const void *void_src, GLuint dst[4])
274{
275   ${f.datatype()} *src = (${f.datatype()} *)void_src;
276   %if f.layout == parser.PACKED:
277      %for c in f.channels:
278         %if c.type != 'x':
279            ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size});
280         %endif
281      %endfor
282   %elif f.layout == parser.ARRAY:
283      %for (i, c) in enumerate(f.channels):
284         %if c.type != 'x':
285            ${c.datatype()} ${c.name} = src[${i}];
286         %endif
287      %endfor
288   %else:
289      <% assert False %>
290   %endif
291
292   %for i in range(4):
293      <% s = f.swizzle[i] %>
294      %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W:
295         dst[${i}] = ${f.channels[s].name};
296      %elif s == parser.Swizzle.SWIZZLE_ZERO:
297         dst[${i}] = 0;
298      %elif s == parser.Swizzle.SWIZZLE_ONE:
299         dst[${i}] = 1;
300      %else:
301         <% assert False %>
302      %endif
303   %endfor
304}
305%endfor
306
307
308void
309_mesa_unpack_rgba_row(mesa_format format, GLuint n,
310                      const void *src, GLfloat dst[][4])
311{
312   GLubyte *s = (GLubyte *)src;
313   GLuint i;
314
315   switch (format) {
316%for f in rgb_formats:
317   %if f.is_compressed():
318      <% continue %>
319   %elif f.is_int() and not f.is_normalized():
320      <% continue %>
321   %endif
322   case ${f.name}:
323      for (i = 0; i < n; ++i) {
324         unpack_float_${f.short_name()}(s, dst[i]);
325         s += ${f.block_size() // 8};
326      }
327      break;
328%endfor
329   case MESA_FORMAT_YCBCR:
330      unpack_float_ycbcr(src, dst, n);
331      break;
332   case MESA_FORMAT_YCBCR_REV:
333      unpack_float_ycbcr_rev(src, dst, n);
334      break;
335   default:
336      _mesa_problem(NULL, "%s: bad format %s", __func__,
337                    _mesa_get_format_name(format));
338      return;
339   }
340}
341
342void
343_mesa_unpack_ubyte_rgba_row(mesa_format format, GLuint n,
344                            const void *src, GLubyte dst[][4])
345{
346   GLubyte *s = (GLubyte *)src;
347   GLuint i;
348
349   switch (format) {
350%for f in rgb_formats:
351   %if not f.is_normalized():
352      <% continue %>
353   %endif
354
355   case ${f.name}:
356      for (i = 0; i < n; ++i) {
357         unpack_ubyte_${f.short_name()}(s, dst[i]);
358         s += ${f.block_size() // 8};
359      }
360      break;
361%endfor
362   default:
363      /* get float values, convert to ubyte */
364      {
365         GLfloat *tmp = malloc(n * 4 * sizeof(GLfloat));
366         if (tmp) {
367            GLuint i;
368            _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp);
369            for (i = 0; i < n; i++) {
370               dst[i][0] = _mesa_float_to_unorm(tmp[i*4+0], 8);
371               dst[i][1] = _mesa_float_to_unorm(tmp[i*4+1], 8);
372               dst[i][2] = _mesa_float_to_unorm(tmp[i*4+2], 8);
373               dst[i][3] = _mesa_float_to_unorm(tmp[i*4+3], 8);
374            }
375            free(tmp);
376         }
377      }
378      break;
379   }
380}
381
382void
383_mesa_unpack_uint_rgba_row(mesa_format format, GLuint n,
384                           const void *src, GLuint dst[][4])
385{
386   GLubyte *s = (GLubyte *)src;
387   GLuint i;
388
389   switch (format) {
390%for f in rgb_formats:
391   %if not f.is_int():
392      <% continue %>
393   %elif f.is_normalized():
394      <% continue %>
395   %endif
396
397   case ${f.name}:
398      for (i = 0; i < n; ++i) {
399         unpack_int_${f.short_name()}(s, dst[i]);
400         s += ${f.block_size() // 8};
401      }
402      break;
403%endfor
404   default:
405      _mesa_problem(NULL, "%s: bad format %s", __func__,
406                    _mesa_get_format_name(format));
407      return;
408   }
409}
410
411/**
412 * Unpack a 2D rect of pixels returning float RGBA colors.
413 * \param format  the source image format
414 * \param src  start address of the source image
415 * \param srcRowStride  source image row stride in bytes
416 * \param dst  start address of the dest image
417 * \param dstRowStride  dest image row stride in bytes
418 * \param x  source image start X pos
419 * \param y  source image start Y pos
420 * \param width  width of rect region to convert
421 * \param height  height of rect region to convert
422 */
423void
424_mesa_unpack_rgba_block(mesa_format format,
425                        const void *src, GLint srcRowStride,
426                        GLfloat dst[][4], GLint dstRowStride,
427                        GLuint x, GLuint y, GLuint width, GLuint height)
428{
429   const GLuint srcPixStride = _mesa_get_format_bytes(format);
430   const GLuint dstPixStride = 4 * sizeof(GLfloat);
431   const GLubyte *srcRow;
432   GLubyte *dstRow;
433   GLuint i;
434
435   /* XXX needs to be fixed for compressed formats */
436
437   srcRow = ((const GLubyte *) src) + srcRowStride * y + srcPixStride * x;
438   dstRow = ((GLubyte *) dst) + dstRowStride * y + dstPixStride * x;
439
440   for (i = 0; i < height; i++) {
441      _mesa_unpack_rgba_row(format, width, srcRow, (GLfloat (*)[4]) dstRow);
442
443      dstRow += dstRowStride;
444      srcRow += srcRowStride;
445   }
446}
447
448/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */
449struct z32f_x24s8
450{
451   float z;
452   uint32_t x24s8;
453};
454
455typedef void (*unpack_float_z_func)(GLuint n, const void *src, GLfloat *dst);
456
457static void
458unpack_float_z_X8_UINT_Z24_UNORM(GLuint n, const void *src, GLfloat *dst)
459{
460   /* only return Z, not stencil data */
461   const GLuint *s = ((const GLuint *) src);
462   const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
463   GLuint i;
464   for (i = 0; i < n; i++) {
465      dst[i] = (GLfloat) ((s[i] >> 8) * scale);
466      assert(dst[i] >= 0.0F);
467      assert(dst[i] <= 1.0F);
468   }
469}
470
471static void
472unpack_float_z_Z24_UNORM_X8_UINT(GLuint n, const void *src, GLfloat *dst)
473{
474   /* only return Z, not stencil data */
475   const GLuint *s = ((const GLuint *) src);
476   const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
477   GLuint i;
478   for (i = 0; i < n; i++) {
479      dst[i] = (GLfloat) ((s[i] & 0x00ffffff) * scale);
480      assert(dst[i] >= 0.0F);
481      assert(dst[i] <= 1.0F);
482   }
483}
484
485static void
486unpack_float_Z_UNORM16(GLuint n, const void *src, GLfloat *dst)
487{
488   const GLushort *s = ((const GLushort *) src);
489   GLuint i;
490   for (i = 0; i < n; i++) {
491      dst[i] = s[i] * (1.0F / 65535.0F);
492   }
493}
494
495static void
496unpack_float_Z_UNORM32(GLuint n, const void *src, GLfloat *dst)
497{
498   const GLuint *s = ((const GLuint *) src);
499   GLuint i;
500   for (i = 0; i < n; i++) {
501      dst[i] = s[i] * (1.0F / 0xffffffff);
502   }
503}
504
505static void
506unpack_float_Z_FLOAT32(GLuint n, const void *src, GLfloat *dst)
507{
508   memcpy(dst, src, n * sizeof(float));
509}
510
511static void
512unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst)
513{
514   const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src;
515   GLuint i;
516   for (i = 0; i < n; i++) {
517      dst[i] = s[i].z;
518   }
519}
520
521
522
523/**
524 * Unpack Z values.
525 * The returned values will always be in the range [0.0, 1.0].
526 */
527void
528_mesa_unpack_float_z_row(mesa_format format, GLuint n,
529                         const void *src, GLfloat *dst)
530{
531   unpack_float_z_func unpack;
532
533   switch (format) {
534   case MESA_FORMAT_S8_UINT_Z24_UNORM:
535   case MESA_FORMAT_X8_UINT_Z24_UNORM:
536      unpack = unpack_float_z_X8_UINT_Z24_UNORM;
537      break;
538   case MESA_FORMAT_Z24_UNORM_S8_UINT:
539   case MESA_FORMAT_Z24_UNORM_X8_UINT:
540      unpack = unpack_float_z_Z24_UNORM_X8_UINT;
541      break;
542   case MESA_FORMAT_Z_UNORM16:
543      unpack = unpack_float_Z_UNORM16;
544      break;
545   case MESA_FORMAT_Z_UNORM32:
546      unpack = unpack_float_Z_UNORM32;
547      break;
548   case MESA_FORMAT_Z_FLOAT32:
549      unpack = unpack_float_Z_FLOAT32;
550      break;
551   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
552      unpack = unpack_float_z_Z32X24S8;
553      break;
554   default:
555      _mesa_problem(NULL, "bad format %s in _mesa_unpack_float_z_row",
556                    _mesa_get_format_name(format));
557      return;
558   }
559
560   unpack(n, src, dst);
561}
562
563
564
565typedef void (*unpack_uint_z_func)(const void *src, GLuint *dst, GLuint n);
566
567static void
568unpack_uint_z_X8_UINT_Z24_UNORM(const void *src, GLuint *dst, GLuint n)
569{
570   /* only return Z, not stencil data */
571   const GLuint *s = ((const GLuint *) src);
572   GLuint i;
573   for (i = 0; i < n; i++) {
574      dst[i] = (s[i] & 0xffffff00) | (s[i] >> 24);
575   }
576}
577
578static void
579unpack_uint_z_Z24_UNORM_X8_UINT(const void *src, GLuint *dst, GLuint n)
580{
581   /* only return Z, not stencil data */
582   const GLuint *s = ((const GLuint *) src);
583   GLuint i;
584   for (i = 0; i < n; i++) {
585      dst[i] = (s[i] << 8) | ((s[i] >> 16) & 0xff);
586   }
587}
588
589static void
590unpack_uint_Z_UNORM16(const void *src, GLuint *dst, GLuint n)
591{
592   const GLushort *s = ((const GLushort *)src);
593   GLuint i;
594   for (i = 0; i < n; i++) {
595      dst[i] = (s[i] << 16) | s[i];
596   }
597}
598
599static void
600unpack_uint_Z_UNORM32(const void *src, GLuint *dst, GLuint n)
601{
602   memcpy(dst, src, n * sizeof(GLuint));
603}
604
605static void
606unpack_uint_Z_FLOAT32(const void *src, GLuint *dst, GLuint n)
607{
608   const float *s = (const float *)src;
609   GLuint i;
610   for (i = 0; i < n; i++) {
611      dst[i] = FLOAT_TO_UINT(CLAMP(s[i], 0.0F, 1.0F));
612   }
613}
614
615static void
616unpack_uint_Z_FLOAT32_X24S8(const void *src, GLuint *dst, GLuint n)
617{
618   const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src;
619   GLuint i;
620
621   for (i = 0; i < n; i++) {
622      dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F));
623   }
624}
625
626
627/**
628 * Unpack Z values.
629 * The returned values will always be in the range [0, 0xffffffff].
630 */
631void
632_mesa_unpack_uint_z_row(mesa_format format, GLuint n,
633                        const void *src, GLuint *dst)
634{
635   unpack_uint_z_func unpack;
636   const GLubyte *srcPtr = (GLubyte *) src;
637
638   switch (format) {
639   case MESA_FORMAT_S8_UINT_Z24_UNORM:
640   case MESA_FORMAT_X8_UINT_Z24_UNORM:
641      unpack = unpack_uint_z_X8_UINT_Z24_UNORM;
642      break;
643   case MESA_FORMAT_Z24_UNORM_S8_UINT:
644   case MESA_FORMAT_Z24_UNORM_X8_UINT:
645      unpack = unpack_uint_z_Z24_UNORM_X8_UINT;
646      break;
647   case MESA_FORMAT_Z_UNORM16:
648      unpack = unpack_uint_Z_UNORM16;
649      break;
650   case MESA_FORMAT_Z_UNORM32:
651      unpack = unpack_uint_Z_UNORM32;
652      break;
653   case MESA_FORMAT_Z_FLOAT32:
654      unpack = unpack_uint_Z_FLOAT32;
655      break;
656   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
657      unpack = unpack_uint_Z_FLOAT32_X24S8;
658      break;
659   default:
660      _mesa_problem(NULL, "bad format %s in _mesa_unpack_uint_z_row",
661                    _mesa_get_format_name(format));
662      return;
663   }
664
665   unpack(srcPtr, dst, n);
666}
667
668
669static void
670unpack_ubyte_s_S_UINT8(const void *src, GLubyte *dst, GLuint n)
671{
672   memcpy(dst, src, n);
673}
674
675static void
676unpack_ubyte_s_S8_UINT_Z24_UNORM(const void *src, GLubyte *dst, GLuint n)
677{
678   GLuint i;
679   const GLuint *src32 = src;
680
681   for (i = 0; i < n; i++)
682      dst[i] = src32[i] & 0xff;
683}
684
685static void
686unpack_ubyte_s_Z24_UNORM_S8_UINT(const void *src, GLubyte *dst, GLuint n)
687{
688   GLuint i;
689   const GLuint *src32 = src;
690
691   for (i = 0; i < n; i++)
692      dst[i] = src32[i] >> 24;
693}
694
695static void
696unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(const void *src, GLubyte *dst, GLuint n)
697{
698   GLuint i;
699   const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src;
700
701   for (i = 0; i < n; i++)
702      dst[i] = s[i].x24s8 & 0xff;
703}
704
705void
706_mesa_unpack_ubyte_stencil_row(mesa_format format, GLuint n,
707			       const void *src, GLubyte *dst)
708{
709   switch (format) {
710   case MESA_FORMAT_S_UINT8:
711      unpack_ubyte_s_S_UINT8(src, dst, n);
712      break;
713   case MESA_FORMAT_S8_UINT_Z24_UNORM:
714      unpack_ubyte_s_S8_UINT_Z24_UNORM(src, dst, n);
715      break;
716   case MESA_FORMAT_Z24_UNORM_S8_UINT:
717      unpack_ubyte_s_Z24_UNORM_S8_UINT(src, dst, n);
718      break;
719   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
720      unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(src, dst, n);
721      break;
722   default:
723      _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row",
724                    _mesa_get_format_name(format));
725      return;
726   }
727}
728
729static void
730unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const GLuint *src, GLuint *dst, GLuint n)
731{
732   GLuint i;
733
734   for (i = 0; i < n; i++) {
735      GLuint val = src[i];
736      dst[i] = val >> 24 | val << 8;
737   }
738}
739
740static void
741unpack_uint_24_8_depth_stencil_Z32_S8X24(const GLuint *src,
742                                         GLuint *dst, GLuint n)
743{
744   GLuint i;
745
746   for (i = 0; i < n; i++) {
747      /* 8 bytes per pixel (float + uint32) */
748      GLfloat zf = ((GLfloat *) src)[i * 2 + 0];
749      GLuint z24 = (GLuint) (zf * (GLfloat) 0xffffff);
750      GLuint s = src[i * 2 + 1] & 0xff;
751      dst[i] = (z24 << 8) | s;
752   }
753}
754
755static void
756unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const GLuint *src, GLuint *dst, GLuint n)
757{
758   memcpy(dst, src, n * 4);
759}
760
761/**
762 * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8.
763 * \param format  the source data format
764 */
765void
766_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n,
767					 const void *src, GLuint *dst)
768{
769   switch (format) {
770   case MESA_FORMAT_S8_UINT_Z24_UNORM:
771      unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n);
772      break;
773   case MESA_FORMAT_Z24_UNORM_S8_UINT:
774      unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n);
775      break;
776   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
777      unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n);
778      break;
779   default:
780      _mesa_problem(NULL,
781                    "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row",
782                    _mesa_get_format_name(format));
783      return;
784   }
785}
786
787static void
788unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const GLuint *src,
789                                            GLuint *dst, GLuint n)
790{
791   GLuint i;
792   struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
793   const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
794
795   for (i = 0; i < n; i++) {
796      const GLuint z24 = src[i] & 0xffffff;
797      d[i].z = z24 * scale;
798      d[i].x24s8 = src[i] >> 24;
799      assert(d[i].z >= 0.0f);
800      assert(d[i].z <= 1.0f);
801   }
802}
803
804static void
805unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const GLuint *src,
806                                               GLuint *dst, GLuint n)
807{
808   memcpy(dst, src, n * sizeof(struct z32f_x24s8));
809}
810
811static void
812unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const GLuint *src,
813                                            GLuint *dst, GLuint n)
814{
815   GLuint i;
816   struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
817   const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
818
819   for (i = 0; i < n; i++) {
820      const GLuint z24 = src[i] >> 8;
821      d[i].z = z24 * scale;
822      d[i].x24s8 = src[i] & 0xff;
823      assert(d[i].z >= 0.0f);
824      assert(d[i].z <= 1.0f);
825   }
826}
827
828/**
829 * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
830 * \param format  the source data format
831 *
832 * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float
833 * component and higher 4 bytes contain packed 24-bit and 8-bit
834 * components.
835 *
836 *    31 30 29 28 ... 4 3 2 1 0    31 30 29 ... 9 8 7 6 5 ... 2 1 0
837 *    +-------------------------+  +--------------------------------+
838 *    |    Float Component      |  | Unused         | 8 bit stencil |
839 *    +-------------------------+  +--------------------------------+
840 *          lower 4 bytes                  higher 4 bytes
841 */
842void
843_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, GLuint n,
844			                          const void *src, GLuint *dst)
845{
846   switch (format) {
847   case MESA_FORMAT_S8_UINT_Z24_UNORM:
848      unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n);
849      break;
850   case MESA_FORMAT_Z24_UNORM_S8_UINT:
851      unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n);
852      break;
853   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
854      unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n);
855      break;
856   default:
857      _mesa_problem(NULL,
858                    "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row",
859                    _mesa_get_format_name(format));
860      return;
861   }
862}
863
864/**
865 * Unpack depth/stencil
866 * \param format  the source data format
867 * \param type the destination data type
868 */
869void
870_mesa_unpack_depth_stencil_row(mesa_format format, GLuint n,
871	                       const void *src, GLenum type,
872                               GLuint *dst)
873{
874   assert(type == GL_UNSIGNED_INT_24_8 ||
875          type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
876
877   switch (type) {
878   case GL_UNSIGNED_INT_24_8:
879      _mesa_unpack_uint_24_8_depth_stencil_row(format, n, src, dst);
880      break;
881   case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
882      _mesa_unpack_float_32_uint_24_8_depth_stencil_row(format, n, src, dst);
883      break;
884   default:
885      _mesa_problem(NULL,
886                    "bad type 0x%x in _mesa_unpack_depth_stencil_row",
887                    type);
888      return;
889   }
890}
891"""
892
893template = Template(string, future_imports=['division']);
894
895print(template.render(argv = argv[0:]))
896