1 /**************************************************************************
3 * Copyright 2009-2010 VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
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"
40 compare_float(float x
, float y
)
47 if (error
> FLT_EPSILON
) {
56 print_packed(const struct util_format_description
*format_desc
,
58 const uint8_t *packed
,
65 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
) {
66 printf("%s%02x", sep
, packed
[i
]);
74 print_unpacked_rgba_doubl(const struct util_format_description
*format_desc
,
76 const double unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4],
83 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
84 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
85 printf("%s{%f, %f, %f, %f}", sep
, unpacked
[i
][j
][0], unpacked
[i
][j
][1], unpacked
[i
][j
][2], unpacked
[i
][j
][3]);
95 print_unpacked_rgba_float(const struct util_format_description
*format_desc
,
97 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4],
101 const char *sep
= "";
103 printf("%s", prefix
);
104 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
105 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
106 printf("%s{%f, %f, %f, %f}", sep
, unpacked
[i
][j
][0], unpacked
[i
][j
][1], unpacked
[i
][j
][2], unpacked
[i
][j
][3]);
111 printf("%s", suffix
);
116 print_unpacked_rgba_8unorm(const struct util_format_description
*format_desc
,
118 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4],
122 const char *sep
= "";
124 printf("%s", prefix
);
125 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
126 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
127 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 printf("%s", suffix
);
136 print_unpacked_z_float(const struct util_format_description
*format_desc
,
138 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
],
142 const char *sep
= "";
144 printf("%s", prefix
);
145 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
146 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
147 printf("%s%f", sep
, unpacked
[i
][j
]);
152 printf("%s", suffix
);
157 print_unpacked_z_32unorm(const struct util_format_description
*format_desc
,
159 uint32_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
],
163 const char *sep
= "";
165 printf("%s", prefix
);
166 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
167 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
168 printf("%s0x%08x", sep
, unpacked
[i
][j
]);
172 printf("%s", suffix
);
177 print_unpacked_s_8uscaled(const struct util_format_description
*format_desc
,
179 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
],
183 const char *sep
= "";
185 printf("%s", prefix
);
186 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
187 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
188 printf("%s0x%02x", sep
, unpacked
[i
][j
]);
192 printf("%s", suffix
);
197 test_format_fetch_rgba_float(const struct util_format_description
*format_desc
,
198 const struct util_format_test_case
*test
)
200 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
205 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
206 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
207 format_desc
->fetch_rgba_float(unpacked
[i
][j
], test
->packed
, j
, i
);
208 for (k
= 0; k
< 4; ++k
) {
209 if (!compare_float(test
->unpacked
[i
][j
][k
], unpacked
[i
][j
][k
])) {
217 print_unpacked_rgba_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
218 print_unpacked_rgba_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
226 test_format_unpack_rgba_float(const struct util_format_description
*format_desc
,
227 const struct util_format_test_case
*test
)
229 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
233 format_desc
->unpack_rgba_float(&unpacked
[0][0][0], sizeof unpacked
[0],
235 format_desc
->block
.width
, format_desc
->block
.height
);
238 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
239 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
240 for (k
= 0; k
< 4; ++k
) {
241 if (!compare_float(test
->unpacked
[i
][j
][k
], unpacked
[i
][j
][k
])) {
249 print_unpacked_rgba_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
250 print_unpacked_rgba_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
258 test_format_pack_rgba_float(const struct util_format_description
*format_desc
,
259 const struct util_format_test_case
*test
)
261 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4];
262 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
266 if (test
->format
== PIPE_FORMAT_DXT1_RGBA
) {
268 * Skip S3TC as packed representation is not canonical.
270 * TODO: Do a round trip conversion.
275 memset(packed
, 0, sizeof packed
);
276 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
277 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
278 for (k
= 0; k
< 4; ++k
) {
279 unpacked
[i
][j
][k
] = (float) test
->unpacked
[i
][j
][k
];
284 format_desc
->pack_rgba_float(packed
, 0,
285 &unpacked
[0][0][0], sizeof unpacked
[0],
286 format_desc
->block
.width
, format_desc
->block
.height
);
289 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
290 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
294 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
295 print_packed(format_desc
, " ", test
->packed
, " expected\n");
303 convert_float_to_8unorm(uint8_t *dst
, const double *src
)
306 boolean accurate
= TRUE
;
308 for (i
= 0; i
< UTIL_FORMAT_MAX_UNPACKED_HEIGHT
*UTIL_FORMAT_MAX_UNPACKED_WIDTH
*4; ++i
) {
313 else if (src
[i
] > 1.0) {
318 dst
[i
] = src
[i
] * 255.0;
327 test_format_unpack_rgba_8unorm(const struct util_format_description
*format_desc
,
328 const struct util_format_test_case
*test
)
330 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
331 uint8_t expected
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
335 format_desc
->unpack_rgba_8unorm(&unpacked
[0][0][0], sizeof unpacked
[0],
337 format_desc
->block
.width
, format_desc
->block
.height
);
339 convert_float_to_8unorm(&expected
[0][0][0], &test
->unpacked
[0][0][0]);
342 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
343 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
344 for (k
= 0; k
< 4; ++k
) {
345 if (expected
[i
][j
][k
] != unpacked
[i
][j
][k
]) {
353 print_unpacked_rgba_8unorm(format_desc
, "FAILED: ", unpacked
, " obtained\n");
354 print_unpacked_rgba_8unorm(format_desc
, " ", expected
, " expected\n");
362 test_format_pack_rgba_8unorm(const struct util_format_description
*format_desc
,
363 const struct util_format_test_case
*test
)
365 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4];
366 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
370 if (test
->format
== PIPE_FORMAT_DXT1_RGBA
) {
372 * Skip S3TC as packed representation is not canonical.
374 * TODO: Do a round trip conversion.
379 if (!convert_float_to_8unorm(&unpacked
[0][0][0], &test
->unpacked
[0][0][0])) {
381 * Skip test cases which cannot be represented by four unorm bytes.
386 memset(packed
, 0, sizeof packed
);
388 format_desc
->pack_rgba_8unorm(packed
, 0,
389 &unpacked
[0][0][0], sizeof unpacked
[0],
390 format_desc
->block
.width
, format_desc
->block
.height
);
393 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
394 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
398 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
399 print_packed(format_desc
, " ", test
->packed
, " expected\n");
407 test_format_unpack_z_float(const struct util_format_description
*format_desc
,
408 const struct util_format_test_case
*test
)
410 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
414 format_desc
->unpack_z_float(&unpacked
[0][0], sizeof unpacked
[0],
416 format_desc
->block
.width
, format_desc
->block
.height
);
419 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
420 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
421 if (!compare_float(test
->unpacked
[i
][j
][0], unpacked
[i
][j
])) {
428 print_unpacked_z_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
429 print_unpacked_rgba_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
437 test_format_pack_z_float(const struct util_format_description
*format_desc
,
438 const struct util_format_test_case
*test
)
440 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
];
441 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
445 memset(packed
, 0, sizeof packed
);
446 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
447 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
448 unpacked
[i
][j
] = (float) test
->unpacked
[i
][j
][0];
449 if (test
->unpacked
[i
][j
][1]) {
455 format_desc
->pack_z_float(packed
, 0,
456 &unpacked
[0][0], sizeof unpacked
[0],
457 format_desc
->block
.width
, format_desc
->block
.height
);
460 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
461 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
465 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
466 print_packed(format_desc
, " ", test
->packed
, " expected\n");
474 test_format_unpack_z_32unorm(const struct util_format_description
*format_desc
,
475 const struct util_format_test_case
*test
)
477 uint32_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
478 uint32_t expected
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
482 format_desc
->unpack_z_32unorm(&unpacked
[0][0], sizeof unpacked
[0],
484 format_desc
->block
.width
, format_desc
->block
.height
);
486 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
487 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
488 expected
[i
][j
] = test
->unpacked
[i
][j
][0] * 0xffffffff;
493 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
494 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
495 if (expected
[i
][j
] != unpacked
[i
][j
]) {
502 print_unpacked_z_32unorm(format_desc
, "FAILED: ", unpacked
, " obtained\n");
503 print_unpacked_z_32unorm(format_desc
, " ", expected
, " expected\n");
511 test_format_pack_z_32unorm(const struct util_format_description
*format_desc
,
512 const struct util_format_test_case
*test
)
514 uint32_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
];
515 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
519 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
520 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
521 unpacked
[i
][j
] = test
->unpacked
[i
][j
][0] * 0xffffffff;
522 if (test
->unpacked
[i
][j
][1]) {
528 memset(packed
, 0, sizeof packed
);
530 format_desc
->pack_z_32unorm(packed
, 0,
531 &unpacked
[0][0], sizeof unpacked
[0],
532 format_desc
->block
.width
, format_desc
->block
.height
);
535 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
536 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
540 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
541 print_packed(format_desc
, " ", test
->packed
, " expected\n");
549 test_format_unpack_s_8uscaled(const struct util_format_description
*format_desc
,
550 const struct util_format_test_case
*test
)
552 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
553 uint8_t expected
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
557 format_desc
->unpack_s_8uscaled(&unpacked
[0][0], sizeof unpacked
[0],
559 format_desc
->block
.width
, format_desc
->block
.height
);
561 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
562 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
563 expected
[i
][j
] = test
->unpacked
[i
][j
][1];
568 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
569 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
570 if (expected
[i
][j
] != unpacked
[i
][j
]) {
577 print_unpacked_s_8uscaled(format_desc
, "FAILED: ", unpacked
, " obtained\n");
578 print_unpacked_s_8uscaled(format_desc
, " ", expected
, " expected\n");
586 test_format_pack_s_8uscaled(const struct util_format_description
*format_desc
,
587 const struct util_format_test_case
*test
)
589 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
];
590 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
594 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
595 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
596 unpacked
[i
][j
] = test
->unpacked
[i
][j
][1];
597 if (test
->unpacked
[i
][j
][0]) {
603 memset(packed
, 0, sizeof packed
);
605 format_desc
->pack_s_8uscaled(packed
, 0,
606 &unpacked
[0][0], sizeof unpacked
[0],
607 format_desc
->block
.width
, format_desc
->block
.height
);
610 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
611 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
615 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
616 print_packed(format_desc
, " ", test
->packed
, " expected\n");
624 (*test_func_t
)(const struct util_format_description
*format_desc
,
625 const struct util_format_test_case
*test
);
629 test_one_func(const struct util_format_description
*format_desc
,
636 printf("Testing util_format_%s_%s ...\n",
637 format_desc
->short_name
, suffix
);
639 for (i
= 0; i
< util_format_nr_test_cases
; ++i
) {
640 const struct util_format_test_case
*test
= &util_format_test_cases
[i
];
642 if (test
->format
== format_desc
->format
) {
643 if (!func(format_desc
, &util_format_test_cases
[i
])) {
656 enum pipe_format format
;
659 for (format
= 1; format
< PIPE_FORMAT_COUNT
; ++format
) {
660 const struct util_format_description
*format_desc
;
662 format_desc
= util_format_description(format
);
667 if (format_desc
->layout
== UTIL_FORMAT_LAYOUT_S3TC
&&
668 !util_format_s3tc_enabled
) {
672 # define TEST_ONE_FUNC(name) \
673 if (format_desc->name) { \
674 if (!test_one_func(format_desc, &test_format_##name, #name)) { \
679 TEST_ONE_FUNC(fetch_rgba_float
);
680 TEST_ONE_FUNC(pack_rgba_float
);
681 TEST_ONE_FUNC(unpack_rgba_float
);
682 TEST_ONE_FUNC(pack_rgba_8unorm
);
683 TEST_ONE_FUNC(unpack_rgba_8unorm
);
685 TEST_ONE_FUNC(unpack_z_32unorm
);
686 TEST_ONE_FUNC(pack_z_32unorm
);
687 TEST_ONE_FUNC(unpack_z_float
);
688 TEST_ONE_FUNC(pack_z_float
);
689 TEST_ONE_FUNC(unpack_s_8uscaled
);
690 TEST_ONE_FUNC(pack_s_8uscaled
);
692 # undef TEST_ONE_FUNC
699 int main(int argc
, char **argv
)
703 util_format_s3tc_init();
705 success
= test_all();
707 return success
? 0 : 1;