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_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_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_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 test_format_fetch_rgba_float(const struct util_format_description
*format_desc
,
137 const struct util_format_test_case
*test
)
139 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
144 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
145 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
146 format_desc
->fetch_rgba_float(unpacked
[i
][j
], test
->packed
, j
, i
);
147 for (k
= 0; k
< 4; ++k
) {
148 if (!compare_float(test
->unpacked
[i
][j
][k
], unpacked
[i
][j
][k
])) {
156 print_unpacked_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
157 print_unpacked_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
165 test_format_unpack_rgba_float(const struct util_format_description
*format_desc
,
166 const struct util_format_test_case
*test
)
168 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
172 format_desc
->unpack_rgba_float(&unpacked
[0][0][0], sizeof unpacked
[0],
174 format_desc
->block
.width
, format_desc
->block
.height
);
177 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
178 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
179 for (k
= 0; k
< 4; ++k
) {
180 if (!compare_float(test
->unpacked
[i
][j
][k
], unpacked
[i
][j
][k
])) {
188 print_unpacked_float(format_desc
, "FAILED: ", unpacked
, " obtained\n");
189 print_unpacked_doubl(format_desc
, " ", test
->unpacked
, " expected\n");
198 test_format_pack_rgba_float(const struct util_format_description
*format_desc
,
199 const struct util_format_test_case
*test
)
201 float unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4];
202 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
206 if (test
->format
== PIPE_FORMAT_DXT1_RGBA
) {
208 * Skip S3TC as packed representation is not canonical.
210 * TODO: Do a round trip conversion.
215 memset(packed
, 0, sizeof packed
);
216 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
217 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
218 for (k
= 0; k
< 4; ++k
) {
219 unpacked
[i
][j
][k
] = (float) test
->unpacked
[i
][j
][k
];
224 format_desc
->pack_rgba_float(packed
, 0,
225 &unpacked
[0][0][0], sizeof unpacked
[0],
226 format_desc
->block
.width
, format_desc
->block
.height
);
229 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
230 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
234 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
235 print_packed(format_desc
, " ", test
->packed
, " expected\n");
243 convert_float_to_8unorm(uint8_t *dst
, const double *src
)
246 boolean accurate
= TRUE
;
248 for (i
= 0; i
< UTIL_FORMAT_MAX_UNPACKED_HEIGHT
*UTIL_FORMAT_MAX_UNPACKED_WIDTH
*4; ++i
) {
253 else if (src
[i
] > 1.0) {
258 dst
[i
] = src
[i
] * 255.0;
267 test_format_unpack_rgba_8unorm(const struct util_format_description
*format_desc
,
268 const struct util_format_test_case
*test
)
270 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
271 uint8_t expected
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4] = { { { 0 } } };
275 format_desc
->unpack_rgba_8unorm(&unpacked
[0][0][0], sizeof unpacked
[0],
277 format_desc
->block
.width
, format_desc
->block
.height
);
279 convert_float_to_8unorm(&expected
[0][0][0], &test
->unpacked
[0][0][0]);
282 for (i
= 0; i
< format_desc
->block
.height
; ++i
) {
283 for (j
= 0; j
< format_desc
->block
.width
; ++j
) {
284 for (k
= 0; k
< 4; ++k
) {
285 if (expected
[i
][j
][k
] != unpacked
[i
][j
][k
]) {
293 print_unpacked_8unorm(format_desc
, "FAILED: ", unpacked
, " obtained\n");
294 print_unpacked_8unorm(format_desc
, " ", expected
, " expected\n");
302 test_format_pack_rgba_8unorm(const struct util_format_description
*format_desc
,
303 const struct util_format_test_case
*test
)
305 uint8_t unpacked
[UTIL_FORMAT_MAX_UNPACKED_HEIGHT
][UTIL_FORMAT_MAX_UNPACKED_WIDTH
][4];
306 uint8_t packed
[UTIL_FORMAT_MAX_PACKED_BYTES
];
310 if (test
->format
== PIPE_FORMAT_DXT1_RGBA
) {
312 * Skip S3TC as packed representation is not canonical.
314 * TODO: Do a round trip conversion.
319 if (!convert_float_to_8unorm(&unpacked
[0][0][0], &test
->unpacked
[0][0][0])) {
321 * Skip test cases which cannot be represented by four unorm bytes.
326 memset(packed
, 0, sizeof packed
);
328 format_desc
->pack_rgba_8unorm(packed
, 0,
329 &unpacked
[0][0][0], sizeof unpacked
[0],
330 format_desc
->block
.width
, format_desc
->block
.height
);
333 for (i
= 0; i
< format_desc
->block
.bits
/8; ++i
)
334 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
338 print_packed(format_desc
, "FAILED: ", packed
, " obtained\n");
339 print_packed(format_desc
, " ", test
->packed
, " expected\n");
347 (*test_func_t
)(const struct util_format_description
*format_desc
,
348 const struct util_format_test_case
*test
);
352 test_one(test_func_t func
, const char *suffix
)
354 enum pipe_format last_format
= PIPE_FORMAT_NONE
;
358 for (i
= 0; i
< util_format_nr_test_cases
; ++i
) {
359 const struct util_format_test_case
*test
= &util_format_test_cases
[i
];
360 const struct util_format_description
*format_desc
;
363 format_desc
= util_format_description(test
->format
);
365 if (format_desc
->layout
== UTIL_FORMAT_LAYOUT_S3TC
&&
366 !util_format_s3tc_enabled
) {
370 if (test
->format
!= last_format
) {
371 printf("%s util_format_%s_%s ...\n",
372 skip
? "Skipping" : "Testing", format_desc
->short_name
, suffix
);
373 last_format
= test
->format
;
377 if (!func(format_desc
, &util_format_test_cases
[i
])) {
392 if (!test_one(&test_format_fetch_rgba_float
, "fetch_rgba_float"))
395 if (!test_one(&test_format_pack_rgba_float
, "pack_rgba_float"))
398 if (!test_one(&test_format_unpack_rgba_float
, "unpack_rgba_float"))
401 if (!test_one(&test_format_pack_rgba_8unorm
, "pack_rgba_8unorm"))
404 if (!test_one(&test_format_unpack_rgba_8unorm
, "unpack_rgba_8unorm"))
411 int main(int argc
, char **argv
)
415 util_format_s3tc_init();
417 success
= test_all();
419 return success
? 0 : 1;