• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
compare_float(float x,float y)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
print_packed(const struct util_format_description * format_desc,const char * prefix,const uint8_t * packed,const char * suffix)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
print_unpacked_rgba_doubl(const struct util_format_description * format_desc,const char * prefix,const double unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],const char * suffix)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
print_unpacked_rgba_float(const struct util_format_description * format_desc,const char * prefix,float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],const char * suffix)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
print_unpacked_rgba_8unorm(const struct util_format_description * format_desc,const char * prefix,uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],const char * suffix)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
print_unpacked_z_float(const struct util_format_description * format_desc,const char * prefix,float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],const char * suffix)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
print_unpacked_z_32unorm(const struct util_format_description * format_desc,const char * prefix,uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],const char * suffix)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
print_unpacked_s_8uint(const struct util_format_description * format_desc,const char * prefix,uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],const char * suffix)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
test_format_fetch_rgba_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_unpack_rgba_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_pack_rgba_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
convert_float_to_8unorm(uint8_t * dst,const double * src)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
test_format_unpack_rgba_8unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_pack_rgba_8unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_unpack_z_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_pack_z_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_unpack_z_32unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_pack_z_32unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_unpack_s_8uint(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_format_pack_s_8uint(const struct util_format_description * format_desc,const struct util_format_test_case * test)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
test_one_func(const struct util_format_description * format_desc,test_func_t func,const char * suffix)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
test_all(void)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       assert(format_desc->block.bits   <= UTIL_FORMAT_MAX_PACKED_BYTES * 8);
697       assert(format_desc->block.height <= UTIL_FORMAT_MAX_UNPACKED_HEIGHT);
698       assert(format_desc->block.width  <= UTIL_FORMAT_MAX_UNPACKED_WIDTH);
699 
700       if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC &&
701           !util_format_s3tc_enabled) {
702          continue;
703       }
704 
705 #     define TEST_ONE_FUNC(name) \
706       if (format_desc->name) { \
707          if (!test_one_func(format_desc, &test_format_##name, #name)) { \
708            success = FALSE; \
709          } \
710       }
711 
712       TEST_ONE_FUNC(fetch_rgba_float);
713       TEST_ONE_FUNC(pack_rgba_float);
714       TEST_ONE_FUNC(unpack_rgba_float);
715       TEST_ONE_FUNC(pack_rgba_8unorm);
716       TEST_ONE_FUNC(unpack_rgba_8unorm);
717 
718       TEST_ONE_FUNC(unpack_z_32unorm);
719       TEST_ONE_FUNC(pack_z_32unorm);
720       TEST_ONE_FUNC(unpack_z_float);
721       TEST_ONE_FUNC(pack_z_float);
722       TEST_ONE_FUNC(unpack_s_8uint);
723       TEST_ONE_FUNC(pack_s_8uint);
724 
725 #     undef TEST_ONE_FUNC
726    }
727 
728    return success;
729 }
730 
731 
main(int argc,char ** argv)732 int main(int argc, char **argv)
733 {
734    boolean success;
735 
736    util_format_s3tc_init();
737 
738    success = test_all();
739 
740    return success ? 0 : 1;
741 }
742