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 **************************************************************************/
32 #include "util/u_format.h"
33 #include "util/u_format_pack.h"
36 #define MAX_PACKED_BYTES 4
40 * A (packed, unpacked) color pair.
42 struct util_format_test_case
44 enum pipe_format format
;
47 * Mask of the bits that actually meaningful data. Used to mask out the
50 uint8_t mask
[MAX_PACKED_BYTES
];
52 uint8_t packed
[MAX_PACKED_BYTES
];
62 * Helper macros to create the packed bytes for longer words.
65 #define PACKED_1x8(x) {x, 0, 0, 0}
66 #define PACKED_4x8(x, y, z, w) {x, y, z, w}
67 #define PACKED_1x32(x) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, ((x) >> 24) & 0xff}
68 #define PACKED_1x16(x) {(x) & 0xff, ((x) >> 8) & 0xff, 0, 0}
74 * These were manually entered. We could generate these
76 * To keep this to a we cover only the corner cases, which should produce
77 * good enough coverage since that pixel format transformations are afine for
80 static const struct util_format_test_case
83 {PIPE_FORMAT_B5G6R5_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
84 {PIPE_FORMAT_B5G6R5_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 1.0}},
85 {PIPE_FORMAT_B5G6R5_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x07e0), {0.0, 1.0, 0.0, 1.0}},
86 {PIPE_FORMAT_B5G6R5_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xf800), {1.0, 0.0, 0.0, 1.0}},
87 {PIPE_FORMAT_B5G6R5_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
89 {PIPE_FORMAT_B5G5R5A1_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
90 {PIPE_FORMAT_B5G5R5A1_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 0.0}},
91 {PIPE_FORMAT_B5G5R5A1_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x03e0), {0.0, 1.0, 0.0, 0.0}},
92 {PIPE_FORMAT_B5G5R5A1_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x7c00), {1.0, 0.0, 0.0, 0.0}},
93 {PIPE_FORMAT_B5G5R5A1_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x8000), {0.0, 0.0, 0.0, 1.0}},
94 {PIPE_FORMAT_B5G5R5A1_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
96 {PIPE_FORMAT_B4G4R4A4_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
97 {PIPE_FORMAT_B4G4R4A4_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x000f), {0.0, 0.0, 1.0, 0.0}},
98 {PIPE_FORMAT_B4G4R4A4_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x00f0), {0.0, 1.0, 0.0, 0.0}},
99 {PIPE_FORMAT_B4G4R4A4_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0f00), {1.0, 0.0, 0.0, 0.0}},
100 {PIPE_FORMAT_B4G4R4A4_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xf000), {0.0, 0.0, 0.0, 1.0}},
101 {PIPE_FORMAT_B4G4R4A4_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
103 {PIPE_FORMAT_R10G10B10A2_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
104 {PIPE_FORMAT_R10G10B10A2_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x000003ff), {1.0, 0.0, 0.0, 0.0}},
105 {PIPE_FORMAT_R10G10B10A2_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x000ffc00), {0.0, 1.0, 0.0, 0.0}},
106 {PIPE_FORMAT_R10G10B10A2_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x3ff00000), {0.0, 0.0, 1.0, 0.0}},
107 {PIPE_FORMAT_R10G10B10A2_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xc0000000), {0.0, 0.0, 0.0, 1.0}},
108 {PIPE_FORMAT_R10G10B10A2_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
110 {PIPE_FORMAT_B8G8R8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
111 {PIPE_FORMAT_B8G8R8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 1.0, 0.0}},
112 {PIPE_FORMAT_B8G8R8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {0.0, 1.0, 0.0, 0.0}},
113 {PIPE_FORMAT_B8G8R8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {1.0, 0.0, 0.0, 0.0}},
114 {PIPE_FORMAT_B8G8R8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 0.0, 1.0}},
115 {PIPE_FORMAT_B8G8R8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
117 {PIPE_FORMAT_B8G8R8X8_UNORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
118 {PIPE_FORMAT_B8G8R8X8_UNORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 1.0, 1.0}},
119 {PIPE_FORMAT_B8G8R8X8_UNORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000ff00), {0.0, 1.0, 0.0, 1.0}},
120 {PIPE_FORMAT_B8G8R8X8_UNORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ff0000), {1.0, 0.0, 0.0, 1.0}},
121 {PIPE_FORMAT_B8G8R8X8_UNORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 0.0, 1.0}},
122 {PIPE_FORMAT_B8G8R8X8_UNORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
124 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
125 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
126 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {1.0, 0.0, 0.0, 0.0}},
127 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 0.0}},
128 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 1.0, 0.0}},
129 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
131 {PIPE_FORMAT_X8R8G8B8_UNORM
, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
132 {PIPE_FORMAT_X8R8G8B8_UNORM
, PACKED_1x32(0xffffff00), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
133 {PIPE_FORMAT_X8R8G8B8_UNORM
, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), {1.0, 0.0, 0.0, 1.0}},
134 {PIPE_FORMAT_X8R8G8B8_UNORM
, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 1.0}},
135 {PIPE_FORMAT_X8R8G8B8_UNORM
, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), {0.0, 0.0, 1.0, 1.0}},
136 {PIPE_FORMAT_X8R8G8B8_UNORM
, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
139 {PIPE_FORMAT_R8G8B8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
140 {PIPE_FORMAT_R8G8B8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
141 {PIPE_FORMAT_R8G8B8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {0.0, 0.0, 1.0, 0.0}},
142 {PIPE_FORMAT_R8G8B8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 0.0}},
143 {PIPE_FORMAT_R8G8B8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {1.0, 0.0, 0.0, 0.0}},
144 {PIPE_FORMAT_R8G8B8A8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
147 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
148 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
149 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {1.0, 0.0, 0.0, 0.0}},
150 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 0.0}},
151 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 1.0, 0.0}},
152 {PIPE_FORMAT_A8R8G8B8_UNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
154 {PIPE_FORMAT_L8_UNORM
, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 1.0}},
155 {PIPE_FORMAT_L8_UNORM
, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 1.0, 1.0, 1.0}},
157 {PIPE_FORMAT_A8_UNORM
, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 0.0}},
158 {PIPE_FORMAT_A8_UNORM
, PACKED_1x8(0xff), PACKED_1x8(0xff), {0.0, 0.0, 0.0, 1.0}},
160 {PIPE_FORMAT_I8_UNORM
, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 0.0}},
161 {PIPE_FORMAT_I8_UNORM
, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 1.0, 1.0, 1.0}},
163 {PIPE_FORMAT_L8A8_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
164 {PIPE_FORMAT_L8A8_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x00ff), {1.0, 1.0, 1.0, 0.0}},
165 {PIPE_FORMAT_L8A8_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xff00), {0.0, 0.0, 0.0, 1.0}},
166 {PIPE_FORMAT_L8A8_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
168 {PIPE_FORMAT_L16_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
169 {PIPE_FORMAT_L16_UNORM
, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
171 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 0.0}},
172 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000007f), { 1.0, 0.0, 0.0, 0.0}},
173 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000081), {-1.0, 0.0, 0.0, 0.0}},
174 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00007f00), { 0.0, 1.0, 0.0, 0.0}},
175 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00008100), { 0.0, -1.0, 0.0, 0.0}},
176 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x007f0000), { 0.0, 0.0, 1.0, 0.0}},
177 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x00810000), { 0.0, 0.0, -1.0, 0.0}},
178 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x7f000000), { 0.0, 0.0, 0.0, 1.0}},
179 {PIPE_FORMAT_R8G8B8A8_SNORM
, PACKED_1x32(0xffffffff), PACKED_1x32(0x81000000), { 0.0, 0.0, 0.0, -1.0}},
181 {PIPE_FORMAT_R8SG8SB8UX8U_NORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
182 {PIPE_FORMAT_R8SG8SB8UX8U_NORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000007f), { 1.0, 0.0, 0.0, 1.0}},
183 {PIPE_FORMAT_R8SG8SB8UX8U_NORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000081), {-1.0, 0.0, 0.0, 1.0}},
184 {PIPE_FORMAT_R8SG8SB8UX8U_NORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00007f00), { 0.0, 1.0, 0.0, 1.0}},
185 {PIPE_FORMAT_R8SG8SB8UX8U_NORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00008100), { 0.0, -1.0, 0.0, 1.0}},
186 {PIPE_FORMAT_R8SG8SB8UX8U_NORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ff0000), { 0.0, 0.0, 1.0, 1.0}},
187 {PIPE_FORMAT_R8SG8SB8UX8U_NORM
, PACKED_1x32(0x00ffffff), PACKED_1x32(0xff000000), { 0.0, 0.0, 0.0, 1.0}},
189 {PIPE_FORMAT_R5SG5SB6U_NORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
190 {PIPE_FORMAT_R5SG5SB6U_NORM
, PACKED_1x16(0xffff), PACKED_1x16(0x000f), { 1.0, 0.0, 0.0, 1.0}},
191 {PIPE_FORMAT_R5SG5SB6U_NORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0011), {-1.0, 0.0, 0.0, 1.0}},
192 {PIPE_FORMAT_R5SG5SB6U_NORM
, PACKED_1x16(0xffff), PACKED_1x16(0x01e0), { 0.0, 1.0, 0.0, 1.0}},
193 {PIPE_FORMAT_R5SG5SB6U_NORM
, PACKED_1x16(0xffff), PACKED_1x16(0x0220), { 0.0, -1.0, 0.0, 1.0}},
194 {PIPE_FORMAT_R5SG5SB6U_NORM
, PACKED_1x16(0xffff), PACKED_1x16(0xfc00), { 0.0, 0.0, 1.0, 1.0}},
199 test_format_unpack(const struct util_format_test_case
*test
)
205 util_format_unpack_4f(test
->format
, unpacked
, test
->packed
);
208 for (i
= 0; i
< 4; ++i
)
209 if (test
->unpacked
[i
] != unpacked
[i
])
213 printf("FAILED: (%f %f %f %f) obtained\n", unpacked
[0], unpacked
[1], unpacked
[2], unpacked
[3]);
214 printf(" (%f %f %f %f) expected\n", test
->unpacked
[0], test
->unpacked
[1], test
->unpacked
[2], test
->unpacked
[3]);
222 test_format_pack(const struct util_format_test_case
*test
)
224 uint8_t packed
[MAX_PACKED_BYTES
];
228 memset(packed
, 0, sizeof packed
);
230 util_format_pack_4f(test
->format
, packed
, test
->unpacked
[0], test
->unpacked
[1], test
->unpacked
[2], test
->unpacked
[3]);
233 for (i
= 0; i
< MAX_PACKED_BYTES
; ++i
)
234 if ((test
->packed
[i
] & test
->mask
[i
]) != (packed
[i
] & test
->mask
[i
]))
238 printf("FAILED: (%02x %02x %02x %02x) obtained\n", packed
[0], packed
[1], packed
[2], packed
[3]);
239 printf(" (%02x %02x %02x %02x) expected\n", test
->packed
[0], test
->packed
[1], test
->packed
[2], test
->packed
[3]);
249 enum pipe_format last_format
= PIPE_FORMAT_NONE
;
253 for (i
= 0; i
< sizeof(test_cases
)/sizeof(test_cases
[0]); ++i
) {
254 if (test_cases
[i
].format
!= last_format
) {
255 const struct util_format_description
*format_desc
;
256 format_desc
= util_format_description(test_cases
[i
].format
);
257 fprintf(stderr
, "Testing %s ...\n", format_desc
->name
);
258 last_format
= test_cases
[i
].format
;
261 if (!test_format_pack(&test_cases
[i
]))
264 if (!test_format_unpack(&test_cases
[i
]))
272 int main(int argc
, char **argv
)
276 success
= test_all();
278 return success
? 0 : 1;