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#include <stdlib.h>
46
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, float 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, float dst[4])
139{
140   rgb9e5_to_float3(*(const uint32_t *)src, dst);
141   dst[3] = 1.0f;
142}
143
144static void
145unpack_float_r11g11b10_float(const void *src, float dst[4])
146{
147   r11g11b10f_to_float3(*(const uint32_t *)src, dst);
148   dst[3] = 1.0f;
149}
150
151static void
152unpack_float_ycbcr(const void *src, float dst[][4], uint32_t n)
153{
154   uint32_t i;
155   for (i = 0; i < n; i++) {
156      const uint16_t *src0 = ((const uint16_t *) src) + i * 2; /* even */
157      const uint16_t *src1 = src0 + 1;         /* odd */
158      const uint8_t y0 = (*src0 >> 8) & 0xff;  /* luminance */
159      const uint8_t cb = *src0 & 0xff;         /* chroma U */
160      const uint8_t y1 = (*src1 >> 8) & 0xff;  /* luminance */
161      const uint8_t cr = *src1 & 0xff;         /* chroma V */
162      const uint8_t y = (i & 1) ? y1 : y0;     /* choose even/odd luminance */
163      float r = 1.164F * (y - 16) + 1.596F * (cr - 128);
164      float g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128);
165      float 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, float dst[][4], uint32_t n)
178{
179   uint32_t i;
180   for (i = 0; i < n; i++) {
181      const uint16_t *src0 = ((const uint16_t *) src) + i * 2; /* even */
182      const uint16_t *src1 = src0 + 1;         /* odd */
183      const uint8_t y0 = *src0 & 0xff;         /* luminance */
184      const uint8_t cr = (*src0 >> 8) & 0xff;  /* chroma V */
185      const uint8_t y1 = *src1 & 0xff;         /* luminance */
186      const uint8_t cb = (*src1 >> 8) & 0xff;  /* chroma U */
187      const uint8_t y = (i & 1) ? y1 : y0;     /* choose even/odd luminance */
188      float r = 1.164F * (y - 16) + 1.596F * (cr - 128);
189      float g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128);
190      float 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, uint8_t 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, uint32_t 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, uint32_t n,
310                      const void *src, float dst[][4])
311{
312   uint8_t *s = (uint8_t *)src;
313   uint32_t 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      unreachable("bad format");
337   }
338}
339
340void
341_mesa_unpack_ubyte_rgba_row(mesa_format format, uint32_t n,
342                            const void *src, uint8_t dst[][4])
343{
344   uint8_t *s = (uint8_t *)src;
345   uint32_t 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         float *tmp = malloc(n * 4 * sizeof(float));
364         if (tmp) {
365            uint32_t i;
366            _mesa_unpack_rgba_row(format, n, src, (float (*)[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, uint32_t n,
382                           const void *src, uint32_t dst[][4])
383{
384   uint8_t *s = (uint8_t *)src;
385   uint32_t 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      unreachable("bad format");
404   }
405}
406
407/**
408 * Unpack a 2D rect of pixels returning float RGBA colors.
409 * \param format  the source image format
410 * \param src  start address of the source image
411 * \param srcRowStride  source image row stride in bytes
412 * \param dst  start address of the dest image
413 * \param dstRowStride  dest image row stride in bytes
414 * \param x  source image start X pos
415 * \param y  source image start Y pos
416 * \param width  width of rect region to convert
417 * \param height  height of rect region to convert
418 */
419void
420_mesa_unpack_rgba_block(mesa_format format,
421                        const void *src, int32_t srcRowStride,
422                        float dst[][4], int32_t dstRowStride,
423                        uint32_t x, uint32_t y, uint32_t width, uint32_t height)
424{
425   const uint32_t srcPixStride = _mesa_get_format_bytes(format);
426   const uint32_t dstPixStride = 4 * sizeof(float);
427   const uint8_t *srcRow;
428   uint8_t *dstRow;
429   uint32_t i;
430
431   /* XXX needs to be fixed for compressed formats */
432
433   srcRow = ((const uint8_t *) src) + srcRowStride * y + srcPixStride * x;
434   dstRow = ((uint8_t *) dst) + dstRowStride * y + dstPixStride * x;
435
436   for (i = 0; i < height; i++) {
437      _mesa_unpack_rgba_row(format, width, srcRow, (float (*)[4]) dstRow);
438
439      dstRow += dstRowStride;
440      srcRow += srcRowStride;
441   }
442}
443
444/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */
445struct z32f_x24s8
446{
447   float z;
448   uint32_t x24s8;
449};
450
451typedef void (*unpack_float_z_func)(uint32_t n, const void *src, float *dst);
452
453static void
454unpack_float_z_X8_UINT_Z24_UNORM(uint32_t n, const void *src, float *dst)
455{
456   /* only return Z, not stencil data */
457   const uint32_t *s = ((const uint32_t *) src);
458   const double scale = 1.0 / (double) 0xffffff;
459   uint32_t i;
460   for (i = 0; i < n; i++) {
461      dst[i] = (float) ((s[i] >> 8) * scale);
462      assert(dst[i] >= 0.0F);
463      assert(dst[i] <= 1.0F);
464   }
465}
466
467static void
468unpack_float_z_Z24_UNORM_X8_UINT(uint32_t n, const void *src, float *dst)
469{
470   /* only return Z, not stencil data */
471   const uint32_t *s = ((const uint32_t *) src);
472   const double scale = 1.0 / (double) 0xffffff;
473   uint32_t i;
474   for (i = 0; i < n; i++) {
475      dst[i] = (float) ((s[i] & 0x00ffffff) * scale);
476      assert(dst[i] >= 0.0F);
477      assert(dst[i] <= 1.0F);
478   }
479}
480
481static void
482unpack_float_Z_UNORM16(uint32_t n, const void *src, float *dst)
483{
484   const uint16_t *s = ((const uint16_t *) src);
485   uint32_t i;
486   for (i = 0; i < n; i++) {
487      dst[i] = s[i] * (1.0F / 65535.0F);
488   }
489}
490
491static void
492unpack_float_Z_UNORM32(uint32_t n, const void *src, float *dst)
493{
494   const uint32_t *s = ((const uint32_t *) src);
495   uint32_t i;
496   for (i = 0; i < n; i++) {
497      dst[i] = s[i] * (1.0F / 0xffffffff);
498   }
499}
500
501static void
502unpack_float_Z_FLOAT32(uint32_t n, const void *src, float *dst)
503{
504   memcpy(dst, src, n * sizeof(float));
505}
506
507static void
508unpack_float_z_Z32X24S8(uint32_t n, const void *src, float *dst)
509{
510   const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src;
511   uint32_t i;
512   for (i = 0; i < n; i++) {
513      dst[i] = s[i].z;
514   }
515}
516
517
518
519/**
520 * Unpack Z values.
521 * The returned values will always be in the range [0.0, 1.0].
522 */
523void
524_mesa_unpack_float_z_row(mesa_format format, uint32_t n,
525                         const void *src, float *dst)
526{
527   unpack_float_z_func unpack;
528
529   switch (format) {
530   case MESA_FORMAT_S8_UINT_Z24_UNORM:
531   case MESA_FORMAT_X8_UINT_Z24_UNORM:
532      unpack = unpack_float_z_X8_UINT_Z24_UNORM;
533      break;
534   case MESA_FORMAT_Z24_UNORM_S8_UINT:
535   case MESA_FORMAT_Z24_UNORM_X8_UINT:
536      unpack = unpack_float_z_Z24_UNORM_X8_UINT;
537      break;
538   case MESA_FORMAT_Z_UNORM16:
539      unpack = unpack_float_Z_UNORM16;
540      break;
541   case MESA_FORMAT_Z_UNORM32:
542      unpack = unpack_float_Z_UNORM32;
543      break;
544   case MESA_FORMAT_Z_FLOAT32:
545      unpack = unpack_float_Z_FLOAT32;
546      break;
547   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
548      unpack = unpack_float_z_Z32X24S8;
549      break;
550   default:
551      unreachable("bad format in _mesa_unpack_float_z_row");
552   }
553
554   unpack(n, src, dst);
555}
556
557
558
559typedef void (*unpack_uint_z_func)(const void *src, uint32_t *dst, uint32_t n);
560
561static void
562unpack_uint_z_X8_UINT_Z24_UNORM(const void *src, uint32_t *dst, uint32_t n)
563{
564   /* only return Z, not stencil data */
565   const uint32_t *s = ((const uint32_t *) src);
566   uint32_t i;
567   for (i = 0; i < n; i++) {
568      dst[i] = (s[i] & 0xffffff00) | (s[i] >> 24);
569   }
570}
571
572static void
573unpack_uint_z_Z24_UNORM_X8_UINT(const void *src, uint32_t *dst, uint32_t n)
574{
575   /* only return Z, not stencil data */
576   const uint32_t *s = ((const uint32_t *) src);
577   uint32_t i;
578   for (i = 0; i < n; i++) {
579      dst[i] = (s[i] << 8) | ((s[i] >> 16) & 0xff);
580   }
581}
582
583static void
584unpack_uint_Z_UNORM16(const void *src, uint32_t *dst, uint32_t n)
585{
586   const uint16_t *s = ((const uint16_t *)src);
587   uint32_t i;
588   for (i = 0; i < n; i++) {
589      dst[i] = (s[i] << 16) | s[i];
590   }
591}
592
593static void
594unpack_uint_Z_UNORM32(const void *src, uint32_t *dst, uint32_t n)
595{
596   memcpy(dst, src, n * sizeof(uint32_t));
597}
598
599static void
600unpack_uint_Z_FLOAT32(const void *src, uint32_t *dst, uint32_t n)
601{
602   const float *s = (const float *)src;
603   uint32_t i;
604   for (i = 0; i < n; i++) {
605      dst[i] = FLOAT_TO_UINT(CLAMP(s[i], 0.0F, 1.0F));
606   }
607}
608
609static void
610unpack_uint_Z_FLOAT32_X24S8(const void *src, uint32_t *dst, uint32_t n)
611{
612   const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src;
613   uint32_t i;
614
615   for (i = 0; i < n; i++) {
616      dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F));
617   }
618}
619
620
621/**
622 * Unpack Z values.
623 * The returned values will always be in the range [0, 0xffffffff].
624 */
625void
626_mesa_unpack_uint_z_row(mesa_format format, uint32_t n,
627                        const void *src, uint32_t *dst)
628{
629   unpack_uint_z_func unpack;
630   const uint8_t *srcPtr = (uint8_t *) src;
631
632   switch (format) {
633   case MESA_FORMAT_S8_UINT_Z24_UNORM:
634   case MESA_FORMAT_X8_UINT_Z24_UNORM:
635      unpack = unpack_uint_z_X8_UINT_Z24_UNORM;
636      break;
637   case MESA_FORMAT_Z24_UNORM_S8_UINT:
638   case MESA_FORMAT_Z24_UNORM_X8_UINT:
639      unpack = unpack_uint_z_Z24_UNORM_X8_UINT;
640      break;
641   case MESA_FORMAT_Z_UNORM16:
642      unpack = unpack_uint_Z_UNORM16;
643      break;
644   case MESA_FORMAT_Z_UNORM32:
645      unpack = unpack_uint_Z_UNORM32;
646      break;
647   case MESA_FORMAT_Z_FLOAT32:
648      unpack = unpack_uint_Z_FLOAT32;
649      break;
650   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
651      unpack = unpack_uint_Z_FLOAT32_X24S8;
652      break;
653   default:
654      unreachable("bad format %s in _mesa_unpack_uint_z_row");
655   }
656
657   unpack(srcPtr, dst, n);
658}
659
660
661static void
662unpack_ubyte_s_S_UINT8(const void *src, uint8_t *dst, uint32_t n)
663{
664   memcpy(dst, src, n);
665}
666
667static void
668unpack_ubyte_s_S8_UINT_Z24_UNORM(const void *src, uint8_t *dst, uint32_t n)
669{
670   uint32_t i;
671   const uint32_t *src32 = src;
672
673   for (i = 0; i < n; i++)
674      dst[i] = src32[i] & 0xff;
675}
676
677static void
678unpack_ubyte_s_Z24_UNORM_S8_UINT(const void *src, uint8_t *dst, uint32_t n)
679{
680   uint32_t i;
681   const uint32_t *src32 = src;
682
683   for (i = 0; i < n; i++)
684      dst[i] = src32[i] >> 24;
685}
686
687static void
688unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(const void *src, uint8_t *dst, uint32_t n)
689{
690   uint32_t i;
691   const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src;
692
693   for (i = 0; i < n; i++)
694      dst[i] = s[i].x24s8 & 0xff;
695}
696
697void
698_mesa_unpack_ubyte_stencil_row(mesa_format format, uint32_t n,
699			       const void *src, uint8_t *dst)
700{
701   switch (format) {
702   case MESA_FORMAT_S_UINT8:
703      unpack_ubyte_s_S_UINT8(src, dst, n);
704      break;
705   case MESA_FORMAT_S8_UINT_Z24_UNORM:
706      unpack_ubyte_s_S8_UINT_Z24_UNORM(src, dst, n);
707      break;
708   case MESA_FORMAT_Z24_UNORM_S8_UINT:
709      unpack_ubyte_s_Z24_UNORM_S8_UINT(src, dst, n);
710      break;
711   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
712      unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(src, dst, n);
713      break;
714   default:
715      unreachable("bad format %s in _mesa_unpack_ubyte_s_row");
716   }
717}
718
719static void
720unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const uint32_t *src, uint32_t *dst, uint32_t n)
721{
722   uint32_t i;
723
724   for (i = 0; i < n; i++) {
725      uint32_t val = src[i];
726      dst[i] = val >> 24 | val << 8;
727   }
728}
729
730static void
731unpack_uint_24_8_depth_stencil_Z32_S8X24(const uint32_t *src,
732                                         uint32_t *dst, uint32_t n)
733{
734   uint32_t i;
735
736   for (i = 0; i < n; i++) {
737      /* 8 bytes per pixel (float + uint32) */
738      float zf = ((float *) src)[i * 2 + 0];
739      uint32_t z24 = (uint32_t) (zf * (float) 0xffffff);
740      uint32_t s = src[i * 2 + 1] & 0xff;
741      dst[i] = (z24 << 8) | s;
742   }
743}
744
745static void
746unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const uint32_t *src, uint32_t *dst, uint32_t n)
747{
748   memcpy(dst, src, n * 4);
749}
750
751/**
752 * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8.
753 * \param format  the source data format
754 */
755void
756_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, uint32_t n,
757					 const void *src, uint32_t *dst)
758{
759   switch (format) {
760   case MESA_FORMAT_S8_UINT_Z24_UNORM:
761      unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n);
762      break;
763   case MESA_FORMAT_Z24_UNORM_S8_UINT:
764      unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n);
765      break;
766   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
767      unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n);
768      break;
769   default:
770      unreachable("bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row");
771   }
772}
773
774static void
775unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const uint32_t *src,
776                                            uint32_t *dst, uint32_t n)
777{
778   uint32_t i;
779   struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
780   const double scale = 1.0 / (double) 0xffffff;
781
782   for (i = 0; i < n; i++) {
783      const uint32_t z24 = src[i] & 0xffffff;
784      d[i].z = z24 * scale;
785      d[i].x24s8 = src[i] >> 24;
786      assert(d[i].z >= 0.0f);
787      assert(d[i].z <= 1.0f);
788   }
789}
790
791static void
792unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const uint32_t *src,
793                                               uint32_t *dst, uint32_t n)
794{
795   memcpy(dst, src, n * sizeof(struct z32f_x24s8));
796}
797
798static void
799unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const uint32_t *src,
800                                            uint32_t *dst, uint32_t n)
801{
802   uint32_t i;
803   struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
804   const double scale = 1.0 / (double) 0xffffff;
805
806   for (i = 0; i < n; i++) {
807      const uint32_t z24 = src[i] >> 8;
808      d[i].z = z24 * scale;
809      d[i].x24s8 = src[i] & 0xff;
810      assert(d[i].z >= 0.0f);
811      assert(d[i].z <= 1.0f);
812   }
813}
814
815/**
816 * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV.
817 * \param format  the source data format
818 *
819 * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float
820 * component and higher 4 bytes contain packed 24-bit and 8-bit
821 * components.
822 *
823 *    31 30 29 28 ... 4 3 2 1 0    31 30 29 ... 9 8 7 6 5 ... 2 1 0
824 *    +-------------------------+  +--------------------------------+
825 *    |    Float Component      |  | Unused         | 8 bit stencil |
826 *    +-------------------------+  +--------------------------------+
827 *          lower 4 bytes                  higher 4 bytes
828 */
829void
830_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, uint32_t n,
831			                          const void *src, uint32_t *dst)
832{
833   switch (format) {
834   case MESA_FORMAT_S8_UINT_Z24_UNORM:
835      unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n);
836      break;
837   case MESA_FORMAT_Z24_UNORM_S8_UINT:
838      unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n);
839      break;
840   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
841      unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n);
842      break;
843   default:
844      unreachable("bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row");
845   }
846}
847
848"""
849
850template = Template(string, future_imports=['division']);
851
852print(template.render(argv = argv[0:]))
853