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