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