1/************************************************************************** 2 * 3 * Copyright 2009-2010 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29#include <stdlib.h> 30#include <stdio.h> 31#include <float.h> 32 33#include "util/u_half.h" 34#include "util/u_format.h" 35#include "util/u_format_tests.h" 36#include "util/u_format_s3tc.h" 37 38 39static boolean 40compare_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 55static void 56print_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 74static void 75print_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 96static void 97print_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 118static void 119print_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 139static void 140print_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 161static void 162print_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 182static void 183print_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 203static boolean 204test_format_fetch_rgba_float(const struct util_format_description *format_desc, 205 const struct util_format_test_case *test) 206{ 207 float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } }; 208 unsigned i, j, k; 209 boolean success; 210 211 success = TRUE; 212 for (i = 0; i < format_desc->block.height; ++i) { 213 for (j = 0; j < format_desc->block.width; ++j) { 214 format_desc->fetch_rgba_float(unpacked[i][j], test->packed, j, i); 215 for (k = 0; k < 4; ++k) { 216 if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) { 217 success = FALSE; 218 } 219 } 220 } 221 } 222 223 /* Ignore S3TC errors */ 224 if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 225 success = TRUE; 226 } 227 228 if (!success) { 229 print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n"); 230 print_unpacked_rgba_doubl(format_desc, " ", test->unpacked, " expected\n"); 231 } 232 233 return success; 234} 235 236 237static boolean 238test_format_unpack_rgba_float(const struct util_format_description *format_desc, 239 const struct util_format_test_case *test) 240{ 241 float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } }; 242 unsigned i, j, k; 243 boolean success; 244 245 format_desc->unpack_rgba_float(&unpacked[0][0][0], sizeof unpacked[0], 246 test->packed, 0, 247 format_desc->block.width, format_desc->block.height); 248 249 success = TRUE; 250 for (i = 0; i < format_desc->block.height; ++i) { 251 for (j = 0; j < format_desc->block.width; ++j) { 252 for (k = 0; k < 4; ++k) { 253 if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) { 254 success = FALSE; 255 } 256 } 257 } 258 } 259 260 /* Ignore S3TC errors */ 261 if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 262 success = TRUE; 263 } 264 265 if (!success) { 266 print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n"); 267 print_unpacked_rgba_doubl(format_desc, " ", test->unpacked, " expected\n"); 268 } 269 270 return success; 271} 272 273 274static boolean 275test_format_pack_rgba_float(const struct util_format_description *format_desc, 276 const struct util_format_test_case *test) 277{ 278 float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4]; 279 uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; 280 unsigned i, j, k; 281 boolean success; 282 283 if (test->format == PIPE_FORMAT_DXT1_RGBA) { 284 /* 285 * Skip S3TC as packed representation is not canonical. 286 * 287 * TODO: Do a round trip conversion. 288 */ 289 return TRUE; 290 } 291 292 memset(packed, 0, sizeof packed); 293 for (i = 0; i < format_desc->block.height; ++i) { 294 for (j = 0; j < format_desc->block.width; ++j) { 295 for (k = 0; k < 4; ++k) { 296 unpacked[i][j][k] = (float) test->unpacked[i][j][k]; 297 } 298 } 299 } 300 301 format_desc->pack_rgba_float(packed, 0, 302 &unpacked[0][0][0], sizeof unpacked[0], 303 format_desc->block.width, format_desc->block.height); 304 305 success = TRUE; 306 for (i = 0; i < format_desc->block.bits/8; ++i) { 307 if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i])) 308 success = FALSE; 309 } 310 311 /* Ignore NaN */ 312 if (util_is_double_nan(test->unpacked[0][0][0])) 313 success = TRUE; 314 315 /* Ignore S3TC errors */ 316 if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 317 success = TRUE; 318 } 319 320 if (!success) { 321 print_packed(format_desc, "FAILED: ", packed, " obtained\n"); 322 print_packed(format_desc, " ", test->packed, " expected\n"); 323 } 324 325 return success; 326} 327 328 329static boolean 330convert_float_to_8unorm(uint8_t *dst, const double *src) 331{ 332 unsigned i; 333 boolean accurate = TRUE; 334 335 for (i = 0; i < UTIL_FORMAT_MAX_UNPACKED_HEIGHT*UTIL_FORMAT_MAX_UNPACKED_WIDTH*4; ++i) { 336 if (src[i] < 0.0) { 337 accurate = FALSE; 338 dst[i] = 0; 339 } 340 else if (src[i] > 1.0) { 341 accurate = FALSE; 342 dst[i] = 255; 343 } 344 else { 345 dst[i] = src[i] * 255.0; 346 } 347 } 348 349 return accurate; 350} 351 352 353static boolean 354test_format_unpack_rgba_8unorm(const struct util_format_description *format_desc, 355 const struct util_format_test_case *test) 356{ 357 uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } }; 358 uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } }; 359 unsigned i, j, k; 360 boolean success; 361 362 format_desc->unpack_rgba_8unorm(&unpacked[0][0][0], sizeof unpacked[0], 363 test->packed, 0, 364 format_desc->block.width, format_desc->block.height); 365 366 convert_float_to_8unorm(&expected[0][0][0], &test->unpacked[0][0][0]); 367 368 success = TRUE; 369 for (i = 0; i < format_desc->block.height; ++i) { 370 for (j = 0; j < format_desc->block.width; ++j) { 371 for (k = 0; k < 4; ++k) { 372 if (expected[i][j][k] != unpacked[i][j][k]) { 373 success = FALSE; 374 } 375 } 376 } 377 } 378 379 /* Ignore NaN */ 380 if (util_is_double_nan(test->unpacked[0][0][0])) 381 success = TRUE; 382 383 if (!success) { 384 print_unpacked_rgba_8unorm(format_desc, "FAILED: ", unpacked, " obtained\n"); 385 print_unpacked_rgba_8unorm(format_desc, " ", expected, " expected\n"); 386 } 387 388 return success; 389} 390 391 392static boolean 393test_format_pack_rgba_8unorm(const struct util_format_description *format_desc, 394 const struct util_format_test_case *test) 395{ 396 uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4]; 397 uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; 398 unsigned i; 399 boolean success; 400 401 if (test->format == PIPE_FORMAT_DXT1_RGBA) { 402 /* 403 * Skip S3TC as packed representation is not canonical. 404 * 405 * TODO: Do a round trip conversion. 406 */ 407 return TRUE; 408 } 409 410 if (!convert_float_to_8unorm(&unpacked[0][0][0], &test->unpacked[0][0][0])) { 411 /* 412 * Skip test cases which cannot be represented by four unorm bytes. 413 */ 414 return TRUE; 415 } 416 417 memset(packed, 0, sizeof packed); 418 419 format_desc->pack_rgba_8unorm(packed, 0, 420 &unpacked[0][0][0], sizeof unpacked[0], 421 format_desc->block.width, format_desc->block.height); 422 423 success = TRUE; 424 for (i = 0; i < format_desc->block.bits/8; ++i) 425 if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i])) 426 success = FALSE; 427 428 /* Ignore NaN */ 429 if (util_is_double_nan(test->unpacked[0][0][0])) 430 success = TRUE; 431 432 /* Ignore failure cases due to unorm8 format */ 433 if (test->unpacked[0][0][0] > 1.0f || test->unpacked[0][0][0] < 0.0f) 434 success = TRUE; 435 436 /* Multiple of 255 */ 437 if ((test->unpacked[0][0][0] * 255.0) != (int)(test->unpacked[0][0][0] * 255.0)) 438 success = TRUE; 439 440 /* Ignore S3TC errors */ 441 if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 442 success = TRUE; 443 } 444 445 if (!success) { 446 print_packed(format_desc, "FAILED: ", packed, " obtained\n"); 447 print_packed(format_desc, " ", test->packed, " expected\n"); 448 } 449 450 return success; 451} 452 453 454static boolean 455test_format_unpack_z_float(const struct util_format_description *format_desc, 456 const struct util_format_test_case *test) 457{ 458 float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } }; 459 unsigned i, j; 460 boolean success; 461 462 format_desc->unpack_z_float(&unpacked[0][0], sizeof unpacked[0], 463 test->packed, 0, 464 format_desc->block.width, format_desc->block.height); 465 466 success = TRUE; 467 for (i = 0; i < format_desc->block.height; ++i) { 468 for (j = 0; j < format_desc->block.width; ++j) { 469 if (!compare_float(test->unpacked[i][j][0], unpacked[i][j])) { 470 success = FALSE; 471 } 472 } 473 } 474 475 if (!success) { 476 print_unpacked_z_float(format_desc, "FAILED: ", unpacked, " obtained\n"); 477 print_unpacked_rgba_doubl(format_desc, " ", test->unpacked, " expected\n"); 478 } 479 480 return success; 481} 482 483 484static boolean 485test_format_pack_z_float(const struct util_format_description *format_desc, 486 const struct util_format_test_case *test) 487{ 488 float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH]; 489 uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; 490 unsigned i, j; 491 boolean success; 492 493 memset(packed, 0, sizeof packed); 494 for (i = 0; i < format_desc->block.height; ++i) { 495 for (j = 0; j < format_desc->block.width; ++j) { 496 unpacked[i][j] = (float) test->unpacked[i][j][0]; 497 if (test->unpacked[i][j][1]) { 498 return TRUE; 499 } 500 } 501 } 502 503 format_desc->pack_z_float(packed, 0, 504 &unpacked[0][0], sizeof unpacked[0], 505 format_desc->block.width, format_desc->block.height); 506 507 success = TRUE; 508 for (i = 0; i < format_desc->block.bits/8; ++i) 509 if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i])) 510 success = FALSE; 511 512 if (!success) { 513 print_packed(format_desc, "FAILED: ", packed, " obtained\n"); 514 print_packed(format_desc, " ", test->packed, " expected\n"); 515 } 516 517 return success; 518} 519 520 521static boolean 522test_format_unpack_z_32unorm(const struct util_format_description *format_desc, 523 const struct util_format_test_case *test) 524{ 525 uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } }; 526 uint32_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } }; 527 unsigned i, j; 528 boolean success; 529 530 format_desc->unpack_z_32unorm(&unpacked[0][0], sizeof unpacked[0], 531 test->packed, 0, 532 format_desc->block.width, format_desc->block.height); 533 534 for (i = 0; i < format_desc->block.height; ++i) { 535 for (j = 0; j < format_desc->block.width; ++j) { 536 expected[i][j] = test->unpacked[i][j][0] * 0xffffffff; 537 } 538 } 539 540 success = TRUE; 541 for (i = 0; i < format_desc->block.height; ++i) { 542 for (j = 0; j < format_desc->block.width; ++j) { 543 if (expected[i][j] != unpacked[i][j]) { 544 success = FALSE; 545 } 546 } 547 } 548 549 if (!success) { 550 print_unpacked_z_32unorm(format_desc, "FAILED: ", unpacked, " obtained\n"); 551 print_unpacked_z_32unorm(format_desc, " ", expected, " expected\n"); 552 } 553 554 return success; 555} 556 557 558static boolean 559test_format_pack_z_32unorm(const struct util_format_description *format_desc, 560 const struct util_format_test_case *test) 561{ 562 uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH]; 563 uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; 564 unsigned i, j; 565 boolean success; 566 567 for (i = 0; i < format_desc->block.height; ++i) { 568 for (j = 0; j < format_desc->block.width; ++j) { 569 unpacked[i][j] = test->unpacked[i][j][0] * 0xffffffff; 570 if (test->unpacked[i][j][1]) { 571 return TRUE; 572 } 573 } 574 } 575 576 memset(packed, 0, sizeof packed); 577 578 format_desc->pack_z_32unorm(packed, 0, 579 &unpacked[0][0], sizeof unpacked[0], 580 format_desc->block.width, format_desc->block.height); 581 582 success = TRUE; 583 for (i = 0; i < format_desc->block.bits/8; ++i) 584 if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i])) 585 success = FALSE; 586 587 if (!success) { 588 print_packed(format_desc, "FAILED: ", packed, " obtained\n"); 589 print_packed(format_desc, " ", test->packed, " expected\n"); 590 } 591 592 return success; 593} 594 595 596static boolean 597test_format_unpack_s_8uint(const struct util_format_description *format_desc, 598 const struct util_format_test_case *test) 599{ 600 uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } }; 601 uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } }; 602 unsigned i, j; 603 boolean success; 604 605 format_desc->unpack_s_8uint(&unpacked[0][0], sizeof unpacked[0], 606 test->packed, 0, 607 format_desc->block.width, format_desc->block.height); 608 609 for (i = 0; i < format_desc->block.height; ++i) { 610 for (j = 0; j < format_desc->block.width; ++j) { 611 expected[i][j] = test->unpacked[i][j][1]; 612 } 613 } 614 615 success = TRUE; 616 for (i = 0; i < format_desc->block.height; ++i) { 617 for (j = 0; j < format_desc->block.width; ++j) { 618 if (expected[i][j] != unpacked[i][j]) { 619 success = FALSE; 620 } 621 } 622 } 623 624 if (!success) { 625 print_unpacked_s_8uint(format_desc, "FAILED: ", unpacked, " obtained\n"); 626 print_unpacked_s_8uint(format_desc, " ", expected, " expected\n"); 627 } 628 629 return success; 630} 631 632 633static boolean 634test_format_pack_s_8uint(const struct util_format_description *format_desc, 635 const struct util_format_test_case *test) 636{ 637 uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH]; 638 uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; 639 unsigned i, j; 640 boolean success; 641 642 for (i = 0; i < format_desc->block.height; ++i) { 643 for (j = 0; j < format_desc->block.width; ++j) { 644 unpacked[i][j] = test->unpacked[i][j][1]; 645 if (test->unpacked[i][j][0]) { 646 return TRUE; 647 } 648 } 649 } 650 651 memset(packed, 0, sizeof packed); 652 653 format_desc->pack_s_8uint(packed, 0, 654 &unpacked[0][0], sizeof unpacked[0], 655 format_desc->block.width, format_desc->block.height); 656 657 success = TRUE; 658 for (i = 0; i < format_desc->block.bits/8; ++i) 659 if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i])) 660 success = FALSE; 661 662 if (!success) { 663 print_packed(format_desc, "FAILED: ", packed, " obtained\n"); 664 print_packed(format_desc, " ", test->packed, " expected\n"); 665 } 666 667 return success; 668} 669 670 671/* Touch-test that the unorm/snorm flags are set up right by codegen. */ 672static boolean 673test_format_norm_flags(const struct util_format_description *format_desc) 674{ 675 boolean success = TRUE; 676 677#define FORMAT_CASE(format, unorm, snorm) \ 678 case format: \ 679 success = (format_desc->is_unorm == unorm && \ 680 format_desc->is_snorm == snorm); \ 681 break 682 683 switch (format_desc->format) { 684 FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_UNORM, TRUE, FALSE); 685 FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_SRGB, TRUE, FALSE); 686 FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_SNORM, FALSE, TRUE); 687 FORMAT_CASE(PIPE_FORMAT_R32_FLOAT, FALSE, FALSE); 688 FORMAT_CASE(PIPE_FORMAT_X8Z24_UNORM, TRUE, FALSE); 689 FORMAT_CASE(PIPE_FORMAT_S8X24_UINT, FALSE, FALSE); 690 FORMAT_CASE(PIPE_FORMAT_DXT1_RGB, TRUE, FALSE); 691 FORMAT_CASE(PIPE_FORMAT_ETC2_RGB8, TRUE, FALSE); 692 FORMAT_CASE(PIPE_FORMAT_ETC2_R11_SNORM, FALSE, TRUE); 693 FORMAT_CASE(PIPE_FORMAT_ASTC_4x4, TRUE, FALSE); 694 FORMAT_CASE(PIPE_FORMAT_BPTC_RGBA_UNORM, TRUE, FALSE); 695 FORMAT_CASE(PIPE_FORMAT_BPTC_RGB_FLOAT, FALSE, FALSE); 696 default: 697 success = !(format_desc->is_unorm && format_desc->is_snorm); 698 break; 699 } 700#undef FORMAT_CASE 701 702 if (!success) { 703 printf("FAILED: %s (unorm %s, snorm %s)\n", 704 format_desc->short_name, 705 format_desc->is_unorm ? "yes" : "no", 706 format_desc->is_snorm ? "yes" : "no"); 707 } 708 709 return success; 710} 711 712typedef boolean 713(*test_func_t)(const struct util_format_description *format_desc, 714 const struct util_format_test_case *test); 715 716 717static boolean 718test_one_func(const struct util_format_description *format_desc, 719 test_func_t func, 720 const char *suffix) 721{ 722 unsigned i; 723 boolean success = TRUE; 724 725 printf("Testing util_format_%s_%s ...\n", 726 format_desc->short_name, suffix); 727 fflush(stdout); 728 729 for (i = 0; i < util_format_nr_test_cases; ++i) { 730 const struct util_format_test_case *test = &util_format_test_cases[i]; 731 732 if (test->format == format_desc->format) { 733 if (!func(format_desc, &util_format_test_cases[i])) { 734 success = FALSE; 735 } 736 } 737 } 738 739 return success; 740} 741 742static boolean 743test_format_metadata(const struct util_format_description *format_desc, 744 boolean (*func)(const struct util_format_description *format_desc), 745 const char *suffix) 746{ 747 boolean success = TRUE; 748 749 printf("Testing util_format_%s_%s ...\n", format_desc->short_name, suffix); 750 fflush(stdout); 751 752 if (!func(format_desc)) { 753 success = FALSE; 754 } 755 756 return success; 757} 758 759static boolean 760test_all(void) 761{ 762 enum pipe_format format; 763 boolean success = TRUE; 764 765 for (format = 1; format < PIPE_FORMAT_COUNT; ++format) { 766 const struct util_format_description *format_desc; 767 768 format_desc = util_format_description(format); 769 if (!format_desc) { 770 continue; 771 } 772 773 assert(format_desc->block.bits <= UTIL_FORMAT_MAX_PACKED_BYTES * 8); 774 assert(format_desc->block.height <= UTIL_FORMAT_MAX_UNPACKED_HEIGHT); 775 assert(format_desc->block.width <= UTIL_FORMAT_MAX_UNPACKED_WIDTH); 776 777# define TEST_ONE_FUNC(name) \ 778 if (format_desc->name) { \ 779 if (!test_one_func(format_desc, &test_format_##name, #name)) { \ 780 success = FALSE; \ 781 } \ 782 } 783 784# define TEST_FORMAT_METADATA(name) \ 785 if (!test_format_metadata(format_desc, &test_format_##name, #name)) { \ 786 success = FALSE; \ 787 } \ 788 789 TEST_ONE_FUNC(fetch_rgba_float); 790 TEST_ONE_FUNC(pack_rgba_float); 791 TEST_ONE_FUNC(unpack_rgba_float); 792 TEST_ONE_FUNC(pack_rgba_8unorm); 793 TEST_ONE_FUNC(unpack_rgba_8unorm); 794 795 TEST_ONE_FUNC(unpack_z_32unorm); 796 TEST_ONE_FUNC(pack_z_32unorm); 797 TEST_ONE_FUNC(unpack_z_float); 798 TEST_ONE_FUNC(pack_z_float); 799 TEST_ONE_FUNC(unpack_s_8uint); 800 TEST_ONE_FUNC(pack_s_8uint); 801 802 TEST_FORMAT_METADATA(norm_flags); 803 804# undef TEST_ONE_FUNC 805# undef TEST_ONE_FORMAT 806 } 807 808 return success; 809} 810 811 812int main(int argc, char **argv) 813{ 814 boolean success; 815 816 success = test_all(); 817 818 return success ? 0 : 1; 819} 820