34e6bf31fcf9aae3da0d387af75b7fbd11bb498d
[mesa.git] / src / gallium / drivers / llvmpipe / lp_test_main.c
1 /**************************************************************************
2 *
3 * Copyright 2009 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 /**
30 * @file
31 * Shared testing code.
32 *
33 * @author Jose Fonseca <jfonseca@vmware.com>
34 */
35
36
37 #include "lp_bld_const.h"
38 #include "lp_test.h"
39
40
41 void
42 dump_type(FILE *fp,
43 union lp_type type)
44 {
45 fprintf(fp, "%s%u%sx%u",
46 type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
47 type.width,
48 type.norm ? "n" : "",
49 type.length);
50 }
51
52
53 double
54 read_elem(union lp_type type, const void *src, unsigned index)
55 {
56 double scale = lp_const_scale(type);
57 double value;
58 assert(index < type.length);
59 if (type.floating) {
60 switch(type.width) {
61 case 32:
62 value = *((const float *)src + index);
63 break;
64 case 64:
65 value = *((const double *)src + index);
66 break;
67 default:
68 assert(0);
69 return 0.0;
70 }
71 }
72 else {
73 if(type.sign) {
74 switch(type.width) {
75 case 8:
76 value = *((const int8_t *)src + index);
77 break;
78 case 16:
79 value = *((const int16_t *)src + index);
80 break;
81 case 32:
82 value = *((const int32_t *)src + index);
83 break;
84 case 64:
85 value = *((const int64_t *)src + index);
86 break;
87 default:
88 assert(0);
89 return 0.0;
90 }
91 }
92 else {
93 switch(type.width) {
94 case 8:
95 value = *((const uint8_t *)src + index);
96 break;
97 case 16:
98 value = *((const uint16_t *)src + index);
99 break;
100 case 32:
101 value = *((const uint32_t *)src + index);
102 break;
103 case 64:
104 value = *((const uint64_t *)src + index);
105 break;
106 default:
107 assert(0);
108 return 0.0;
109 }
110 }
111 }
112 return value/scale;
113 }
114
115
116 void
117 write_elem(union lp_type type, void *dst, unsigned index, double src)
118 {
119 double scale = lp_const_scale(type);
120 double value = scale*src;
121 assert(index < type.length);
122 if (type.floating) {
123 switch(type.width) {
124 case 32:
125 *((float *)dst + index) = (float)(value);
126 break;
127 case 64:
128 *((double *)dst + index) = value;
129 break;
130 default:
131 assert(0);
132 }
133 }
134 else {
135 if(type.sign) {
136 switch(type.width) {
137 case 8:
138 *((int8_t *)dst + index) = (int8_t)round(value);
139 break;
140 case 16:
141 *((int16_t *)dst + index) = (int16_t)round(value);
142 break;
143 case 32:
144 *((int32_t *)dst + index) = (int32_t)round(value);
145 break;
146 case 64:
147 *((int64_t *)dst + index) = (int32_t)round(value);
148 break;
149 default:
150 assert(0);
151 }
152 }
153 else {
154 switch(type.width) {
155 case 8:
156 *((uint8_t *)dst + index) = (uint8_t)round(value);
157 break;
158 case 16:
159 *((uint16_t *)dst + index) = (uint16_t)round(value);
160 break;
161 case 32:
162 *((uint32_t *)dst + index) = (uint32_t)round(value);
163 break;
164 case 64:
165 *((uint64_t *)dst + index) = (uint64_t)round(value);
166 break;
167 default:
168 assert(0);
169 }
170 }
171 }
172 }
173
174
175 void
176 random_elem(union lp_type type, void *dst, unsigned index)
177 {
178 assert(index < type.length);
179 if (type.floating) {
180 double value = (double)random()/(double)RAND_MAX;
181 if(!type.norm) {
182 value += (double)random();
183 if(random() & 1)
184 value = -value;
185 }
186 switch(type.width) {
187 case 32:
188 *((float *)dst + index) = (float)value;
189 break;
190 case 64:
191 *((double *)dst + index) = value;
192 break;
193 default:
194 assert(0);
195 }
196 }
197 else {
198 switch(type.width) {
199 case 8:
200 *((uint8_t *)dst + index) = (uint8_t)random();
201 break;
202 case 16:
203 *((uint16_t *)dst + index) = (uint16_t)random();
204 break;
205 case 32:
206 *((uint32_t *)dst + index) = (uint32_t)random();
207 break;
208 case 64:
209 *((uint64_t *)dst + index) = (uint64_t)random();
210 break;
211 default:
212 assert(0);
213 }
214 }
215 }
216
217
218 void
219 read_vec(union lp_type type, const void *src, double *dst)
220 {
221 unsigned i;
222 for (i = 0; i < type.length; ++i)
223 dst[i] = read_elem(type, src, i);
224 }
225
226
227 void
228 write_vec(union lp_type type, void *dst, const double *src)
229 {
230 unsigned i;
231 for (i = 0; i < type.length; ++i)
232 write_elem(type, dst, i, src[i]);
233 }
234
235
236 float
237 random_float(void)
238 {
239 return (float)((double)random()/(double)RAND_MAX);
240 }
241
242
243 void
244 random_vec(union lp_type type, void *dst)
245 {
246 unsigned i;
247 for (i = 0; i < type.length; ++i)
248 random_elem(type, dst, i);
249 }
250
251
252 boolean
253 compare_vec(union lp_type type, const void *res, const void *ref)
254 {
255 double eps;
256 unsigned i;
257
258 if (type.floating) {
259 switch(type.width) {
260 case 32:
261 eps = FLT_EPSILON;
262 break;
263 case 64:
264 eps = DBL_EPSILON;
265 break;
266 default:
267 assert(0);
268 eps = 0.0;
269 break;
270 }
271 }
272 else {
273 double scale = lp_const_scale(type);
274 eps = 1.0/scale;
275 }
276
277 for (i = 0; i < type.length; ++i) {
278 double res_elem = read_elem(type, res, i);
279 double ref_elem = read_elem(type, ref, i);
280 double delta = fabs(res_elem - ref_elem);
281 if(delta >= 2.0*eps)
282 return FALSE;
283 }
284
285 return TRUE;
286 }
287
288
289 void
290 dump_vec(FILE *fp, union lp_type type, const void *src)
291 {
292 unsigned i;
293 for (i = 0; i < type.length; ++i) {
294 if(i)
295 fprintf(fp, " ");
296 if (type.floating) {
297 double value;
298 switch(type.width) {
299 case 32:
300 value = *((const float *)src + i);
301 break;
302 case 64:
303 value = *((const double *)src + i);
304 break;
305 default:
306 assert(0);
307 value = 0.0;
308 }
309 fprintf(fp, "%f", value);
310 }
311 else {
312 if(type.sign) {
313 long long value;
314 const char *format;
315 switch(type.width) {
316 case 8:
317 value = *((const int8_t *)src + i);
318 format = "%3lli";
319 break;
320 case 16:
321 value = *((const int16_t *)src + i);
322 format = "%5lli";
323 break;
324 case 32:
325 value = *((const int32_t *)src + i);
326 format = "%10lli";
327 break;
328 case 64:
329 value = *((const int64_t *)src + i);
330 format = "%20lli";
331 break;
332 default:
333 assert(0);
334 value = 0.0;
335 format = "?";
336 }
337 fprintf(fp, format, value);
338 }
339 else {
340 unsigned long long value;
341 const char *format;
342 switch(type.width) {
343 case 8:
344 value = *((const uint8_t *)src + i);
345 format = "%4llu";
346 break;
347 case 16:
348 value = *((const uint16_t *)src + i);
349 format = "%6llu";
350 break;
351 case 32:
352 value = *((const uint32_t *)src + i);
353 format = "%11llu";
354 break;
355 case 64:
356 value = *((const uint64_t *)src + i);
357 format = "%21llu";
358 break;
359 default:
360 assert(0);
361 value = 0.0;
362 format = "?";
363 }
364 fprintf(fp, format, value);
365 }
366 }
367 }
368 }
369
370
371 int main(int argc, char **argv)
372 {
373 unsigned verbose = 0;
374 FILE *fp = NULL;
375 unsigned long n = 1000;
376 unsigned i;
377 boolean success;
378
379 for(i = 1; i < argc; ++i) {
380 if(strcmp(argv[i], "-v") == 0)
381 ++verbose;
382 else if(strcmp(argv[i], "-o") == 0)
383 fp = fopen(argv[++i], "wt");
384 else
385 n = atoi(argv[i]);
386 }
387
388 if(fp) {
389 /* Warm up the caches */
390 test_some(0, NULL, 100);
391
392 write_tsv_header(fp);
393 }
394
395 if(n)
396 success = test_some(verbose, fp, n);
397 else
398 success = test_all(verbose, fp);
399
400 if(fp)
401 fclose(fp);
402
403 return success ? 0 : 1;
404 }