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
]);
75 print_unpacked_rgba_doubl(const struct util_format_description
*format_desc
,
77 const double unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4],
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]);
97 print_unpacked_rgba_float(const struct util_format_description
*format_desc
,
99 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4],
103 const char *sep
= "";
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]);
113 printf("%s", suffix
);
119 print_unpacked_rgba_8unorm(const struct util_format_description
*format_desc
,
121 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4],
125 const char *sep
= "";
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]);
134 printf("%s", suffix
);
140 print_unpacked_z_float(const struct util_format_description
*format_desc
,
142 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
],
146 const char *sep
= "";
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
]);
156 printf("%s", suffix
);
162 print_unpacked_z_32unorm(const struct util_format_description
*format_desc
,
164 uint32_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
],
168 const char *sep
= "";
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
]);
177 printf("%s", suffix
);
183 print_unpacked_s_8uint(const struct util_format_description
*format_desc
,
185 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
],
189 const char *sep
= "";
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
]);
198 printf("%s", suffix
);
204 test_format_fetch_rgba_float(const struct util_format_description
*format_desc
,
205 const struct util_format_test_case
*test
)
207 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
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
])) {
224 print_unpacked_rgba_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
225 print_unpacked_rgba_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
233 test_format_unpack_rgba_float(const struct util_format_description
*format_desc
,
234 const struct util_format_test_case
*test
)
236 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
240 format_desc
->unpack_rgba_float(&unpacked
[0][0][0], sizeof unpacked
[0],
242 format_desc
->block
.width
, format_desc
->block
.height
);
245 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
246 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
247 for (k
= 0; k
< 4; ++k
) {
248 if (!compare_float(test
->unpacked
[i
][j
][k
], unpacked
[i
][j
][k
])) {
256 print_unpacked_rgba_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
257 print_unpacked_rgba_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
265 test_format_pack_rgba_float(const struct util_format_description
*format_desc
,
266 const struct util_format_test_case
*test
)
268 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4];
269 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
273 if (test
->format
== PIPE_FORMAT_DXT1_RGBA
) {
275 * Skip S3TC as packed representation is not canonical.
277 * TODO: Do a round trip conversion.
282 memset(packed
, 0, sizeof packed
);
283 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
284 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
285 for (k
= 0; k
< 4; ++k
) {
286 unpacked
[i
][j
][k
] = (float) test
->unpacked
[i
][j
][k
];
291 format_desc
->pack_rgba_float(packed
, 0,
292 &unpacked
[0][0][0], sizeof unpacked
[0],
293 format_desc
->block
.width
, format_desc
->block
.height
);
296 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
297 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
301 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
302 print_packed(format_desc
, " ", test
->packed
, " expected\n");
310 convert_float_to_8unorm(uint8_t *dst
, const double *src
)
313 boolean accurate
= TRUE
;
315 for (i
= 0; i
< UTIL_FORMAT_MAX_UNPACKED_HEIGHT
*UTIL_FORMAT_MAX_UNPACKED_WIDTH
*4; ++i
) {
320 else if (src
[i
] > 1.0) {
325 dst
[i
] = src
[i
] * 255.0;
334 test_format_unpack_rgba_8unorm(const struct util_format_description
*format_desc
,
335 const struct util_format_test_case
*test
)
337 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
338 uint8_t expected
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
342 format_desc
->unpack_rgba_8unorm(&unpacked
[0][0][0], sizeof unpacked
[0],
344 format_desc
->block
.width
, format_desc
->block
.height
);
346 convert_float_to_8unorm(&expected
[0][0][0], &test
->unpacked
[0][0][0]);
349 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
350 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
351 for (k
= 0; k
< 4; ++k
) {
352 if (expected
[i
][j
][k
] != unpacked
[i
][j
][k
]) {
360 print_unpacked_rgba_8unorm(format_desc
, "FAILED: ", unpacked
, " obtained\n");
361 print_unpacked_rgba_8unorm(format_desc
, " ", expected
, " expected\n");
369 test_format_pack_rgba_8unorm(const struct util_format_description
*format_desc
,
370 const struct util_format_test_case
*test
)
372 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4];
373 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
377 if (test
->format
== PIPE_FORMAT_DXT1_RGBA
) {
379 * Skip S3TC as packed representation is not canonical.
381 * TODO: Do a round trip conversion.
386 if (!convert_float_to_8unorm(&unpacked
[0][0][0], &test
->unpacked
[0][0][0])) {
388 * Skip test cases which cannot be represented by four unorm bytes.
393 memset(packed
, 0, sizeof packed
);
395 format_desc
->pack_rgba_8unorm(packed
, 0,
396 &unpacked
[0][0][0], sizeof unpacked
[0],
397 format_desc
->block
.width
, format_desc
->block
.height
);
400 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
401 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
405 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
406 print_packed(format_desc
, " ", test
->packed
, " expected\n");
414 test_format_unpack_z_float(const struct util_format_description
*format_desc
,
415 const struct util_format_test_case
*test
)
417 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
421 format_desc
->unpack_z_float(&unpacked
[0][0], sizeof unpacked
[0],
423 format_desc
->block
.width
, format_desc
->block
.height
);
426 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
427 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
428 if (!compare_float(test
->unpacked
[i
][j
][0], unpacked
[i
][j
])) {
435 print_unpacked_z_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
436 print_unpacked_rgba_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
444 test_format_pack_z_float(const struct util_format_description
*format_desc
,
445 const struct util_format_test_case
*test
)
447 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
];
448 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
452 memset(packed
, 0, sizeof packed
);
453 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
454 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
455 unpacked
[i
][j
] = (float) test
->unpacked
[i
][j
][0];
456 if (test
->unpacked
[i
][j
][1]) {
462 format_desc
->pack_z_float(packed
, 0,
463 &unpacked
[0][0], sizeof unpacked
[0],
464 format_desc
->block
.width
, format_desc
->block
.height
);
467 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
468 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
472 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
473 print_packed(format_desc
, " ", test
->packed
, " expected\n");
481 test_format_unpack_z_32unorm(const struct util_format_description
*format_desc
,
482 const struct util_format_test_case
*test
)
484 uint32_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
485 uint32_t expected
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
489 format_desc
->unpack_z_32unorm(&unpacked
[0][0], sizeof unpacked
[0],
491 format_desc
->block
.width
, format_desc
->block
.height
);
493 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
494 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
495 expected
[i
][j
] = test
->unpacked
[i
][j
][0] * 0xffffffff;
500 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
501 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
502 if (expected
[i
][j
] != unpacked
[i
][j
]) {
509 print_unpacked_z_32unorm(format_desc
, "FAILED: ", unpacked
, " obtained\n");
510 print_unpacked_z_32unorm(format_desc
, " ", expected
, " expected\n");
518 test_format_pack_z_32unorm(const struct util_format_description
*format_desc
,
519 const struct util_format_test_case
*test
)
521 uint32_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
];
522 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
526 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
527 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
528 unpacked
[i
][j
] = test
->unpacked
[i
][j
][0] * 0xffffffff;
529 if (test
->unpacked
[i
][j
][1]) {
535 memset(packed
, 0, sizeof packed
);
537 format_desc
->pack_z_32unorm(packed
, 0,
538 &unpacked
[0][0], sizeof unpacked
[0],
539 format_desc
->block
.width
, format_desc
->block
.height
);
542 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
543 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
547 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
548 print_packed(format_desc
, " ", test
->packed
, " expected\n");
556 test_format_unpack_s_8uint(const struct util_format_description
*format_desc
,
557 const struct util_format_test_case
*test
)
559 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
560 uint8_t expected
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
] = { { 0 } };
564 format_desc
->unpack_s_8uint(&unpacked
[0][0], sizeof unpacked
[0],
566 format_desc
->block
.width
, format_desc
->block
.height
);
568 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
569 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
570 expected
[i
][j
] = test
->unpacked
[i
][j
][1];
575 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
576 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
577 if (expected
[i
][j
] != unpacked
[i
][j
]) {
584 print_unpacked_s_8uint(format_desc
, "FAILED: ", unpacked
, " obtained\n");
585 print_unpacked_s_8uint(format_desc
, " ", expected
, " expected\n");
593 test_format_pack_s_8uint(const struct util_format_description
*format_desc
,
594 const struct util_format_test_case
*test
)
596 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
];
597 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
601 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
602 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
603 unpacked
[i
][j
] = test
->unpacked
[i
][j
][1];
604 if (test
->unpacked
[i
][j
][0]) {
610 memset(packed
, 0, sizeof packed
);
612 format_desc
->pack_s_8uint(packed
, 0,
613 &unpacked
[0][0], sizeof unpacked
[0],
614 format_desc
->block
.width
, format_desc
->block
.height
);
617 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
618 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
622 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
623 print_packed(format_desc
, " ", test
->packed
, " expected\n");
631 (*test_func_t
)(const struct util_format_description
*format_desc
,
632 const struct util_format_test_case
*test
);
636 test_one_func(const struct util_format_description
*format_desc
,
641 boolean success
= TRUE
;
643 printf("Testing util_format_%s_%s ...\n",
644 format_desc
->short_name
, suffix
);
647 for (i
= 0; i
< util_format_nr_test_cases
; ++i
) {
648 const struct util_format_test_case
*test
= &util_format_test_cases
[i
];
650 if (test
->format
== format_desc
->format
) {
651 if (!func(format_desc
, &util_format_test_cases
[i
])) {
664 enum pipe_format format
;
665 boolean success
= TRUE
;
667 for (format
= 1; format
< PIPE_FORMAT_COUNT
; ++format
) {
668 const struct util_format_description
*format_desc
;
670 format_desc
= util_format_description(format
);
675 if (format_desc
->layout
== UTIL_FORMAT_LAYOUT_S3TC
&&
676 !util_format_s3tc_enabled
) {
680 # define TEST_ONE_FUNC(name) \
681 if (format_desc->name) { \
682 if (!test_one_func(format_desc, &test_format_##name, #name)) { \
687 TEST_ONE_FUNC(fetch_rgba_float
);
688 TEST_ONE_FUNC(pack_rgba_float
);
689 TEST_ONE_FUNC(unpack_rgba_float
);
690 TEST_ONE_FUNC(pack_rgba_8unorm
);
691 TEST_ONE_FUNC(unpack_rgba_8unorm
);
693 TEST_ONE_FUNC(unpack_z_32unorm
);
694 TEST_ONE_FUNC(pack_z_32unorm
);
695 TEST_ONE_FUNC(unpack_z_float
);
696 TEST_ONE_FUNC(pack_z_float
);
697 TEST_ONE_FUNC(unpack_s_8uint
);
698 TEST_ONE_FUNC(pack_s_8uint
);
700 # undef TEST_ONE_FUNC
707 int main(int argc
, char **argv
)
711 util_format_s3tc_init();
713 success
= test_all();
715 return success
? 0 : 1;