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