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