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