• 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    /* Ignore S3TC errors */
224    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
225       success = TRUE;
226    }
227 
228    if (!success) {
229       print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
230       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
231    }
232 
233    return success;
234 }
235 
236 
237 static boolean
test_format_unpack_rgba_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)238 test_format_unpack_rgba_float(const struct util_format_description *format_desc,
239                               const struct util_format_test_case *test)
240 {
241    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
242    unsigned i, j, k;
243    boolean success;
244 
245    format_desc->unpack_rgba_float(&unpacked[0][0][0], sizeof unpacked[0],
246                              test->packed, 0,
247                              format_desc->block.width, format_desc->block.height);
248 
249    success = TRUE;
250    for (i = 0; i < format_desc->block.height; ++i) {
251       for (j = 0; j < format_desc->block.width; ++j) {
252          for (k = 0; k < 4; ++k) {
253             if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
254                success = FALSE;
255             }
256          }
257       }
258    }
259 
260    /* Ignore S3TC errors */
261    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
262       success = TRUE;
263    }
264 
265    if (!success) {
266       print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
267       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
268    }
269 
270    return success;
271 }
272 
273 
274 static boolean
test_format_pack_rgba_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)275 test_format_pack_rgba_float(const struct util_format_description *format_desc,
276                             const struct util_format_test_case *test)
277 {
278    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
279    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
280    unsigned i, j, k;
281    boolean success;
282 
283    if (test->format == PIPE_FORMAT_DXT1_RGBA) {
284       /*
285        * Skip S3TC as packed representation is not canonical.
286        *
287        * TODO: Do a round trip conversion.
288        */
289       return TRUE;
290    }
291 
292    memset(packed, 0, sizeof packed);
293    for (i = 0; i < format_desc->block.height; ++i) {
294       for (j = 0; j < format_desc->block.width; ++j) {
295          for (k = 0; k < 4; ++k) {
296             unpacked[i][j][k] = (float) test->unpacked[i][j][k];
297          }
298       }
299    }
300 
301    format_desc->pack_rgba_float(packed, 0,
302                            &unpacked[0][0][0], sizeof unpacked[0],
303                            format_desc->block.width, format_desc->block.height);
304 
305    success = TRUE;
306    for (i = 0; i < format_desc->block.bits/8; ++i) {
307       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
308          success = FALSE;
309    }
310 
311    /* Ignore NaN */
312    if (util_is_double_nan(test->unpacked[0][0][0]))
313       success = TRUE;
314 
315    /* Ignore S3TC errors */
316    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
317       success = TRUE;
318    }
319 
320    if (!success) {
321       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
322       print_packed(format_desc, "        ", test->packed, " expected\n");
323    }
324 
325    return success;
326 }
327 
328 
329 static boolean
convert_float_to_8unorm(uint8_t * dst,const double * src)330 convert_float_to_8unorm(uint8_t *dst, const double *src)
331 {
332    unsigned i;
333    boolean accurate = TRUE;
334 
335    for (i = 0; i < UTIL_FORMAT_MAX_UNPACKED_HEIGHT*UTIL_FORMAT_MAX_UNPACKED_WIDTH*4; ++i) {
336       if (src[i] < 0.0) {
337          accurate = FALSE;
338          dst[i] = 0;
339       }
340       else if (src[i] > 1.0) {
341          accurate = FALSE;
342          dst[i] = 255;
343       }
344       else {
345          dst[i] = src[i] * 255.0;
346       }
347    }
348 
349    return accurate;
350 }
351 
352 
353 static boolean
test_format_unpack_rgba_8unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)354 test_format_unpack_rgba_8unorm(const struct util_format_description *format_desc,
355                                const struct util_format_test_case *test)
356 {
357    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
358    uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
359    unsigned i, j, k;
360    boolean success;
361 
362    format_desc->unpack_rgba_8unorm(&unpacked[0][0][0], sizeof unpacked[0],
363                               test->packed, 0,
364                               format_desc->block.width, format_desc->block.height);
365 
366    convert_float_to_8unorm(&expected[0][0][0], &test->unpacked[0][0][0]);
367 
368    success = TRUE;
369    for (i = 0; i < format_desc->block.height; ++i) {
370       for (j = 0; j < format_desc->block.width; ++j) {
371          for (k = 0; k < 4; ++k) {
372             if (expected[i][j][k] != unpacked[i][j][k]) {
373                success = FALSE;
374             }
375          }
376       }
377    }
378 
379    /* Ignore NaN */
380    if (util_is_double_nan(test->unpacked[0][0][0]))
381       success = TRUE;
382 
383    /* Ignore S3TC errors */
384    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
385       success = TRUE;
386    }
387 
388    if (!success) {
389       print_unpacked_rgba_8unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
390       print_unpacked_rgba_8unorm(format_desc, "        ", expected, " expected\n");
391    }
392 
393    return success;
394 }
395 
396 
397 static boolean
test_format_pack_rgba_8unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)398 test_format_pack_rgba_8unorm(const struct util_format_description *format_desc,
399                              const struct util_format_test_case *test)
400 {
401    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
402    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
403    unsigned i;
404    boolean success;
405 
406    if (test->format == PIPE_FORMAT_DXT1_RGBA) {
407       /*
408        * Skip S3TC as packed representation is not canonical.
409        *
410        * TODO: Do a round trip conversion.
411        */
412       return TRUE;
413    }
414 
415    if (!convert_float_to_8unorm(&unpacked[0][0][0], &test->unpacked[0][0][0])) {
416       /*
417        * Skip test cases which cannot be represented by four unorm bytes.
418        */
419       return TRUE;
420    }
421 
422    memset(packed, 0, sizeof packed);
423 
424    format_desc->pack_rgba_8unorm(packed, 0,
425                             &unpacked[0][0][0], sizeof unpacked[0],
426                             format_desc->block.width, format_desc->block.height);
427 
428    success = TRUE;
429    for (i = 0; i < format_desc->block.bits/8; ++i)
430       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
431          success = FALSE;
432 
433    /* Ignore NaN */
434    if (util_is_double_nan(test->unpacked[0][0][0]))
435       success = TRUE;
436 
437    /* Ignore failure cases due to unorm8 format */
438    if (test->unpacked[0][0][0] > 1.0f || test->unpacked[0][0][0] < 0.0f)
439       success = TRUE;
440 
441    /* Multiple of 255 */
442    if ((test->unpacked[0][0][0] * 255.0) != (int)(test->unpacked[0][0][0] * 255.0))
443       success = TRUE;
444 
445    /* Ignore S3TC errors */
446    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
447       success = TRUE;
448    }
449 
450    if (!success) {
451       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
452       print_packed(format_desc, "        ", test->packed, " expected\n");
453    }
454 
455    return success;
456 }
457 
458 
459 static boolean
test_format_unpack_z_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)460 test_format_unpack_z_float(const struct util_format_description *format_desc,
461                               const struct util_format_test_case *test)
462 {
463    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
464    unsigned i, j;
465    boolean success;
466 
467    format_desc->unpack_z_float(&unpacked[0][0], sizeof unpacked[0],
468                                test->packed, 0,
469                                format_desc->block.width, format_desc->block.height);
470 
471    success = TRUE;
472    for (i = 0; i < format_desc->block.height; ++i) {
473       for (j = 0; j < format_desc->block.width; ++j) {
474          if (!compare_float(test->unpacked[i][j][0], unpacked[i][j])) {
475             success = FALSE;
476          }
477       }
478    }
479 
480    if (!success) {
481       print_unpacked_z_float(format_desc, "FAILED: ", unpacked, " obtained\n");
482       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
483    }
484 
485    return success;
486 }
487 
488 
489 static boolean
test_format_pack_z_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)490 test_format_pack_z_float(const struct util_format_description *format_desc,
491                             const struct util_format_test_case *test)
492 {
493    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
494    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
495    unsigned i, j;
496    boolean success;
497 
498    memset(packed, 0, sizeof packed);
499    for (i = 0; i < format_desc->block.height; ++i) {
500       for (j = 0; j < format_desc->block.width; ++j) {
501          unpacked[i][j] = (float) test->unpacked[i][j][0];
502          if (test->unpacked[i][j][1]) {
503             return TRUE;
504          }
505       }
506    }
507 
508    format_desc->pack_z_float(packed, 0,
509                              &unpacked[0][0], sizeof unpacked[0],
510                              format_desc->block.width, format_desc->block.height);
511 
512    success = TRUE;
513    for (i = 0; i < format_desc->block.bits/8; ++i)
514       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
515          success = FALSE;
516 
517    if (!success) {
518       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
519       print_packed(format_desc, "        ", test->packed, " expected\n");
520    }
521 
522    return success;
523 }
524 
525 
526 static boolean
test_format_unpack_z_32unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)527 test_format_unpack_z_32unorm(const struct util_format_description *format_desc,
528                                const struct util_format_test_case *test)
529 {
530    uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
531    uint32_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
532    unsigned i, j;
533    boolean success;
534 
535    format_desc->unpack_z_32unorm(&unpacked[0][0], sizeof unpacked[0],
536                                  test->packed, 0,
537                                  format_desc->block.width, format_desc->block.height);
538 
539    for (i = 0; i < format_desc->block.height; ++i) {
540       for (j = 0; j < format_desc->block.width; ++j) {
541          expected[i][j] = test->unpacked[i][j][0] * 0xffffffff;
542       }
543    }
544 
545    success = TRUE;
546    for (i = 0; i < format_desc->block.height; ++i) {
547       for (j = 0; j < format_desc->block.width; ++j) {
548          if (expected[i][j] != unpacked[i][j]) {
549             success = FALSE;
550          }
551       }
552    }
553 
554    if (!success) {
555       print_unpacked_z_32unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
556       print_unpacked_z_32unorm(format_desc, "        ", expected, " expected\n");
557    }
558 
559    return success;
560 }
561 
562 
563 static boolean
test_format_pack_z_32unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)564 test_format_pack_z_32unorm(const struct util_format_description *format_desc,
565                              const struct util_format_test_case *test)
566 {
567    uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
568    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
569    unsigned i, j;
570    boolean success;
571 
572    for (i = 0; i < format_desc->block.height; ++i) {
573       for (j = 0; j < format_desc->block.width; ++j) {
574          unpacked[i][j] = test->unpacked[i][j][0] * 0xffffffff;
575          if (test->unpacked[i][j][1]) {
576             return TRUE;
577          }
578       }
579    }
580 
581    memset(packed, 0, sizeof packed);
582 
583    format_desc->pack_z_32unorm(packed, 0,
584                                &unpacked[0][0], sizeof unpacked[0],
585                                format_desc->block.width, format_desc->block.height);
586 
587    success = TRUE;
588    for (i = 0; i < format_desc->block.bits/8; ++i)
589       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
590          success = FALSE;
591 
592    if (!success) {
593       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
594       print_packed(format_desc, "        ", test->packed, " expected\n");
595    }
596 
597    return success;
598 }
599 
600 
601 static boolean
test_format_unpack_s_8uint(const struct util_format_description * format_desc,const struct util_format_test_case * test)602 test_format_unpack_s_8uint(const struct util_format_description *format_desc,
603                                const struct util_format_test_case *test)
604 {
605    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
606    uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
607    unsigned i, j;
608    boolean success;
609 
610    format_desc->unpack_s_8uint(&unpacked[0][0], sizeof unpacked[0],
611                                   test->packed, 0,
612                                   format_desc->block.width, format_desc->block.height);
613 
614    for (i = 0; i < format_desc->block.height; ++i) {
615       for (j = 0; j < format_desc->block.width; ++j) {
616          expected[i][j] = test->unpacked[i][j][1];
617       }
618    }
619 
620    success = TRUE;
621    for (i = 0; i < format_desc->block.height; ++i) {
622       for (j = 0; j < format_desc->block.width; ++j) {
623          if (expected[i][j] != unpacked[i][j]) {
624             success = FALSE;
625          }
626       }
627    }
628 
629    if (!success) {
630       print_unpacked_s_8uint(format_desc, "FAILED: ", unpacked, " obtained\n");
631       print_unpacked_s_8uint(format_desc, "        ", expected, " expected\n");
632    }
633 
634    return success;
635 }
636 
637 
638 static boolean
test_format_pack_s_8uint(const struct util_format_description * format_desc,const struct util_format_test_case * test)639 test_format_pack_s_8uint(const struct util_format_description *format_desc,
640                              const struct util_format_test_case *test)
641 {
642    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
643    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
644    unsigned i, j;
645    boolean success;
646 
647    for (i = 0; i < format_desc->block.height; ++i) {
648       for (j = 0; j < format_desc->block.width; ++j) {
649          unpacked[i][j] = test->unpacked[i][j][1];
650          if (test->unpacked[i][j][0]) {
651             return TRUE;
652          }
653       }
654    }
655 
656    memset(packed, 0, sizeof packed);
657 
658    format_desc->pack_s_8uint(packed, 0,
659                                 &unpacked[0][0], sizeof unpacked[0],
660                                 format_desc->block.width, format_desc->block.height);
661 
662    success = TRUE;
663    for (i = 0; i < format_desc->block.bits/8; ++i)
664       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
665          success = FALSE;
666 
667    if (!success) {
668       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
669       print_packed(format_desc, "        ", test->packed, " expected\n");
670    }
671 
672    return success;
673 }
674 
675 
676 typedef boolean
677 (*test_func_t)(const struct util_format_description *format_desc,
678                const struct util_format_test_case *test);
679 
680 
681 static boolean
test_one_func(const struct util_format_description * format_desc,test_func_t func,const char * suffix)682 test_one_func(const struct util_format_description *format_desc,
683               test_func_t func,
684               const char *suffix)
685 {
686    unsigned i;
687    boolean success = TRUE;
688 
689    printf("Testing util_format_%s_%s ...\n",
690           format_desc->short_name, suffix);
691    fflush(stdout);
692 
693    for (i = 0; i < util_format_nr_test_cases; ++i) {
694       const struct util_format_test_case *test = &util_format_test_cases[i];
695 
696       if (test->format == format_desc->format) {
697          if (!func(format_desc, &util_format_test_cases[i])) {
698            success = FALSE;
699          }
700       }
701    }
702 
703    return success;
704 }
705 
706 
707 static boolean
test_all(void)708 test_all(void)
709 {
710    enum pipe_format format;
711    boolean success = TRUE;
712 
713    for (format = 1; format < PIPE_FORMAT_COUNT; ++format) {
714       const struct util_format_description *format_desc;
715 
716       format_desc = util_format_description(format);
717       if (!format_desc) {
718          continue;
719       }
720 
721       assert(format_desc->block.bits   <= UTIL_FORMAT_MAX_PACKED_BYTES * 8);
722       assert(format_desc->block.height <= UTIL_FORMAT_MAX_UNPACKED_HEIGHT);
723       assert(format_desc->block.width  <= UTIL_FORMAT_MAX_UNPACKED_WIDTH);
724 
725 #     define TEST_ONE_FUNC(name) \
726       if (format_desc->name) { \
727          if (!test_one_func(format_desc, &test_format_##name, #name)) { \
728            success = FALSE; \
729          } \
730       }
731 
732       TEST_ONE_FUNC(fetch_rgba_float);
733       TEST_ONE_FUNC(pack_rgba_float);
734       TEST_ONE_FUNC(unpack_rgba_float);
735       TEST_ONE_FUNC(pack_rgba_8unorm);
736       TEST_ONE_FUNC(unpack_rgba_8unorm);
737 
738       TEST_ONE_FUNC(unpack_z_32unorm);
739       TEST_ONE_FUNC(pack_z_32unorm);
740       TEST_ONE_FUNC(unpack_z_float);
741       TEST_ONE_FUNC(pack_z_float);
742       TEST_ONE_FUNC(unpack_s_8uint);
743       TEST_ONE_FUNC(pack_s_8uint);
744 
745 #     undef TEST_ONE_FUNC
746    }
747 
748    return success;
749 }
750 
751 
main(int argc,char ** argv)752 int main(int argc, char **argv)
753 {
754    boolean success;
755 
756    success = test_all();
757 
758    return success ? 0 : 1;
759 }
760