1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "shared.rsh"
18
19// Testing math library
20
21volatile float f1;
22volatile float2 f2;
23volatile float3 f3;
24volatile float4 f4;
25
26volatile int i1;
27volatile int2 i2;
28volatile int3 i3;
29volatile int4 i4;
30
31volatile uint ui1;
32volatile uint2 ui2;
33volatile uint3 ui3;
34volatile uint4 ui4;
35
36volatile short s1;
37volatile short2 s2;
38volatile short3 s3;
39volatile short4 s4;
40
41volatile ushort us1;
42volatile ushort2 us2;
43volatile ushort3 us3;
44volatile ushort4 us4;
45
46volatile char c1;
47volatile char2 c2;
48volatile char3 c3;
49volatile char4 c4;
50
51volatile uchar uc1;
52volatile uchar2 uc2;
53volatile uchar3 uc3;
54volatile uchar4 uc4;
55
56#define DECL_INT(prefix)            \
57volatile char prefix##_c_1 = 1;     \
58volatile char2 prefix##_c_2 = 1;    \
59volatile char3 prefix##_c_3 = 1;    \
60volatile char4 prefix##_c_4 = 1;    \
61volatile uchar prefix##_uc_1 = 1;   \
62volatile uchar2 prefix##_uc_2 = 1;  \
63volatile uchar3 prefix##_uc_3 = 1;  \
64volatile uchar4 prefix##_uc_4 = 1;  \
65volatile short prefix##_s_1 = 1;    \
66volatile short2 prefix##_s_2 = 1;   \
67volatile short3 prefix##_s_3 = 1;   \
68volatile short4 prefix##_s_4 = 1;   \
69volatile ushort prefix##_us_1 = 1;  \
70volatile ushort2 prefix##_us_2 = 1; \
71volatile ushort3 prefix##_us_3 = 1; \
72volatile ushort4 prefix##_us_4 = 1; \
73volatile int prefix##_i_1 = 1;      \
74volatile int2 prefix##_i_2 = 1;     \
75volatile int3 prefix##_i_3 = 1;     \
76volatile int4 prefix##_i_4 = 1;     \
77volatile uint prefix##_ui_1 = 1;    \
78volatile uint2 prefix##_ui_2 = 1;   \
79volatile uint3 prefix##_ui_3 = 1;   \
80volatile uint4 prefix##_ui_4 = 1;   \
81volatile long prefix##_l_1 = 1;     \
82volatile ulong prefix##_ul_1 = 1;
83
84DECL_INT(res)
85DECL_INT(src1)
86DECL_INT(src2)
87
88#define TEST_INT_OP_TYPE(op, type)                      \
89rsDebug("Testing " #op " for " #type "1", i++);         \
90res_##type##_1 = src1_##type##_1 op src2_##type##_1;    \
91rsDebug("Testing " #op " for " #type "2", i++);         \
92res_##type##_2 = src1_##type##_2 op src2_##type##_2;    \
93rsDebug("Testing " #op " for " #type "3", i++);         \
94res_##type##_3 = src1_##type##_3 op src2_##type##_3;    \
95rsDebug("Testing " #op " for " #type "4", i++);         \
96res_##type##_4 = src1_##type##_4 op src2_##type##_4;
97
98#define TEST_INT_OP(op)                     \
99TEST_INT_OP_TYPE(op, c)                     \
100TEST_INT_OP_TYPE(op, uc)                    \
101TEST_INT_OP_TYPE(op, s)                     \
102TEST_INT_OP_TYPE(op, us)                    \
103TEST_INT_OP_TYPE(op, i)                     \
104TEST_INT_OP_TYPE(op, ui)                    \
105rsDebug("Testing " #op " for l1", i++);     \
106res_l_1 = src1_l_1 op src2_l_1;             \
107rsDebug("Testing " #op " for ul1", i++);    \
108res_ul_1 = src1_ul_1 op src2_ul_1;
109
110#define TEST_XN_FUNC_YN(typeout, fnc, typein)   \
111    res_##typeout##_1 = fnc(src1_##typein##_1); \
112    res_##typeout##_2 = fnc(src1_##typein##_2); \
113    res_##typeout##_3 = fnc(src1_##typein##_3); \
114    res_##typeout##_4 = fnc(src1_##typein##_4);
115
116#define TEST_XN_FUNC_XN_XN(type, fnc)                       \
117    res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1); \
118    res_##type##_2 = fnc(src1_##type##_2, src2_##type##_2); \
119    res_##type##_3 = fnc(src1_##type##_3, src2_##type##_3); \
120    res_##type##_4 = fnc(src1_##type##_4, src2_##type##_4);
121
122#define TEST_X_FUNC_X_X_X(type, fnc)    \
123    res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1, src2_##type##_1);
124
125#define TEST_IN_FUNC_IN(fnc)        \
126    rsDebug("Testing " #fnc, 0);    \
127    TEST_XN_FUNC_YN(uc, fnc, uc)    \
128    TEST_XN_FUNC_YN(c, fnc, c)      \
129    TEST_XN_FUNC_YN(us, fnc, us)    \
130    TEST_XN_FUNC_YN(s, fnc, s)      \
131    TEST_XN_FUNC_YN(ui, fnc, ui)    \
132    TEST_XN_FUNC_YN(i, fnc, i)
133
134#define TEST_UIN_FUNC_IN(fnc)       \
135    rsDebug("Testing " #fnc, 0);    \
136    TEST_XN_FUNC_YN(uc, fnc, c)     \
137    TEST_XN_FUNC_YN(us, fnc, s)     \
138    TEST_XN_FUNC_YN(ui, fnc, i)     \
139
140#define TEST_IN_FUNC_IN_IN(fnc)     \
141    rsDebug("Testing " #fnc, 0);    \
142    TEST_XN_FUNC_XN_XN(uc, fnc)     \
143    TEST_XN_FUNC_XN_XN(c, fnc)      \
144    TEST_XN_FUNC_XN_XN(us, fnc)     \
145    TEST_XN_FUNC_XN_XN(s, fnc)      \
146    TEST_XN_FUNC_XN_XN(ui, fnc)     \
147    TEST_XN_FUNC_XN_XN(i, fnc)
148
149#define TEST_I_FUNC_I_I_I(fnc)      \
150    rsDebug("Testing " #fnc, 0);    \
151    TEST_X_FUNC_X_X_X(uc, fnc)      \
152    TEST_X_FUNC_X_X_X(c, fnc)       \
153    TEST_X_FUNC_X_X_X(us, fnc)      \
154    TEST_X_FUNC_X_X_X(s, fnc)       \
155    TEST_X_FUNC_X_X_X(ui, fnc)      \
156    TEST_X_FUNC_X_X_X(i, fnc)
157
158#define TEST_FN_FUNC_FN(fnc)        \
159    rsDebug("Testing " #fnc, 0);    \
160    f1 = fnc(f1);                   \
161    f2 = fnc(f2);                   \
162    f3 = fnc(f3);                   \
163    f4 = fnc(f4);
164
165#define TEST_FN_FUNC_FN_PFN(fnc)    \
166    rsDebug("Testing " #fnc, 0);    \
167    f1 = fnc(f1, (float*) &f1);     \
168    f2 = fnc(f2, (float2*) &f2);    \
169    f3 = fnc(f3, (float3*) &f3);    \
170    f4 = fnc(f4, (float4*) &f4);
171
172#define TEST_FN_FUNC_FN_FN(fnc)     \
173    rsDebug("Testing " #fnc, 0);    \
174    f1 = fnc(f1, f1);               \
175    f2 = fnc(f2, f2);               \
176    f3 = fnc(f3, f3);               \
177    f4 = fnc(f4, f4);
178
179#define TEST_F34_FUNC_F34_F34(fnc)  \
180    rsDebug("Testing " #fnc, 0);    \
181    f3 = fnc(f3, f3);               \
182    f4 = fnc(f4, f4);
183
184#define TEST_FN_FUNC_FN_F(fnc)      \
185    rsDebug("Testing " #fnc, 0);    \
186    f1 = fnc(f1, f1);               \
187    f2 = fnc(f2, f1);               \
188    f3 = fnc(f3, f1);               \
189    f4 = fnc(f4, f1);
190
191#define TEST_FN_FUNC_F_FN(fnc)      \
192    rsDebug("Testing " #fnc, 0);    \
193    f1 = fnc(f1, f1);               \
194    f2 = fnc(f1, f2);               \
195    f3 = fnc(f1, f3);               \
196    f4 = fnc(f1, f4);
197
198#define TEST_F_FUNC_FN(fnc)         \
199    rsDebug("Testing " #fnc, 0);    \
200    f1 = fnc(f1);                   \
201    f1 = fnc(f2);                   \
202    f1 = fnc(f3);                   \
203    f1 = fnc(f4);
204
205#define TEST_F_FUNC_FN_FN(fnc)      \
206    rsDebug("Testing " #fnc, 0);    \
207    f1 = fnc(f1, f1);               \
208    f1 = fnc(f2, f2);               \
209    f1 = fnc(f3, f3);               \
210    f1 = fnc(f4, f4);
211
212#define TEST_FN_FUNC_FN_IN(fnc)     \
213    rsDebug("Testing " #fnc, 0);    \
214    f1 = fnc(f1, i1);               \
215    f2 = fnc(f2, i2);               \
216    f3 = fnc(f3, i3);               \
217    f4 = fnc(f4, i4);
218
219#define TEST_FN_FUNC_FN_I(fnc)      \
220    rsDebug("Testing " #fnc, 0);    \
221    f1 = fnc(f1, i1);               \
222    f2 = fnc(f2, i1);               \
223    f3 = fnc(f3, i1);               \
224    f4 = fnc(f4, i1);
225
226#define TEST_FN_FUNC_FN_FN_FN(fnc)  \
227    rsDebug("Testing " #fnc, 0);    \
228    f1 = fnc(f1, f1, f1);           \
229    f2 = fnc(f2, f2, f2);           \
230    f3 = fnc(f3, f3, f3);           \
231    f4 = fnc(f4, f4, f4);
232
233#define TEST_FN_FUNC_FN_FN_F(fnc)   \
234    rsDebug("Testing " #fnc, 0);    \
235    f1 = fnc(f1, f1, f1);           \
236    f2 = fnc(f2, f1, f1);           \
237    f3 = fnc(f3, f1, f1);           \
238    f4 = fnc(f4, f1, f1);
239
240#define TEST_FN_FUNC_FN_PIN(fnc)    \
241    rsDebug("Testing " #fnc, 0);    \
242    f1 = fnc(f1, (int*) &i1);       \
243    f2 = fnc(f2, (int2*) &i2);      \
244    f3 = fnc(f3, (int3*) &i3);      \
245    f4 = fnc(f4, (int4*) &i4);
246
247#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
248    rsDebug("Testing " #fnc, 0);    \
249    f1 = fnc(f1, f1, (int*) &i1);   \
250    f2 = fnc(f2, f2, (int2*) &i2);  \
251    f3 = fnc(f3, f3, (int3*) &i3);  \
252    f4 = fnc(f4, f4, (int4*) &i4);
253
254#define TEST_IN_FUNC_FN(fnc)        \
255    rsDebug("Testing " #fnc, 0);    \
256    i1 = fnc(f1);                   \
257    i2 = fnc(f2);                   \
258    i3 = fnc(f3);                   \
259    i4 = fnc(f4);
260
261static bool test_fp_math(uint32_t index) {
262    bool failed = false;
263    start();
264
265    TEST_FN_FUNC_FN(acos);
266    TEST_FN_FUNC_FN(acosh);
267    TEST_FN_FUNC_FN(acospi);
268    TEST_FN_FUNC_FN(asin);
269    TEST_FN_FUNC_FN(asinh);
270    TEST_FN_FUNC_FN(asinpi);
271    TEST_FN_FUNC_FN(atan);
272    TEST_FN_FUNC_FN_FN(atan2);
273    TEST_FN_FUNC_FN(atanh);
274    TEST_FN_FUNC_FN(atanpi);
275    TEST_FN_FUNC_FN_FN(atan2pi);
276    TEST_FN_FUNC_FN(cbrt);
277    TEST_FN_FUNC_FN(ceil);
278    TEST_FN_FUNC_FN_FN_FN(clamp);
279    TEST_FN_FUNC_FN_FN_F(clamp);
280    TEST_FN_FUNC_FN_FN(copysign);
281    TEST_FN_FUNC_FN(cos);
282    TEST_FN_FUNC_FN(cosh);
283    TEST_FN_FUNC_FN(cospi);
284    TEST_F34_FUNC_F34_F34(cross);
285    TEST_FN_FUNC_FN(degrees);
286    TEST_F_FUNC_FN_FN(distance);
287    TEST_F_FUNC_FN_FN(dot);
288    TEST_FN_FUNC_FN(erfc);
289    TEST_FN_FUNC_FN(erf);
290    TEST_FN_FUNC_FN(exp);
291    TEST_FN_FUNC_FN(exp2);
292    TEST_FN_FUNC_FN(exp10);
293    TEST_FN_FUNC_FN(expm1);
294    TEST_FN_FUNC_FN(fabs);
295    TEST_FN_FUNC_FN_FN(fdim);
296    TEST_FN_FUNC_FN(floor);
297    TEST_FN_FUNC_FN_FN_FN(fma);
298    TEST_FN_FUNC_FN_FN(fmax);
299    TEST_FN_FUNC_FN_F(fmax);
300    TEST_FN_FUNC_FN_FN(fmin);
301    TEST_FN_FUNC_FN_F(fmin);
302    TEST_FN_FUNC_FN_FN(fmod);
303    TEST_FN_FUNC_FN_PFN(fract);
304    TEST_FN_FUNC_FN_PIN(frexp);
305    TEST_FN_FUNC_FN_FN(hypot);
306    TEST_IN_FUNC_FN(ilogb);
307    TEST_FN_FUNC_FN_IN(ldexp);
308    TEST_FN_FUNC_FN_I(ldexp);
309    TEST_F_FUNC_FN(length);
310    TEST_FN_FUNC_FN(lgamma);
311    TEST_FN_FUNC_FN_PIN(lgamma);
312    TEST_FN_FUNC_FN(log);
313    TEST_FN_FUNC_FN(log2);
314    TEST_FN_FUNC_FN(log10);
315    TEST_FN_FUNC_FN(log1p);
316    TEST_FN_FUNC_FN(logb);
317    TEST_FN_FUNC_FN_FN_FN(mad);
318    TEST_FN_FUNC_FN_FN(max);
319    TEST_FN_FUNC_FN_F(max);
320    TEST_FN_FUNC_FN_FN(min);
321    TEST_FN_FUNC_FN_F(min);
322    TEST_FN_FUNC_FN_FN_FN(mix);
323    TEST_FN_FUNC_FN_FN_F(mix);
324    TEST_FN_FUNC_FN_PFN(modf);
325    // nan
326    TEST_FN_FUNC_FN_FN(nextafter);
327    TEST_FN_FUNC_FN(normalize);
328    TEST_FN_FUNC_FN_FN(pow);
329    TEST_FN_FUNC_FN_IN(pown);
330    TEST_FN_FUNC_FN_FN(powr);
331    TEST_FN_FUNC_FN(radians);
332    TEST_FN_FUNC_FN_FN(remainder);
333    TEST_FN_FUNC_FN_FN_PIN(remquo);
334    TEST_FN_FUNC_FN(rint);
335    TEST_FN_FUNC_FN_IN(rootn);
336    TEST_FN_FUNC_FN(round);
337    TEST_FN_FUNC_FN(rsqrt);
338    TEST_FN_FUNC_FN(sign);
339    TEST_FN_FUNC_FN(sin);
340    TEST_FN_FUNC_FN_PFN(sincos);
341    TEST_FN_FUNC_FN(sinh);
342    TEST_FN_FUNC_FN(sinpi);
343    TEST_FN_FUNC_FN(sqrt);
344    TEST_FN_FUNC_FN_FN(step);
345    TEST_FN_FUNC_FN_F(step);
346    TEST_FN_FUNC_F_FN(step);
347    TEST_FN_FUNC_FN(tan);
348    TEST_FN_FUNC_FN(tanh);
349    TEST_FN_FUNC_FN(tanpi);
350    TEST_FN_FUNC_FN(tgamma);
351    TEST_FN_FUNC_FN(trunc);
352
353    float time = end(index);
354
355    if (failed) {
356        rsDebug("test_fp_math FAILED", time);
357    }
358    else {
359        rsDebug("test_fp_math PASSED", time);
360    }
361
362    return failed;
363}
364
365static bool test_int_math(uint32_t index) {
366    bool failed = false;
367    start();
368
369    TEST_UIN_FUNC_IN(abs);
370    TEST_IN_FUNC_IN(clz);
371    TEST_IN_FUNC_IN_IN(min);
372    TEST_IN_FUNC_IN_IN(max);
373    TEST_I_FUNC_I_I_I(clamp);
374
375    float time = end(index);
376
377    if (failed) {
378        rsDebug("test_int_math FAILED", time);
379    }
380    else {
381        rsDebug("test_int_math PASSED", time);
382    }
383
384    return failed;
385}
386
387static bool test_basic_operators() {
388    bool failed = false;
389    int i = 0;
390
391    TEST_INT_OP(+);
392    TEST_INT_OP(-);
393    TEST_INT_OP(*);
394    TEST_INT_OP(/);
395    TEST_INT_OP(%);
396    TEST_INT_OP(<<);
397    TEST_INT_OP(>>);
398
399    if (failed) {
400        rsDebug("test_basic_operators FAILED", 0);
401    }
402    else {
403        rsDebug("test_basic_operators PASSED", 0);
404    }
405
406    return failed;
407}
408
409#define TEST_CVT(to, from, type)                        \
410rsDebug("Testing convert from " #from " to " #to, 0);   \
411to##1 = from##1;                                        \
412to##2 = convert_##type##2(from##2);                     \
413to##3 = convert_##type##3(from##3);                     \
414to##4 = convert_##type##4(from##4);
415
416#define TEST_CVT_MATRIX(to, type)   \
417TEST_CVT(to, c, type);              \
418TEST_CVT(to, uc, type);             \
419TEST_CVT(to, s, type);              \
420TEST_CVT(to, us, type);             \
421TEST_CVT(to, i, type);              \
422TEST_CVT(to, ui, type);             \
423TEST_CVT(to, f, type);              \
424
425static bool test_convert() {
426    bool failed = false;
427
428    TEST_CVT_MATRIX(c, char);
429    TEST_CVT_MATRIX(uc, uchar);
430    TEST_CVT_MATRIX(s, short);
431    TEST_CVT_MATRIX(us, ushort);
432    TEST_CVT_MATRIX(i, int);
433    TEST_CVT_MATRIX(ui, uint);
434    TEST_CVT_MATRIX(f, float);
435
436    if (failed) {
437        rsDebug("test_convert FAILED", 0);
438    }
439    else {
440        rsDebug("test_convert PASSED", 0);
441    }
442
443    return failed;
444}
445
446void math_test(uint32_t index, int test_num) {
447    bool failed = false;
448    failed |= test_convert();
449    failed |= test_fp_math(index);
450    failed |= test_int_math(index);
451    failed |= test_basic_operators();
452
453    if (failed) {
454        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
455    }
456    else {
457        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
458    }
459}
460