Home | History | Annotate | Download | only in unit
      1 /**************************************************************************
      2  *
      3  * Copyright 2009-2010 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 
     29 #include <stdlib.h>
     30 #include <stdio.h>
     31 #include <float.h>
     32 
     33 #include "util/u_half.h"
     34 #include "util/u_format.h"
     35 #include "util/u_format_tests.h"
     36 #include "util/u_format_s3tc.h"
     37 
     38 
     39 static boolean
     40 compare_float(float x, float y)
     41 {
     42    float error = y - x;
     43 
     44    if (error < 0.0f)
     45       error = -error;
     46 
     47    if (error > FLT_EPSILON) {
     48       return FALSE;
     49    }
     50 
     51    return TRUE;
     52 }
     53 
     54 
     55 static void
     56 print_packed(const struct util_format_description *format_desc,
     57              const char *prefix,
     58              const uint8_t *packed,
     59              const char *suffix)
     60 {
     61    unsigned i;
     62    const char *sep = "";
     63 
     64    printf("%s", prefix);
     65    for (i = 0; i < format_desc->block.bits/8; ++i) {
     66       printf("%s%02x", sep, packed[i]);
     67       sep = " ";
     68    }
     69    printf("%s", suffix);
     70    fflush(stdout);
     71 }
     72 
     73 
     74 static void
     75 print_unpacked_rgba_doubl(const struct util_format_description *format_desc,
     76                      const char *prefix,
     77                      const double unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
     78                      const char *suffix)
     79 {
     80    unsigned i, j;
     81    const char *sep = "";
     82 
     83    printf("%s", prefix);
     84    for (i = 0; i < format_desc->block.height; ++i) {
     85       for (j = 0; j < format_desc->block.width; ++j) {
     86          printf("%s{%f, %f, %f, %f}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
     87          sep = ", ";
     88       }
     89       sep = ",\n";
     90    }
     91    printf("%s", suffix);
     92    fflush(stdout);
     93 }
     94 
     95 
     96 static void
     97 print_unpacked_rgba_float(const struct util_format_description *format_desc,
     98                      const char *prefix,
     99                      float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
    100                      const char *suffix)
    101 {
    102    unsigned i, j;
    103    const char *sep = "";
    104 
    105    printf("%s", prefix);
    106    for (i = 0; i < format_desc->block.height; ++i) {
    107       for (j = 0; j < format_desc->block.width; ++j) {
    108          printf("%s{%f, %f, %f, %f}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
    109          sep = ", ";
    110       }
    111       sep = ",\n";
    112    }
    113    printf("%s", suffix);
    114    fflush(stdout);
    115 }
    116 
    117 
    118 static void
    119 print_unpacked_rgba_8unorm(const struct util_format_description *format_desc,
    120                       const char *prefix,
    121                       uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
    122                       const char *suffix)
    123 {
    124    unsigned i, j;
    125    const char *sep = "";
    126 
    127    printf("%s", prefix);
    128    for (i = 0; i < format_desc->block.height; ++i) {
    129       for (j = 0; j < format_desc->block.width; ++j) {
    130          printf("%s{0x%02x, 0x%02x, 0x%02x, 0x%02x}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
    131          sep = ", ";
    132       }
    133    }
    134    printf("%s", suffix);
    135    fflush(stdout);
    136 }
    137 
    138 
    139 static void
    140 print_unpacked_z_float(const struct util_format_description *format_desc,
    141                        const char *prefix,
    142                        float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
    143                        const char *suffix)
    144 {
    145    unsigned i, j;
    146    const char *sep = "";
    147 
    148    printf("%s", prefix);
    149    for (i = 0; i < format_desc->block.height; ++i) {
    150       for (j = 0; j < format_desc->block.width; ++j) {
    151          printf("%s%f", sep, unpacked[i][j]);
    152          sep = ", ";
    153       }
    154       sep = ",\n";
    155    }
    156    printf("%s", suffix);
    157    fflush(stdout);
    158 }
    159 
    160 
    161 static void
    162 print_unpacked_z_32unorm(const struct util_format_description *format_desc,
    163                          const char *prefix,
    164                          uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
    165                          const char *suffix)
    166 {
    167    unsigned i, j;
    168    const char *sep = "";
    169 
    170    printf("%s", prefix);
    171    for (i = 0; i < format_desc->block.height; ++i) {
    172       for (j = 0; j < format_desc->block.width; ++j) {
    173          printf("%s0x%08x", sep, unpacked[i][j]);
    174          sep = ", ";
    175       }
    176    }
    177    printf("%s", suffix);
    178    fflush(stdout);
    179 }
    180 
    181 
    182 static void
    183 print_unpacked_s_8uint(const struct util_format_description *format_desc,
    184                        const char *prefix,
    185                        uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
    186                        const char *suffix)
    187 {
    188    unsigned i, j;
    189    const char *sep = "";
    190 
    191    printf("%s", prefix);
    192    for (i = 0; i < format_desc->block.height; ++i) {
    193       for (j = 0; j < format_desc->block.width; ++j) {
    194          printf("%s0x%02x", sep, unpacked[i][j]);
    195          sep = ", ";
    196       }
    197    }
    198    printf("%s", suffix);
    199    fflush(stdout);
    200 }
    201 
    202 
    203 static boolean
    204 test_format_fetch_rgba_float(const struct util_format_description *format_desc,
    205                              const struct util_format_test_case *test)
    206 {
    207    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
    208    unsigned i, j, k;
    209    boolean success;
    210 
    211    success = TRUE;
    212    for (i = 0; i < format_desc->block.height; ++i) {
    213       for (j = 0; j < format_desc->block.width; ++j) {
    214          format_desc->fetch_rgba_float(unpacked[i][j], test->packed, j, i);
    215          for (k = 0; k < 4; ++k) {
    216             if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
    217                success = FALSE;
    218             }
    219          }
    220       }
    221    }
    222 
    223    if (!success) {
    224       print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
    225       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
    226    }
    227 
    228    return success;
    229 }
    230 
    231 
    232 static boolean
    233 test_format_unpack_rgba_float(const struct util_format_description *format_desc,
    234                               const struct util_format_test_case *test)
    235 {
    236    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
    237    unsigned i, j, k;
    238    boolean success;
    239 
    240    format_desc->unpack_rgba_float(&unpacked[0][0][0], sizeof unpacked[0],
    241                              test->packed, 0,
    242                              format_desc->block.width, format_desc->block.height);
    243 
    244    success = TRUE;
    245    for (i = 0; i < format_desc->block.height; ++i) {
    246       for (j = 0; j < format_desc->block.width; ++j) {
    247          for (k = 0; k < 4; ++k) {
    248             if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
    249                success = FALSE;
    250             }
    251          }
    252       }
    253    }
    254 
    255    if (!success) {
    256       print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
    257       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
    258    }
    259 
    260    return success;
    261 }
    262 
    263 
    264 static boolean
    265 test_format_pack_rgba_float(const struct util_format_description *format_desc,
    266                             const struct util_format_test_case *test)
    267 {
    268    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
    269    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
    270    unsigned i, j, k;
    271    boolean success;
    272 
    273    if (test->format == PIPE_FORMAT_DXT1_RGBA) {
    274       /*
    275        * Skip S3TC as packed representation is not canonical.
    276        *
    277        * TODO: Do a round trip conversion.
    278        */
    279       return TRUE;
    280    }
    281 
    282    memset(packed, 0, sizeof packed);
    283    for (i = 0; i < format_desc->block.height; ++i) {
    284       for (j = 0; j < format_desc->block.width; ++j) {
    285          for (k = 0; k < 4; ++k) {
    286             unpacked[i][j][k] = (float) test->unpacked[i][j][k];
    287          }
    288       }
    289    }
    290 
    291    format_desc->pack_rgba_float(packed, 0,
    292                            &unpacked[0][0][0], sizeof unpacked[0],
    293                            format_desc->block.width, format_desc->block.height);
    294 
    295    success = TRUE;
    296    for (i = 0; i < format_desc->block.bits/8; ++i) {
    297       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
    298          success = FALSE;
    299    }
    300 
    301    /* Ignore NaN */
    302    if (util_is_double_nan(test->unpacked[0][0][0]))
    303       success = TRUE;
    304 
    305    if (!success) {
    306       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
    307       print_packed(format_desc, "        ", test->packed, " expected\n");
    308    }
    309 
    310    return success;
    311 }
    312 
    313 
    314 static boolean
    315 convert_float_to_8unorm(uint8_t *dst, const double *src)
    316 {
    317    unsigned i;
    318    boolean accurate = TRUE;
    319 
    320    for (i = 0; i < UTIL_FORMAT_MAX_UNPACKED_HEIGHT*UTIL_FORMAT_MAX_UNPACKED_WIDTH*4; ++i) {
    321       if (src[i] < 0.0) {
    322          accurate = FALSE;
    323          dst[i] = 0;
    324       }
    325       else if (src[i] > 1.0) {
    326          accurate = FALSE;
    327          dst[i] = 255;
    328       }
    329       else {
    330          dst[i] = src[i] * 255.0;
    331       }
    332    }
    333 
    334    return accurate;
    335 }
    336 
    337 
    338 static boolean
    339 test_format_unpack_rgba_8unorm(const struct util_format_description *format_desc,
    340                                const struct util_format_test_case *test)
    341 {
    342    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
    343    uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
    344    unsigned i, j, k;
    345    boolean success;
    346 
    347    format_desc->unpack_rgba_8unorm(&unpacked[0][0][0], sizeof unpacked[0],
    348                               test->packed, 0,
    349                               format_desc->block.width, format_desc->block.height);
    350 
    351    convert_float_to_8unorm(&expected[0][0][0], &test->unpacked[0][0][0]);
    352 
    353    success = TRUE;
    354    for (i = 0; i < format_desc->block.height; ++i) {
    355       for (j = 0; j < format_desc->block.width; ++j) {
    356          for (k = 0; k < 4; ++k) {
    357             if (expected[i][j][k] != unpacked[i][j][k]) {
    358                success = FALSE;
    359             }
    360          }
    361       }
    362    }
    363 
    364    /* Ignore NaN */
    365    if (util_is_double_nan(test->unpacked[0][0][0]))
    366       success = TRUE;
    367 
    368    if (!success) {
    369       print_unpacked_rgba_8unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
    370       print_unpacked_rgba_8unorm(format_desc, "        ", expected, " expected\n");
    371    }
    372 
    373    return success;
    374 }
    375 
    376 
    377 static boolean
    378 test_format_pack_rgba_8unorm(const struct util_format_description *format_desc,
    379                              const struct util_format_test_case *test)
    380 {
    381    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
    382    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
    383    unsigned i;
    384    boolean success;
    385 
    386    if (test->format == PIPE_FORMAT_DXT1_RGBA) {
    387       /*
    388        * Skip S3TC as packed representation is not canonical.
    389        *
    390        * TODO: Do a round trip conversion.
    391        */
    392       return TRUE;
    393    }
    394 
    395    if (!convert_float_to_8unorm(&unpacked[0][0][0], &test->unpacked[0][0][0])) {
    396       /*
    397        * Skip test cases which cannot be represented by four unorm bytes.
    398        */
    399       return TRUE;
    400    }
    401 
    402    memset(packed, 0, sizeof packed);
    403 
    404    format_desc->pack_rgba_8unorm(packed, 0,
    405                             &unpacked[0][0][0], sizeof unpacked[0],
    406                             format_desc->block.width, format_desc->block.height);
    407 
    408    success = TRUE;
    409    for (i = 0; i < format_desc->block.bits/8; ++i)
    410       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
    411          success = FALSE;
    412 
    413    /* Ignore NaN */
    414    if (util_is_double_nan(test->unpacked[0][0][0]))
    415       success = TRUE;
    416 
    417    /* Ignore failure cases due to unorm8 format */
    418    if (test->unpacked[0][0][0] > 1.0f || test->unpacked[0][0][0] < 0.0f)
    419       success = TRUE;
    420 
    421    /* Multiple of 255 */
    422    if ((test->unpacked[0][0][0] * 255.0) != (int)(test->unpacked[0][0][0] * 255.0))
    423       success = TRUE;
    424 
    425    if (!success) {
    426       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
    427       print_packed(format_desc, "        ", test->packed, " expected\n");
    428    }
    429 
    430    return success;
    431 }
    432 
    433 
    434 static boolean
    435 test_format_unpack_z_float(const struct util_format_description *format_desc,
    436                               const struct util_format_test_case *test)
    437 {
    438    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
    439    unsigned i, j;
    440    boolean success;
    441 
    442    format_desc->unpack_z_float(&unpacked[0][0], sizeof unpacked[0],
    443                                test->packed, 0,
    444                                format_desc->block.width, format_desc->block.height);
    445 
    446    success = TRUE;
    447    for (i = 0; i < format_desc->block.height; ++i) {
    448       for (j = 0; j < format_desc->block.width; ++j) {
    449          if (!compare_float(test->unpacked[i][j][0], unpacked[i][j])) {
    450             success = FALSE;
    451          }
    452       }
    453    }
    454 
    455    if (!success) {
    456       print_unpacked_z_float(format_desc, "FAILED: ", unpacked, " obtained\n");
    457       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
    458    }
    459 
    460    return success;
    461 }
    462 
    463 
    464 static boolean
    465 test_format_pack_z_float(const struct util_format_description *format_desc,
    466                             const struct util_format_test_case *test)
    467 {
    468    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
    469    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
    470    unsigned i, j;
    471    boolean success;
    472 
    473    memset(packed, 0, sizeof packed);
    474    for (i = 0; i < format_desc->block.height; ++i) {
    475       for (j = 0; j < format_desc->block.width; ++j) {
    476          unpacked[i][j] = (float) test->unpacked[i][j][0];
    477          if (test->unpacked[i][j][1]) {
    478             return TRUE;
    479          }
    480       }
    481    }
    482 
    483    format_desc->pack_z_float(packed, 0,
    484                              &unpacked[0][0], sizeof unpacked[0],
    485                              format_desc->block.width, format_desc->block.height);
    486 
    487    success = TRUE;
    488    for (i = 0; i < format_desc->block.bits/8; ++i)
    489       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
    490          success = FALSE;
    491 
    492    if (!success) {
    493       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
    494       print_packed(format_desc, "        ", test->packed, " expected\n");
    495    }
    496 
    497    return success;
    498 }
    499 
    500 
    501 static boolean
    502 test_format_unpack_z_32unorm(const struct util_format_description *format_desc,
    503                                const struct util_format_test_case *test)
    504 {
    505    uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
    506    uint32_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
    507    unsigned i, j;
    508    boolean success;
    509 
    510    format_desc->unpack_z_32unorm(&unpacked[0][0], sizeof unpacked[0],
    511                                  test->packed, 0,
    512                                  format_desc->block.width, format_desc->block.height);
    513 
    514    for (i = 0; i < format_desc->block.height; ++i) {
    515       for (j = 0; j < format_desc->block.width; ++j) {
    516          expected[i][j] = test->unpacked[i][j][0] * 0xffffffff;
    517       }
    518    }
    519 
    520    success = TRUE;
    521    for (i = 0; i < format_desc->block.height; ++i) {
    522       for (j = 0; j < format_desc->block.width; ++j) {
    523          if (expected[i][j] != unpacked[i][j]) {
    524             success = FALSE;
    525          }
    526       }
    527    }
    528 
    529    if (!success) {
    530       print_unpacked_z_32unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
    531       print_unpacked_z_32unorm(format_desc, "        ", expected, " expected\n");
    532    }
    533 
    534    return success;
    535 }
    536 
    537 
    538 static boolean
    539 test_format_pack_z_32unorm(const struct util_format_description *format_desc,
    540                              const struct util_format_test_case *test)
    541 {
    542    uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
    543    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
    544    unsigned i, j;
    545    boolean success;
    546 
    547    for (i = 0; i < format_desc->block.height; ++i) {
    548       for (j = 0; j < format_desc->block.width; ++j) {
    549          unpacked[i][j] = test->unpacked[i][j][0] * 0xffffffff;
    550          if (test->unpacked[i][j][1]) {
    551             return TRUE;
    552          }
    553       }
    554    }
    555 
    556    memset(packed, 0, sizeof packed);
    557 
    558    format_desc->pack_z_32unorm(packed, 0,
    559                                &unpacked[0][0], sizeof unpacked[0],
    560                                format_desc->block.width, format_desc->block.height);
    561 
    562    success = TRUE;
    563    for (i = 0; i < format_desc->block.bits/8; ++i)
    564       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
    565          success = FALSE;
    566 
    567    if (!success) {
    568       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
    569       print_packed(format_desc, "        ", test->packed, " expected\n");
    570    }
    571 
    572    return success;
    573 }
    574 
    575 
    576 static boolean
    577 test_format_unpack_s_8uint(const struct util_format_description *format_desc,
    578                                const struct util_format_test_case *test)
    579 {
    580    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
    581    uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
    582    unsigned i, j;
    583    boolean success;
    584 
    585    format_desc->unpack_s_8uint(&unpacked[0][0], sizeof unpacked[0],
    586                                   test->packed, 0,
    587                                   format_desc->block.width, format_desc->block.height);
    588 
    589    for (i = 0; i < format_desc->block.height; ++i) {
    590       for (j = 0; j < format_desc->block.width; ++j) {
    591          expected[i][j] = test->unpacked[i][j][1];
    592       }
    593    }
    594 
    595    success = TRUE;
    596    for (i = 0; i < format_desc->block.height; ++i) {
    597       for (j = 0; j < format_desc->block.width; ++j) {
    598          if (expected[i][j] != unpacked[i][j]) {
    599             success = FALSE;
    600          }
    601       }
    602    }
    603 
    604    if (!success) {
    605       print_unpacked_s_8uint(format_desc, "FAILED: ", unpacked, " obtained\n");
    606       print_unpacked_s_8uint(format_desc, "        ", expected, " expected\n");
    607    }
    608 
    609    return success;
    610 }
    611 
    612 
    613 static boolean
    614 test_format_pack_s_8uint(const struct util_format_description *format_desc,
    615                              const struct util_format_test_case *test)
    616 {
    617    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
    618    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
    619    unsigned i, j;
    620    boolean success;
    621 
    622    for (i = 0; i < format_desc->block.height; ++i) {
    623       for (j = 0; j < format_desc->block.width; ++j) {
    624          unpacked[i][j] = test->unpacked[i][j][1];
    625          if (test->unpacked[i][j][0]) {
    626             return TRUE;
    627          }
    628       }
    629    }
    630 
    631    memset(packed, 0, sizeof packed);
    632 
    633    format_desc->pack_s_8uint(packed, 0,
    634                                 &unpacked[0][0], sizeof unpacked[0],
    635                                 format_desc->block.width, format_desc->block.height);
    636 
    637    success = TRUE;
    638    for (i = 0; i < format_desc->block.bits/8; ++i)
    639       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
    640          success = FALSE;
    641 
    642    if (!success) {
    643       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
    644       print_packed(format_desc, "        ", test->packed, " expected\n");
    645    }
    646 
    647    return success;
    648 }
    649 
    650 
    651 typedef boolean
    652 (*test_func_t)(const struct util_format_description *format_desc,
    653                const struct util_format_test_case *test);
    654 
    655 
    656 static boolean
    657 test_one_func(const struct util_format_description *format_desc,
    658               test_func_t func,
    659               const char *suffix)
    660 {
    661    unsigned i;
    662    boolean success = TRUE;
    663 
    664    printf("Testing util_format_%s_%s ...\n",
    665           format_desc->short_name, suffix);
    666    fflush(stdout);
    667 
    668    for (i = 0; i < util_format_nr_test_cases; ++i) {
    669       const struct util_format_test_case *test = &util_format_test_cases[i];
    670 
    671       if (test->format == format_desc->format) {
    672          if (!func(format_desc, &util_format_test_cases[i])) {
    673            success = FALSE;
    674          }
    675       }
    676    }
    677 
    678    return success;
    679 }
    680 
    681 
    682 static boolean
    683 test_all(void)
    684 {
    685    enum pipe_format format;
    686    boolean success = TRUE;
    687 
    688    for (format = 1; format < PIPE_FORMAT_COUNT; ++format) {
    689       const struct util_format_description *format_desc;
    690 
    691       format_desc = util_format_description(format);
    692       if (!format_desc) {
    693          continue;
    694       }
    695 
    696       if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC &&
    697           !util_format_s3tc_enabled) {
    698          continue;
    699       }
    700 
    701 #     define TEST_ONE_FUNC(name) \
    702       if (format_desc->name) { \
    703          if (!test_one_func(format_desc, &test_format_##name, #name)) { \
    704            success = FALSE; \
    705          } \
    706       }
    707 
    708       TEST_ONE_FUNC(fetch_rgba_float);
    709       TEST_ONE_FUNC(pack_rgba_float);
    710       TEST_ONE_FUNC(unpack_rgba_float);
    711       TEST_ONE_FUNC(pack_rgba_8unorm);
    712       TEST_ONE_FUNC(unpack_rgba_8unorm);
    713 
    714       TEST_ONE_FUNC(unpack_z_32unorm);
    715       TEST_ONE_FUNC(pack_z_32unorm);
    716       TEST_ONE_FUNC(unpack_z_float);
    717       TEST_ONE_FUNC(pack_z_float);
    718       TEST_ONE_FUNC(unpack_s_8uint);
    719       TEST_ONE_FUNC(pack_s_8uint);
    720 
    721 #     undef TEST_ONE_FUNC
    722    }
    723 
    724    return success;
    725 }
    726 
    727 
    728 int main(int argc, char **argv)
    729 {
    730    boolean success;
    731 
    732    util_format_s3tc_init();
    733 
    734    success = test_all();
    735 
    736    return success ? 0 : 1;
    737 }
    738