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