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