Test behaviour of color write enable with colorWriteMask
[platform/upstream/VK-GL-CTS.git] / framework / delibs / debase / deMath.h
1 #ifndef _DEMATH_H
2 #define _DEMATH_H
3 /*-------------------------------------------------------------------------
4  * drawElements Base Portability Library
5  * -------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Basic mathematical operations.
24  *//*--------------------------------------------------------------------*/
25
26 #include "deDefs.h"
27
28 #include <math.h>
29 #include <float.h>
30
31 DE_BEGIN_EXTERN_C
32
33 /* Mathematical constants. */
34
35 #define DE_PI                   3.14159265358979324f    /*!< Pi.                                        */
36 #define DE_LOG_2                0.69314718056f                  /*!< log_e(2.0)                         */
37 #define DE_INV_LOG_2    1.44269504089f                  /*!< 1.0 / log_e(2.0)           */
38 #define DE_E                    2.71828182845904523536f /*!< e.                                         */
39 #define DE_LOG2_E               1.44269504088896340736f /*!< log_2(e).                          */
40 #define DE_INV_LOG2_E   0.69314718055994530942f /*!< 1.0 / log_2(e).            */
41
42 #define DE_PI_DOUBLE    3.14159265358979323846  /*!< Pi as a double.            */
43 #define DE_PI_16BIT             0x4248                                  /*!< Pi. as a float16b          */
44
45 /* Rounding mode control. */
46
47 typedef enum deRoundingMode_e
48 {
49         DE_ROUNDINGMODE_TO_NEAREST_EVEN = 0,
50         DE_ROUNDINGMODE_TO_ZERO,
51         DE_ROUNDINGMODE_TO_POSITIVE_INF,
52         DE_ROUNDINGMODE_TO_NEGATIVE_INF,
53
54         DE_ROUNDINGMODE_LAST
55 } deRoundingMode;
56
57 deRoundingMode          deGetRoundingMode       (void);
58 deBool                          deSetRoundingMode       (deRoundingMode mode);
59
60 void                            deMath_selfTest         (void);
61
62 /* Float properties */
63
64 /* \note The NaN test probably won't work with -ffast-math */
65
66 DE_INLINE int           deFloatIsInf            (float x)               { return (x > FLT_MAX) - (x < -FLT_MAX); }
67 DE_INLINE deBool        deFloatIsNaN            (float x)               { return (x != x); }
68
69 DE_INLINE int           deIsInf                         (double x)              { return (x > DBL_MAX) - (x < -DBL_MAX); }
70 DE_INLINE deBool        deIsNaN                         (double x)              { return (x != x); }
71
72 /* Basic utilities. */
73
74 DE_INLINE float         deFloatAbs                      (float x)                                               { return (x >= 0.0f) ? x : -x; }
75 DE_INLINE float         deFloatMin                      (float a, float b)                              { return (a <= b) ? a : b; }
76 DE_INLINE float         deFloatMax                      (float a, float b)                              { return (a >= b) ? a : b; }
77 DE_INLINE float         deFloatClamp            (float x, float mn, float mx)   { return (x <= mn) ? mn : ((x >= mx) ? mx : x); }
78
79 DE_INLINE double        deAbs                           (double x)                                                      { return (x >= 0.0) ? x : -x; }
80 DE_INLINE double        deMin                           (double a, double b)                            { return (a <= b) ? a : b; }
81 DE_INLINE double        deMax                           (double a, double b)                            { return (a >= b) ? a : b; }
82 DE_INLINE double        deClamp                         (double x, double mn, double mx)        { return (x <= mn) ? mn : ((x >= mx) ? mx : x); }
83
84 /* Utility functions. */
85
86 DE_INLINE float         deFloatSign                     (float a)                                       { return (a == 0.0f) ? 0.0f : ((a > 0.0f) ? +1.0f : -1.0f); }
87 DE_INLINE int           deFloatIntSign          (float a)                                       { return (a == 0.0f) ? 0 : ((a > 0.0f) ? +1 : -1); }
88 DE_INLINE float         deFloatFloor            (float a)                                       { return (float)floor(a); }
89 DE_INLINE float         deFloatCeil                     (float a)                                       { return (float)ceil(a); }
90 DE_INLINE float         deFloatRound            (float a)                                       { return deFloatFloor(a + 0.5f); }
91 DE_INLINE float         deFloatFrac                     (float a)                                       { return a - deFloatFloor(a); }
92 DE_INLINE float         deFloatMod                      (float a, float b)                      { return (float)fmod(a, b); }
93 DE_INLINE float         deFloatModf                     (float x, float* i)                     { double j = 0; double ret = modf(x, &j); *i = (float)j; return (float)ret; }
94 DE_INLINE float         deFloatMadd                     (float a, float b, float c)     { return (a*b) + c; }
95 DE_INLINE float         deFloatTrunc            (float a)                                       { return deFloatSign(a) * deFloatFloor(deFloatAbs(a)); }
96 DE_INLINE float         deFloatLdExp            (float a, int exponent)         { return (float)ldexp(a, exponent); }
97 DE_INLINE float         deFloatFrExp            (float x, int* exponent)        { return (float)frexp(x, exponent); }
98 float                           deFloatFractExp         (float x, int* exponent);
99
100 DE_INLINE double        deSign                          (double x)                                              { return deIsNaN(x) ? x : (double)((x > 0.0) - (x < 0.0)); }
101 DE_INLINE int           deIntSign                       (double x)                                              { return (x > 0.0) - (x < 0.0); }
102 DE_INLINE double        deFloor                         (double a)                                              { return floor(a); }
103 DE_INLINE double        deCeil                          (double a)                                              { return ceil(a); }
104 DE_INLINE double        deRound                         (double a)                                              { return floor(a + 0.5); }
105 DE_INLINE double        deFrac                          (double a)                                              { return a - deFloor(a); }
106 DE_INLINE double        deMod                           (double a, double b)                    { return fmod(a, b); }
107 DE_INLINE double        deModf                          (double x, double* i)                   { return modf(x, i); }
108 DE_INLINE double        deMadd                          (double a, double b, double c)  { return (a*b) + c; }
109 DE_INLINE double        deTrunc                         (double a)                                              { return deSign(a) * floor(fabs(a)); }
110 DE_INLINE double        deLdExp                         (double a, int exponent)                { return ldexp(a, exponent); }
111 double                          deRoundEven                     (double a);
112 DE_INLINE double        deFrExp                         (double x, int* exponent)               { return frexp(x, exponent); }
113 /* Like frexp, except the returned fraction is in range [1.0, 2.0) */
114 double                          deFractExp                      (double x, int* exponent);
115
116 /* Exponential functions. */
117
118 DE_INLINE float         deFloatPow                      (float a, float b)                      { return (float)pow(a, b); }
119 DE_INLINE float         deFloatExp                      (float a)                                       { return (float)exp(a); }
120 DE_INLINE float         deFloatLog                      (float a)                                       { return (float)log(a); }
121 DE_INLINE float         deFloatExp2                     (float a)                                       { return (float)exp(a * DE_LOG_2); }
122 DE_INLINE float         deFloatLog2                     (float a)                                       { return (float)log(a) * DE_INV_LOG_2; }
123 DE_INLINE float         deFloatSqrt                     (float a)                                       { return (float)sqrt(a); }
124 DE_INLINE float         deFloatRcp                      (float a)                                       { return (1.0f / a); }
125 DE_INLINE float         deFloatRsq                      (float a)                                       { float s = (float)sqrt(a); return (s == 0.0f) ? 0.0f : (1.0f / s); }
126
127 DE_INLINE double        dePow                           (double a, double b)            { return pow(a, b); }
128 DE_INLINE double        deExp                           (double a)                                      { return exp(a); }
129 DE_INLINE double        deLog                           (double a)                                      { return log(a); }
130 DE_INLINE double        deExp2                          (double a)                                      { return exp(a * log(2.0)); }
131 DE_INLINE double        deLog2                          (double a)                                      { return log(a) / log(2.0); }
132 DE_INLINE double        deSqrt                          (double a)                                      { return sqrt(a); }
133 DE_INLINE double        deCbrt                          (double a)                                      { return deSign(a) * dePow(deAbs(a), 1.0 / 3.0); }
134
135 /* Geometric functions. */
136
137 DE_INLINE float         deFloatRadians          (float a)                                       { return a * (DE_PI / 180.0f); }
138 DE_INLINE float         deFloatDegrees          (float a)                                       { return a * (180.0f / DE_PI); }
139 DE_INLINE float         deFloatSin                      (float a)                                       { return (float)sin(a); }
140 DE_INLINE float         deFloatCos                      (float a)                                       { return (float)cos(a); }
141 DE_INLINE float         deFloatTan                      (float a)                                       { return (float)tan(a); }
142 DE_INLINE float         deFloatAsin                     (float a)                                       { return (float)asin(a); }
143 DE_INLINE float         deFloatAcos                     (float a)                                       { return (float)acos(a); }
144 DE_INLINE float         deFloatAtan2            (float y, float x)                      { return (float)atan2(y, x); }
145 DE_INLINE float         deFloatAtanOver         (float yOverX)                          { return (float)atan(yOverX); }
146 DE_INLINE float         deFloatSinh                     (float a)                                       { return (float)sinh(a); }
147 DE_INLINE float         deFloatCosh                     (float a)                                       { return (float)cosh(a); }
148 DE_INLINE float         deFloatTanh                     (float a)                                       { return (float)tanh(a); }
149 DE_INLINE float         deFloatAsinh            (float a)                                       { return deFloatLog(a + deFloatSqrt(a*a + 1)); }
150 DE_INLINE float         deFloatAcosh            (float a)                                       { return deFloatLog(a + deFloatSqrt(a*a - 1)); }
151 DE_INLINE float         deFloatAtanh            (float a)                                       { return 0.5f*deFloatLog((1.0f+a)/(1.0f-a)); }
152
153 DE_INLINE double        deSin                   (double a)                                              { return sin(a); }
154 DE_INLINE double        deCos                   (double a)                                              { return cos(a); }
155 DE_INLINE double        deTan                   (double a)                                              { return tan(a); }
156 DE_INLINE double        deAsin                  (double a)                                              { return asin(a); }
157 DE_INLINE double        deAcos                  (double a)                                              { return acos(a); }
158 DE_INLINE double        deAtan2                 (double y, double x)                    { return atan2(y, x); }
159 DE_INLINE double        deAtanOver              (double yOverX)                                 { return atan(yOverX); }
160 DE_INLINE double        deSinh                  (double a)                                              { return sinh(a); }
161 DE_INLINE double        deCosh                  (double a)                                              { return cosh(a); }
162 DE_INLINE double        deTanh                  (double a)                                              { return tanh(a); }
163 DE_INLINE double        deAsinh                 (double a)                                              { return deLog(a + deSqrt(a*a + 1)); }
164 DE_INLINE double        deAcosh                 (double a)                                              { return deLog(a + deSqrt(a*a - 1)); }
165 DE_INLINE double        deAtanh                 (double a)                                              { return 0.5*deLog((1.0+a)/(1.0-a)); }
166
167 /* Interpolation. */
168
169 DE_INLINE float         deFloatMix                      (float a, float b, float t)     { return a*(1.0f-t) + b*t; }
170 DE_INLINE float         deFloatStep                     (float limit, float val)        { return (val < limit) ? 0.0f : 1.0f; }
171 DE_INLINE float         deFloatSmoothStep       (float e0, float e1, float v)
172 {
173         float t;
174         if (v <= e0) return 0.0f;
175         if (v >= e1) return 1.0f;
176         t = (v - e0) / (e1 - e0);
177         return t * t * (3.0f - 2.0f * t);
178 }
179
180 DE_INLINE double        deMix                           (double a, double b, double t)  { return a*(1.0-t) + b*t; }
181 DE_INLINE double        deStep                          (double limit, double val)              { return (val < limit) ? 0.0 : 1.0; }
182
183 /* Comparison functions. */
184
185 DE_INLINE deBool        deFloatCmpEQ            (float a, float b)                      { return (a == b); }
186 DE_INLINE deBool        deFloatCmpNE            (float a, float b)                      { return (a != b); }
187 DE_INLINE deBool        deFloatCmpLT            (float a, float b)                      { return (a < b);  }
188 DE_INLINE deBool        deFloatCmpLE            (float a, float b)                      { return (a <= b); }
189 DE_INLINE deBool        deFloatCmpGT            (float a, float b)                      { return (a > b);  }
190 DE_INLINE deBool        deFloatCmpGE            (float a, float b)                      { return (a >= b); }
191
192 /* Convert int to float. If the value cannot be represented exactly in native single precision format, return
193  * either the nearest lower or the nearest higher representable value, chosen in an implementation-defined manner.
194  *
195  * \note Choosing either nearest lower or nearest higher means that implementation could for example consistently
196  *       choose the lower value, i.e. this function does not round towards nearest.
197  * \note Value returned is in native single precision format. For example with x86 extended precision, the value
198  *       returned might not be representable in IEEE single precision float.
199  */
200 DE_INLINE float         deInt32ToFloat                          (deInt32 x)                                     { return (float)x; }
201
202 /* Convert to float. If the value cannot be represented exactly in IEEE single precision floating point format,
203  * return the nearest lower (round towards negative inf). */
204 float                           deInt32ToFloatRoundToNegInf     (deInt32 x);
205
206 /* Convert to float. If the value cannot be represented exactly IEEE single precision floating point format,
207  * return the nearest higher (round towards positive inf). */
208 float                           deInt32ToFloatRoundToPosInf     (deInt32 x);
209
210 /* Conversion to integer. */
211
212 DE_INLINE deInt32       deChopFloatToInt32              (float x)                               { return (deInt32)x; }
213 DE_INLINE deInt32       deFloorFloatToInt32             (float x)                               { return (deInt32)(deFloatFloor(x)); }
214 DE_INLINE deInt32       deCeilFloatToInt32              (float x)                               { return (deInt32)(deFloatCeil(x)); }
215
216 DE_INLINE deInt32       deChopToInt32                   (double x)                              { return (deInt32)x; }
217 DE_INLINE deInt32       deFloorToInt32                  (double x)                              { return (deInt32)(deFloor(x)); }
218 DE_INLINE deInt32       deCeilToInt32                   (double x)                              { return (deInt32)(deCeil(x)); }
219
220 /* Arithmetic round */
221 DE_INLINE deInt16       deRoundFloatToInt16             (float x)                               { if(x >= 0.0f) return (deInt16)(x + 0.5f); else return (deInt16)(x - 0.5f); }
222 DE_INLINE deInt32       deRoundFloatToInt32             (float x)                               { if(x >= 0.0f) return (deInt32)(x + 0.5f); else return (deInt32)(x - 0.5f); }
223 DE_INLINE deInt64       deRoundFloatToInt64             (float x)                               { if(x >= 0.0f) return (deInt64)(x + 0.5f); else return (deInt64)(x - 0.5f); }
224
225 DE_INLINE deInt16       deRoundToInt16                  (double x)                              { if(x >= 0.0) return (deInt16)(x + 0.5); else return (deInt16)(x - 0.5); }
226 DE_INLINE deInt32       deRoundToInt32                  (double x)                              { if(x >= 0.0) return (deInt32)(x + 0.5); else return (deInt32)(x - 0.5); }
227 DE_INLINE deInt64       deRoundToInt64                  (double x)                              { if(x >= 0.0) return (deInt64)(x + 0.5); else return (deInt64)(x - 0.5); }
228
229 DE_END_EXTERN_C
230
231 #endif /* _DEMATH_H */