• 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/half_float.h"
34 #include "util/u_math.h"
35 #include "util/format/u_format.h"
36 #include "util/format/u_format_tests.h"
37 #include "util/format/u_format_s3tc.h"
38 
39 
40 static boolean
compare_float(float x,float y)41 compare_float(float x, float y)
42 {
43    float error = y - x;
44 
45    if (error < 0.0f)
46       error = -error;
47 
48    if (error > FLT_EPSILON) {
49       return FALSE;
50    }
51 
52    return TRUE;
53 }
54 
55 
56 static void
print_packed(const struct util_format_description * format_desc,const char * prefix,const uint8_t * packed,const char * suffix)57 print_packed(const struct util_format_description *format_desc,
58              const char *prefix,
59              const uint8_t *packed,
60              const char *suffix)
61 {
62    unsigned i;
63    const char *sep = "";
64 
65    printf("%s", prefix);
66    for (i = 0; i < format_desc->block.bits/8; ++i) {
67       printf("%s%02x", sep, packed[i]);
68       sep = " ";
69    }
70    printf("%s", suffix);
71    fflush(stdout);
72 }
73 
74 
75 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)76 print_unpacked_rgba_doubl(const struct util_format_description *format_desc,
77                      const char *prefix,
78                      const double unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
79                      const char *suffix)
80 {
81    unsigned i, j;
82    const char *sep = "";
83 
84    printf("%s", prefix);
85    for (i = 0; i < format_desc->block.height; ++i) {
86       for (j = 0; j < format_desc->block.width; ++j) {
87          printf("%s{%f, %f, %f, %f}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
88          sep = ", ";
89       }
90       sep = ",\n";
91    }
92    printf("%s", suffix);
93    fflush(stdout);
94 }
95 
96 
97 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)98 print_unpacked_rgba_float(const struct util_format_description *format_desc,
99                      const char *prefix,
100                      float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
101                      const char *suffix)
102 {
103    unsigned i, j;
104    const char *sep = "";
105 
106    printf("%s", prefix);
107    for (i = 0; i < format_desc->block.height; ++i) {
108       for (j = 0; j < format_desc->block.width; ++j) {
109          printf("%s{%f, %f, %f, %f}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
110          sep = ", ";
111       }
112       sep = ",\n";
113    }
114    printf("%s", suffix);
115    fflush(stdout);
116 }
117 
118 
119 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)120 print_unpacked_rgba_8unorm(const struct util_format_description *format_desc,
121                       const char *prefix,
122                       uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
123                       const char *suffix)
124 {
125    unsigned i, j;
126    const char *sep = "";
127 
128    printf("%s", prefix);
129    for (i = 0; i < format_desc->block.height; ++i) {
130       for (j = 0; j < format_desc->block.width; ++j) {
131          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]);
132          sep = ", ";
133       }
134    }
135    printf("%s", suffix);
136    fflush(stdout);
137 }
138 
139 
140 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)141 print_unpacked_z_float(const struct util_format_description *format_desc,
142                        const char *prefix,
143                        float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
144                        const char *suffix)
145 {
146    unsigned i, j;
147    const char *sep = "";
148 
149    printf("%s", prefix);
150    for (i = 0; i < format_desc->block.height; ++i) {
151       for (j = 0; j < format_desc->block.width; ++j) {
152          printf("%s%f", sep, unpacked[i][j]);
153          sep = ", ";
154       }
155       sep = ",\n";
156    }
157    printf("%s", suffix);
158    fflush(stdout);
159 }
160 
161 
162 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)163 print_unpacked_z_32unorm(const struct util_format_description *format_desc,
164                          const char *prefix,
165                          uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
166                          const char *suffix)
167 {
168    unsigned i, j;
169    const char *sep = "";
170 
171    printf("%s", prefix);
172    for (i = 0; i < format_desc->block.height; ++i) {
173       for (j = 0; j < format_desc->block.width; ++j) {
174          printf("%s0x%08x", sep, unpacked[i][j]);
175          sep = ", ";
176       }
177    }
178    printf("%s", suffix);
179    fflush(stdout);
180 }
181 
182 
183 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)184 print_unpacked_s_8uint(const struct util_format_description *format_desc,
185                        const char *prefix,
186                        uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
187                        const char *suffix)
188 {
189    unsigned i, j;
190    const char *sep = "";
191 
192    printf("%s", prefix);
193    for (i = 0; i < format_desc->block.height; ++i) {
194       for (j = 0; j < format_desc->block.width; ++j) {
195          printf("%s0x%02x", sep, unpacked[i][j]);
196          sep = ", ";
197       }
198    }
199    printf("%s", suffix);
200    fflush(stdout);
201 }
202 
203 
204 static boolean
test_format_fetch_rgba(const struct util_format_description * format_desc,const struct util_format_test_case * test)205 test_format_fetch_rgba(const struct util_format_description *format_desc,
206                              const struct util_format_test_case *test)
207 {
208    util_format_fetch_rgba_func_ptr fetch_rgba =
209       util_format_fetch_rgba_func(format_desc->format);
210    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
211    unsigned i, j, k;
212    boolean success;
213 
214    success = TRUE;
215    for (i = 0; i < format_desc->block.height; ++i) {
216       for (j = 0; j < format_desc->block.width; ++j) {
217          fetch_rgba(unpacked[i][j], test->packed, j, i);
218          for (k = 0; k < 4; ++k) {
219             if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
220                success = FALSE;
221             }
222          }
223       }
224    }
225 
226    /* Ignore S3TC errors */
227    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
228       success = TRUE;
229    }
230 
231    if (!success) {
232       print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
233       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
234    }
235 
236    return success;
237 }
238 
239 
240 static boolean
test_format_unpack_rgba(const struct util_format_description * format_desc,const struct util_format_test_case * test)241 test_format_unpack_rgba(const struct util_format_description *format_desc,
242                         const struct util_format_test_case *test)
243 {
244    const struct util_format_unpack_description *unpack =
245       util_format_unpack_description(format_desc->format);
246    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
247    unsigned i, j, k;
248    boolean success;
249 
250    unpack->unpack_rgba(&unpacked[0][0][0], sizeof unpacked[0],
251                        test->packed, 0,
252                        format_desc->block.width, format_desc->block.height);
253 
254    success = TRUE;
255    for (i = 0; i < format_desc->block.height; ++i) {
256       for (j = 0; j < format_desc->block.width; ++j) {
257          for (k = 0; k < 4; ++k) {
258             if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
259                success = FALSE;
260             }
261          }
262       }
263    }
264 
265    /* Ignore S3TC errors */
266    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
267       success = TRUE;
268    }
269 
270    if (!success) {
271       print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
272       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
273    }
274 
275    return success;
276 }
277 
278 
279 static boolean
test_format_pack_rgba_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)280 test_format_pack_rgba_float(const struct util_format_description *format_desc,
281                             const struct util_format_test_case *test)
282 {
283    const struct util_format_pack_description *pack =
284       util_format_pack_description(format_desc->format);
285    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
286    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
287    unsigned i, j, k;
288    boolean success;
289 
290    if (test->format == PIPE_FORMAT_DXT1_RGBA) {
291       /*
292        * Skip S3TC as packed representation is not canonical.
293        *
294        * TODO: Do a round trip conversion.
295        */
296       return TRUE;
297    }
298 
299    memset(packed, 0, sizeof packed);
300    for (i = 0; i < format_desc->block.height; ++i) {
301       for (j = 0; j < format_desc->block.width; ++j) {
302          for (k = 0; k < 4; ++k) {
303             unpacked[i][j][k] = (float) test->unpacked[i][j][k];
304          }
305       }
306    }
307 
308    pack->pack_rgba_float(packed, 0,
309                            &unpacked[0][0][0], sizeof unpacked[0],
310                            format_desc->block.width, format_desc->block.height);
311 
312    success = TRUE;
313    for (i = 0; i < format_desc->block.bits/8; ++i) {
314       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
315          success = FALSE;
316    }
317 
318    /* Ignore NaN */
319    if (util_is_double_nan(test->unpacked[0][0][0]))
320       success = TRUE;
321 
322    /* Ignore S3TC errors */
323    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
324       success = TRUE;
325    }
326 
327    if (!success) {
328       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
329       print_packed(format_desc, "        ", test->packed, " expected\n");
330    }
331 
332    return success;
333 }
334 
335 
336 static boolean
convert_float_to_8unorm(uint8_t * dst,const double * src)337 convert_float_to_8unorm(uint8_t *dst, const double *src)
338 {
339    unsigned i;
340    boolean accurate = TRUE;
341 
342    for (i = 0; i < UTIL_FORMAT_MAX_UNPACKED_HEIGHT*UTIL_FORMAT_MAX_UNPACKED_WIDTH*4; ++i) {
343       if (src[i] < 0.0) {
344          accurate = FALSE;
345          dst[i] = 0;
346       }
347       else if (src[i] > 1.0) {
348          accurate = FALSE;
349          dst[i] = 255;
350       }
351       else {
352          dst[i] = src[i] * 255.0;
353       }
354    }
355 
356    return accurate;
357 }
358 
359 
360 static boolean
test_format_unpack_rgba_8unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)361 test_format_unpack_rgba_8unorm(const struct util_format_description *format_desc,
362                                const struct util_format_test_case *test)
363 {
364    const struct util_format_unpack_description *unpack =
365       util_format_unpack_description(format_desc->format);
366    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
367    uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
368    unsigned i, j, k;
369    boolean success;
370 
371    if (util_format_is_pure_integer(format_desc->format))
372       return FALSE;
373 
374    unpack->unpack_rgba_8unorm(&unpacked[0][0][0], sizeof unpacked[0],
375                               test->packed, 0,
376                               format_desc->block.width, format_desc->block.height);
377 
378    convert_float_to_8unorm(&expected[0][0][0], &test->unpacked[0][0][0]);
379 
380    success = TRUE;
381    for (i = 0; i < format_desc->block.height; ++i) {
382       for (j = 0; j < format_desc->block.width; ++j) {
383          for (k = 0; k < 4; ++k) {
384             if (expected[i][j][k] != unpacked[i][j][k]) {
385                success = FALSE;
386             }
387          }
388       }
389    }
390 
391    /* Ignore NaN */
392    if (util_is_double_nan(test->unpacked[0][0][0]))
393       success = TRUE;
394 
395    if (!success) {
396       print_unpacked_rgba_8unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
397       print_unpacked_rgba_8unorm(format_desc, "        ", expected, " expected\n");
398    }
399 
400    return success;
401 }
402 
403 
404 static boolean
test_format_pack_rgba_8unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)405 test_format_pack_rgba_8unorm(const struct util_format_description *format_desc,
406                              const struct util_format_test_case *test)
407 {
408    const struct util_format_pack_description *pack =
409       util_format_pack_description(format_desc->format);
410    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
411    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
412    unsigned i;
413    boolean success;
414 
415    if (test->format == PIPE_FORMAT_DXT1_RGBA) {
416       /*
417        * Skip S3TC as packed representation is not canonical.
418        *
419        * TODO: Do a round trip conversion.
420        */
421       return TRUE;
422    }
423 
424    if (!convert_float_to_8unorm(&unpacked[0][0][0], &test->unpacked[0][0][0])) {
425       /*
426        * Skip test cases which cannot be represented by four unorm bytes.
427        */
428       return TRUE;
429    }
430 
431    memset(packed, 0, sizeof packed);
432 
433    pack->pack_rgba_8unorm(packed, 0,
434                           &unpacked[0][0][0], sizeof unpacked[0],
435                           format_desc->block.width, format_desc->block.height);
436 
437    success = TRUE;
438    for (i = 0; i < format_desc->block.bits/8; ++i)
439       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
440          success = FALSE;
441 
442    /* Ignore NaN */
443    if (util_is_double_nan(test->unpacked[0][0][0]))
444       success = TRUE;
445 
446    /* Ignore failure cases due to unorm8 format */
447    if (test->unpacked[0][0][0] > 1.0f || test->unpacked[0][0][0] < 0.0f)
448       success = TRUE;
449 
450    /* Multiple of 255 */
451    if ((test->unpacked[0][0][0] * 255.0) != (int)(test->unpacked[0][0][0] * 255.0))
452       success = TRUE;
453 
454    /* Ignore S3TC errors */
455    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
456       success = TRUE;
457    }
458 
459    if (!success) {
460       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
461       print_packed(format_desc, "        ", test->packed, " expected\n");
462    }
463 
464    return success;
465 }
466 
467 
468 static boolean
test_format_unpack_z_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)469 test_format_unpack_z_float(const struct util_format_description *format_desc,
470                               const struct util_format_test_case *test)
471 {
472    const struct util_format_unpack_description *unpack =
473       util_format_unpack_description(format_desc->format);
474    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
475    unsigned i, j;
476    boolean success;
477 
478    unpack->unpack_z_float(&unpacked[0][0], sizeof unpacked[0],
479                           test->packed, 0,
480                           format_desc->block.width, format_desc->block.height);
481 
482    success = TRUE;
483    for (i = 0; i < format_desc->block.height; ++i) {
484       for (j = 0; j < format_desc->block.width; ++j) {
485          if (!compare_float(test->unpacked[i][j][0], unpacked[i][j])) {
486             success = FALSE;
487          }
488       }
489    }
490 
491    if (!success) {
492       print_unpacked_z_float(format_desc, "FAILED: ", unpacked, " obtained\n");
493       print_unpacked_rgba_doubl(format_desc, "        ", test->unpacked, " expected\n");
494    }
495 
496    return success;
497 }
498 
499 
500 static boolean
test_format_pack_z_float(const struct util_format_description * format_desc,const struct util_format_test_case * test)501 test_format_pack_z_float(const struct util_format_description *format_desc,
502                             const struct util_format_test_case *test)
503 {
504    const struct util_format_pack_description *pack =
505       util_format_pack_description(format_desc->format);
506    float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
507    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
508    unsigned i, j;
509    boolean success;
510 
511    memset(packed, 0, sizeof packed);
512    for (i = 0; i < format_desc->block.height; ++i) {
513       for (j = 0; j < format_desc->block.width; ++j) {
514          unpacked[i][j] = (float) test->unpacked[i][j][0];
515          if (test->unpacked[i][j][1]) {
516             return TRUE;
517          }
518       }
519    }
520 
521    pack->pack_z_float(packed, 0,
522                       &unpacked[0][0], sizeof unpacked[0],
523                       format_desc->block.width, format_desc->block.height);
524 
525    success = TRUE;
526    for (i = 0; i < format_desc->block.bits/8; ++i)
527       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
528          success = FALSE;
529 
530    if (!success) {
531       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
532       print_packed(format_desc, "        ", test->packed, " expected\n");
533    }
534 
535    return success;
536 }
537 
538 
539 static boolean
test_format_unpack_z_32unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)540 test_format_unpack_z_32unorm(const struct util_format_description *format_desc,
541                                const struct util_format_test_case *test)
542 {
543    const struct util_format_unpack_description *unpack =
544       util_format_unpack_description(format_desc->format);
545    uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
546    uint32_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
547    unsigned i, j;
548    boolean success;
549 
550    unpack->unpack_z_32unorm(&unpacked[0][0], sizeof unpacked[0],
551                             test->packed, 0,
552                             format_desc->block.width, format_desc->block.height);
553 
554    for (i = 0; i < format_desc->block.height; ++i) {
555       for (j = 0; j < format_desc->block.width; ++j) {
556          expected[i][j] = test->unpacked[i][j][0] * 0xffffffff;
557       }
558    }
559 
560    success = TRUE;
561    for (i = 0; i < format_desc->block.height; ++i) {
562       for (j = 0; j < format_desc->block.width; ++j) {
563          if (expected[i][j] != unpacked[i][j]) {
564             success = FALSE;
565          }
566       }
567    }
568 
569    if (!success) {
570       print_unpacked_z_32unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
571       print_unpacked_z_32unorm(format_desc, "        ", expected, " expected\n");
572    }
573 
574    return success;
575 }
576 
577 
578 static boolean
test_format_pack_z_32unorm(const struct util_format_description * format_desc,const struct util_format_test_case * test)579 test_format_pack_z_32unorm(const struct util_format_description *format_desc,
580                              const struct util_format_test_case *test)
581 {
582    const struct util_format_pack_description *pack =
583       util_format_pack_description(format_desc->format);
584    uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
585    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
586    unsigned i, j;
587    boolean success;
588 
589    for (i = 0; i < format_desc->block.height; ++i) {
590       for (j = 0; j < format_desc->block.width; ++j) {
591          unpacked[i][j] = test->unpacked[i][j][0] * 0xffffffff;
592          if (test->unpacked[i][j][1]) {
593             return TRUE;
594          }
595       }
596    }
597 
598    memset(packed, 0, sizeof packed);
599 
600    pack->pack_z_32unorm(packed, 0,
601                         &unpacked[0][0], sizeof unpacked[0],
602                         format_desc->block.width, format_desc->block.height);
603 
604    success = TRUE;
605    for (i = 0; i < format_desc->block.bits/8; ++i)
606       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
607          success = FALSE;
608 
609    if (!success) {
610       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
611       print_packed(format_desc, "        ", test->packed, " expected\n");
612    }
613 
614    return success;
615 }
616 
617 
618 static boolean
test_format_unpack_s_8uint(const struct util_format_description * format_desc,const struct util_format_test_case * test)619 test_format_unpack_s_8uint(const struct util_format_description *format_desc,
620                                const struct util_format_test_case *test)
621 {
622    const struct util_format_unpack_description *unpack =
623       util_format_unpack_description(format_desc->format);
624    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
625    uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
626    unsigned i, j;
627    boolean success;
628 
629    unpack->unpack_s_8uint(&unpacked[0][0], sizeof unpacked[0],
630                           test->packed, 0,
631                           format_desc->block.width, format_desc->block.height);
632 
633    for (i = 0; i < format_desc->block.height; ++i) {
634       for (j = 0; j < format_desc->block.width; ++j) {
635          expected[i][j] = test->unpacked[i][j][1];
636       }
637    }
638 
639    success = TRUE;
640    for (i = 0; i < format_desc->block.height; ++i) {
641       for (j = 0; j < format_desc->block.width; ++j) {
642          if (expected[i][j] != unpacked[i][j]) {
643             success = FALSE;
644          }
645       }
646    }
647 
648    if (!success) {
649       print_unpacked_s_8uint(format_desc, "FAILED: ", unpacked, " obtained\n");
650       print_unpacked_s_8uint(format_desc, "        ", expected, " expected\n");
651    }
652 
653    return success;
654 }
655 
656 
657 static boolean
test_format_pack_s_8uint(const struct util_format_description * format_desc,const struct util_format_test_case * test)658 test_format_pack_s_8uint(const struct util_format_description *format_desc,
659                              const struct util_format_test_case *test)
660 {
661    const struct util_format_pack_description *pack =
662       util_format_pack_description(format_desc->format);
663    uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
664    uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
665    unsigned i, j;
666    boolean success;
667 
668    for (i = 0; i < format_desc->block.height; ++i) {
669       for (j = 0; j < format_desc->block.width; ++j) {
670          unpacked[i][j] = test->unpacked[i][j][1];
671          if (test->unpacked[i][j][0]) {
672             return TRUE;
673          }
674       }
675    }
676 
677    memset(packed, 0, sizeof packed);
678 
679    pack->pack_s_8uint(packed, 0,
680                       &unpacked[0][0], sizeof unpacked[0],
681                       format_desc->block.width, format_desc->block.height);
682 
683    success = TRUE;
684    for (i = 0; i < format_desc->block.bits/8; ++i)
685       if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
686          success = FALSE;
687 
688    if (!success) {
689       print_packed(format_desc, "FAILED: ", packed, " obtained\n");
690       print_packed(format_desc, "        ", test->packed, " expected\n");
691    }
692 
693    return success;
694 }
695 
696 
697 /* Touch-test that the unorm/snorm flags are set up right by codegen. */
698 static boolean
test_format_norm_flags(const struct util_format_description * format_desc)699 test_format_norm_flags(const struct util_format_description *format_desc)
700 {
701    boolean success = TRUE;
702 
703 #define FORMAT_CASE(format, unorm, snorm) \
704    case format: \
705       success = (format_desc->is_unorm == unorm && \
706                  format_desc->is_snorm == snorm); \
707       break
708 
709    switch (format_desc->format) {
710       FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_UNORM, TRUE, FALSE);
711       FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_SRGB, TRUE, FALSE);
712       FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_SNORM, FALSE, TRUE);
713       FORMAT_CASE(PIPE_FORMAT_R32_FLOAT, FALSE, FALSE);
714       FORMAT_CASE(PIPE_FORMAT_X8Z24_UNORM, TRUE, FALSE);
715       FORMAT_CASE(PIPE_FORMAT_S8X24_UINT, FALSE, FALSE);
716       FORMAT_CASE(PIPE_FORMAT_DXT1_RGB, TRUE, FALSE);
717       FORMAT_CASE(PIPE_FORMAT_ETC2_RGB8, TRUE, FALSE);
718       FORMAT_CASE(PIPE_FORMAT_ETC2_R11_SNORM, FALSE, TRUE);
719       FORMAT_CASE(PIPE_FORMAT_ASTC_4x4, TRUE, FALSE);
720       FORMAT_CASE(PIPE_FORMAT_BPTC_RGBA_UNORM, TRUE, FALSE);
721       FORMAT_CASE(PIPE_FORMAT_BPTC_RGB_FLOAT, FALSE, FALSE);
722    default:
723       success = !(format_desc->is_unorm && format_desc->is_snorm);
724       break;
725    }
726 #undef FORMAT_CASE
727 
728    if (!success) {
729       printf("FAILED: %s (unorm %s, snorm %s)\n",
730              format_desc->short_name,
731              format_desc->is_unorm ? "yes" : "no",
732              format_desc->is_snorm ? "yes" : "no");
733    }
734 
735    return success;
736 }
737 
738 typedef boolean
739 (*test_func_t)(const struct util_format_description *format_desc,
740                const struct util_format_test_case *test);
741 
742 
743 static boolean
test_one_func(const struct util_format_description * format_desc,test_func_t func,const char * suffix)744 test_one_func(const struct util_format_description *format_desc,
745               test_func_t func,
746               const char *suffix)
747 {
748    unsigned i;
749    boolean success = TRUE;
750 
751    printf("Testing util_format_%s_%s ...\n",
752           format_desc->short_name, suffix);
753    fflush(stdout);
754 
755    for (i = 0; i < util_format_nr_test_cases; ++i) {
756       const struct util_format_test_case *test = &util_format_test_cases[i];
757 
758       if (test->format == format_desc->format) {
759          if (!func(format_desc, &util_format_test_cases[i])) {
760            success = FALSE;
761          }
762       }
763    }
764 
765    return success;
766 }
767 
768 static boolean
test_format_metadata(const struct util_format_description * format_desc,boolean (* func)(const struct util_format_description * format_desc),const char * suffix)769 test_format_metadata(const struct util_format_description *format_desc,
770                      boolean (*func)(const struct util_format_description *format_desc),
771                      const char *suffix)
772 {
773    boolean success = TRUE;
774 
775    printf("Testing util_format_%s_%s ...\n", format_desc->short_name, suffix);
776    fflush(stdout);
777 
778    if (!func(format_desc)) {
779       success = FALSE;
780    }
781 
782    return success;
783 }
784 
785 static boolean
test_all(void)786 test_all(void)
787 {
788    enum pipe_format format;
789    boolean success = TRUE;
790 
791    for (format = 1; format < PIPE_FORMAT_COUNT; ++format) {
792       const struct util_format_description *format_desc;
793 
794       format_desc = util_format_description(format);
795       if (!format_desc) {
796          continue;
797       }
798 
799       assert(format_desc->block.bits   <= UTIL_FORMAT_MAX_PACKED_BYTES * 8);
800       assert(format_desc->block.height <= UTIL_FORMAT_MAX_UNPACKED_HEIGHT);
801       assert(format_desc->block.width  <= UTIL_FORMAT_MAX_UNPACKED_WIDTH);
802 
803 #     define TEST_ONE_PACK_FUNC(name) \
804       if (util_format_pack_description(format)->name) {                 \
805          if (!test_one_func(format_desc, &test_format_##name, #name)) { \
806            success = FALSE; \
807          } \
808       }
809 
810 #     define TEST_ONE_UNPACK_FUNC(name) \
811       if (util_format_unpack_description(format)->name) {               \
812          if (!test_one_func(format_desc, &test_format_##name, #name)) { \
813            success = FALSE; \
814          } \
815       }
816 
817 #     define TEST_FORMAT_METADATA(name) \
818       if (!test_format_metadata(format_desc, &test_format_##name, #name)) { \
819          success = FALSE; \
820       } \
821 
822       if (util_format_fetch_rgba_func(format)) {
823          if (!test_one_func(format_desc, test_format_fetch_rgba, "fetch_rgba"))
824             success = FALSE;
825       }
826 
827       TEST_ONE_PACK_FUNC(pack_rgba_float);
828       TEST_ONE_UNPACK_FUNC(unpack_rgba);
829       TEST_ONE_PACK_FUNC(pack_rgba_8unorm);
830       TEST_ONE_UNPACK_FUNC(unpack_rgba_8unorm);
831 
832       TEST_ONE_UNPACK_FUNC(unpack_z_32unorm);
833       TEST_ONE_PACK_FUNC(pack_z_32unorm);
834       TEST_ONE_UNPACK_FUNC(unpack_z_float);
835       TEST_ONE_PACK_FUNC(pack_z_float);
836       TEST_ONE_UNPACK_FUNC(unpack_s_8uint);
837       TEST_ONE_PACK_FUNC(pack_s_8uint);
838 
839       TEST_FORMAT_METADATA(norm_flags);
840 
841 #     undef TEST_ONE_FUNC
842 #     undef TEST_ONE_FORMAT
843    }
844 
845    return success;
846 }
847 
848 
main(int argc,char ** argv)849 int main(int argc, char **argv)
850 {
851    boolean success;
852 
853    success = test_all();
854 
855    return success ? 0 : 1;
856 }
857