xref: /aosp_15_r20/external/deqp/framework/randomshaders/rsgBuiltinFunctions.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker #ifndef _RSGBUILTINFUNCTIONS_HPP
2*35238bceSAndroid Build Coastguard Worker #define _RSGBUILTINFUNCTIONS_HPP
3*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Random Shader Generator
5*35238bceSAndroid Build Coastguard Worker  * ----------------------------------------------------
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
8*35238bceSAndroid Build Coastguard Worker  *
9*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
10*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
11*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
14*35238bceSAndroid Build Coastguard Worker  *
15*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
16*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
17*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
19*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
20*35238bceSAndroid Build Coastguard Worker  *
21*35238bceSAndroid Build Coastguard Worker  *//*!
22*35238bceSAndroid Build Coastguard Worker  * \file
23*35238bceSAndroid Build Coastguard Worker  * \brief Built-in Functions.
24*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "rsgDefs.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "rsgExpression.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "rsgUtils.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker namespace rsg
32*35238bceSAndroid Build Coastguard Worker {
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker // Template for built-in functions with form "GenType func(GenType val)".
35*35238bceSAndroid Build Coastguard Worker template <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
36*35238bceSAndroid Build Coastguard Worker class UnaryBuiltinVecFunc : public Expression
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker public:
39*35238bceSAndroid Build Coastguard Worker     UnaryBuiltinVecFunc(GeneratorState &state, const char *function, ConstValueRangeAccess valueRange);
40*35238bceSAndroid Build Coastguard Worker     virtual ~UnaryBuiltinVecFunc(void);
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker     Expression *createNextChild(GeneratorState &state);
43*35238bceSAndroid Build Coastguard Worker     void tokenize(GeneratorState &state, TokenStream &str) const;
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker     void evaluate(ExecutionContext &execCtx);
getValue(void) const46*35238bceSAndroid Build Coastguard Worker     ExecConstValueAccess getValue(void) const
47*35238bceSAndroid Build Coastguard Worker     {
48*35238bceSAndroid Build Coastguard Worker         return m_value.getValue(m_inValueRange.getType());
49*35238bceSAndroid Build Coastguard Worker     }
50*35238bceSAndroid Build Coastguard Worker 
51*35238bceSAndroid Build Coastguard Worker     static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker private:
54*35238bceSAndroid Build Coastguard Worker     std::string m_function;
55*35238bceSAndroid Build Coastguard Worker     ValueRange m_inValueRange;
56*35238bceSAndroid Build Coastguard Worker     ExecValueStorage m_value;
57*35238bceSAndroid Build Coastguard Worker     Expression *m_child;
58*35238bceSAndroid Build Coastguard Worker };
59*35238bceSAndroid Build Coastguard Worker 
60*35238bceSAndroid Build Coastguard Worker template <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
UnaryBuiltinVecFunc(GeneratorState & state,const char * function,ConstValueRangeAccess valueRange)61*35238bceSAndroid Build Coastguard Worker UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::UnaryBuiltinVecFunc(
62*35238bceSAndroid Build Coastguard Worker     GeneratorState &state, const char *function, ConstValueRangeAccess valueRange)
63*35238bceSAndroid Build Coastguard Worker     : m_function(function)
64*35238bceSAndroid Build Coastguard Worker     , m_inValueRange(valueRange.getType())
65*35238bceSAndroid Build Coastguard Worker     , m_child(DE_NULL)
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker     DE_UNREF(state);
68*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(valueRange.getType().isFloatOrVec());
69*35238bceSAndroid Build Coastguard Worker 
70*35238bceSAndroid Build Coastguard Worker     m_value.setStorage(valueRange.getType());
71*35238bceSAndroid Build Coastguard Worker 
72*35238bceSAndroid Build Coastguard Worker     // Compute input value range
73*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < m_inValueRange.getType().getNumElements(); ndx++)
74*35238bceSAndroid Build Coastguard Worker     {
75*35238bceSAndroid Build Coastguard Worker         ConstValueRangeAccess outRange = valueRange.component(ndx);
76*35238bceSAndroid Build Coastguard Worker         ValueRangeAccess inRange       = m_inValueRange.asAccess().component(ndx);
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker         ComputeValueRange()(outRange.getMin().asFloat(), outRange.getMax().asFloat(), inRange.getMin().asFloat(),
79*35238bceSAndroid Build Coastguard Worker                             inRange.getMax().asFloat());
80*35238bceSAndroid Build Coastguard Worker     }
81*35238bceSAndroid Build Coastguard Worker }
82*35238bceSAndroid Build Coastguard Worker 
83*35238bceSAndroid Build Coastguard Worker template <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
~UnaryBuiltinVecFunc(void)84*35238bceSAndroid Build Coastguard Worker UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::~UnaryBuiltinVecFunc(void)
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker     delete m_child;
87*35238bceSAndroid Build Coastguard Worker }
88*35238bceSAndroid Build Coastguard Worker 
89*35238bceSAndroid Build Coastguard Worker template <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
createNextChild(GeneratorState & state)90*35238bceSAndroid Build Coastguard Worker Expression *UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::createNextChild(
91*35238bceSAndroid Build Coastguard Worker     GeneratorState &state)
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker     if (m_child)
94*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker     m_child = Expression::createRandom(state, m_inValueRange.asAccess());
97*35238bceSAndroid Build Coastguard Worker     return m_child;
98*35238bceSAndroid Build Coastguard Worker }
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker template <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
tokenize(GeneratorState & state,TokenStream & str) const101*35238bceSAndroid Build Coastguard Worker void UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::tokenize(GeneratorState &state,
102*35238bceSAndroid Build Coastguard Worker                                                                                      TokenStream &str) const
103*35238bceSAndroid Build Coastguard Worker {
104*35238bceSAndroid Build Coastguard Worker     str << Token(m_function.c_str()) << Token::LEFT_PAREN;
105*35238bceSAndroid Build Coastguard Worker     m_child->tokenize(state, str);
106*35238bceSAndroid Build Coastguard Worker     str << Token::RIGHT_PAREN;
107*35238bceSAndroid Build Coastguard Worker }
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker template <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
evaluate(ExecutionContext & execCtx)110*35238bceSAndroid Build Coastguard Worker void UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::evaluate(ExecutionContext &execCtx)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker     m_child->evaluate(execCtx);
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker     ExecConstValueAccess srcValue = m_child->getValue();
115*35238bceSAndroid Build Coastguard Worker     ExecValueAccess dstValue      = m_value.getValue(m_inValueRange.getType());
116*35238bceSAndroid Build Coastguard Worker 
117*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < m_inValueRange.getType().getNumElements(); elemNdx++)
118*35238bceSAndroid Build Coastguard Worker     {
119*35238bceSAndroid Build Coastguard Worker         ExecConstValueAccess srcComp = srcValue.component(elemNdx);
120*35238bceSAndroid Build Coastguard Worker         ExecValueAccess dstComp      = dstValue.component(elemNdx);
121*35238bceSAndroid Build Coastguard Worker 
122*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
123*35238bceSAndroid Build Coastguard Worker             dstComp.asFloat(compNdx) = Evaluate()(srcComp.asFloat(compNdx));
124*35238bceSAndroid Build Coastguard Worker     }
125*35238bceSAndroid Build Coastguard Worker }
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker template <class GetValueRangeWeight, class ComputeValueRange, class Evaluate>
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)128*35238bceSAndroid Build Coastguard Worker float UnaryBuiltinVecFunc<GetValueRangeWeight, ComputeValueRange, Evaluate>::getWeight(const GeneratorState &state,
129*35238bceSAndroid Build Coastguard Worker                                                                                        ConstValueRangeAccess valueRange)
130*35238bceSAndroid Build Coastguard Worker {
131*35238bceSAndroid Build Coastguard Worker     // \todo [2011-06-14 pyry] Void support?
132*35238bceSAndroid Build Coastguard Worker     if (!valueRange.getType().isFloatOrVec())
133*35238bceSAndroid Build Coastguard Worker         return 0.0f;
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker     int availableLevels = state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker     if (availableLevels < getConservativeValueExprDepth(state, valueRange) + 1)
138*35238bceSAndroid Build Coastguard Worker         return 0.0f;
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker     // Compute value range weight
141*35238bceSAndroid Build Coastguard Worker     float combinedWeight = 1.0f;
142*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < valueRange.getType().getNumElements(); elemNdx++)
143*35238bceSAndroid Build Coastguard Worker     {
144*35238bceSAndroid Build Coastguard Worker         float elemWeight = GetValueRangeWeight()(valueRange.component(elemNdx).getMin().asFloat(),
145*35238bceSAndroid Build Coastguard Worker                                                  valueRange.component(elemNdx).getMax().asFloat());
146*35238bceSAndroid Build Coastguard Worker         combinedWeight *= elemWeight;
147*35238bceSAndroid Build Coastguard Worker     }
148*35238bceSAndroid Build Coastguard Worker 
149*35238bceSAndroid Build Coastguard Worker     return combinedWeight;
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker // Proxy template.
153*35238bceSAndroid Build Coastguard Worker template <class C>
154*35238bceSAndroid Build Coastguard Worker struct GetUnaryBuiltinVecWeight
155*35238bceSAndroid Build Coastguard Worker {
operator ()rsg::GetUnaryBuiltinVecWeight156*35238bceSAndroid Build Coastguard Worker     inline float operator()(float outMin, float outMax) const
157*35238bceSAndroid Build Coastguard Worker     {
158*35238bceSAndroid Build Coastguard Worker         return C::getCompWeight(outMin, outMax);
159*35238bceSAndroid Build Coastguard Worker     }
160*35238bceSAndroid Build Coastguard Worker };
161*35238bceSAndroid Build Coastguard Worker 
162*35238bceSAndroid Build Coastguard Worker template <class C>
163*35238bceSAndroid Build Coastguard Worker struct ComputeUnaryBuiltinVecRange
164*35238bceSAndroid Build Coastguard Worker {
operator ()rsg::ComputeUnaryBuiltinVecRange165*35238bceSAndroid Build Coastguard Worker     inline void operator()(float outMin, float outMax, float &inMin, float &inMax) const
166*35238bceSAndroid Build Coastguard Worker     {
167*35238bceSAndroid Build Coastguard Worker         C::computeValueRange(outMin, outMax, inMin, inMax);
168*35238bceSAndroid Build Coastguard Worker     }
169*35238bceSAndroid Build Coastguard Worker };
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker template <class C>
172*35238bceSAndroid Build Coastguard Worker struct EvaluateUnaryBuiltinVec
173*35238bceSAndroid Build Coastguard Worker {
operator ()rsg::EvaluateUnaryBuiltinVec174*35238bceSAndroid Build Coastguard Worker     inline float operator()(float inVal) const
175*35238bceSAndroid Build Coastguard Worker     {
176*35238bceSAndroid Build Coastguard Worker         return C::evaluateComp(inVal);
177*35238bceSAndroid Build Coastguard Worker     }
178*35238bceSAndroid Build Coastguard Worker };
179*35238bceSAndroid Build Coastguard Worker 
180*35238bceSAndroid Build Coastguard Worker template <class C>
181*35238bceSAndroid Build Coastguard Worker class UnaryBuiltinVecTemplateProxy
182*35238bceSAndroid Build Coastguard Worker     : public UnaryBuiltinVecFunc<GetUnaryBuiltinVecWeight<C>, ComputeUnaryBuiltinVecRange<C>,
183*35238bceSAndroid Build Coastguard Worker                                  EvaluateUnaryBuiltinVec<C>>
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker public:
UnaryBuiltinVecTemplateProxy(GeneratorState & state,const char * function,ConstValueRangeAccess valueRange)186*35238bceSAndroid Build Coastguard Worker     UnaryBuiltinVecTemplateProxy(GeneratorState &state, const char *function, ConstValueRangeAccess valueRange)
187*35238bceSAndroid Build Coastguard Worker         : UnaryBuiltinVecFunc<GetUnaryBuiltinVecWeight<C>, ComputeUnaryBuiltinVecRange<C>, EvaluateUnaryBuiltinVec<C>>(
188*35238bceSAndroid Build Coastguard Worker               state, function, valueRange)
189*35238bceSAndroid Build Coastguard Worker     {
190*35238bceSAndroid Build Coastguard Worker     }
191*35238bceSAndroid Build Coastguard Worker };
192*35238bceSAndroid Build Coastguard Worker 
193*35238bceSAndroid Build Coastguard Worker // Template for trigonometric function group.
194*35238bceSAndroid Build Coastguard Worker template <class C>
195*35238bceSAndroid Build Coastguard Worker class UnaryTrigonometricFunc : public UnaryBuiltinVecTemplateProxy<C>
196*35238bceSAndroid Build Coastguard Worker {
197*35238bceSAndroid Build Coastguard Worker public:
UnaryTrigonometricFunc(GeneratorState & state,const char * function,ConstValueRangeAccess valueRange)198*35238bceSAndroid Build Coastguard Worker     UnaryTrigonometricFunc(GeneratorState &state, const char *function, ConstValueRangeAccess valueRange)
199*35238bceSAndroid Build Coastguard Worker         : UnaryBuiltinVecTemplateProxy<C>(state, function, valueRange)
200*35238bceSAndroid Build Coastguard Worker     {
201*35238bceSAndroid Build Coastguard Worker     }
202*35238bceSAndroid Build Coastguard Worker 
getCompWeight(float outMin,float outMax)203*35238bceSAndroid Build Coastguard Worker     static inline float getCompWeight(float outMin, float outMax)
204*35238bceSAndroid Build Coastguard Worker     {
205*35238bceSAndroid Build Coastguard Worker         if (Scalar::min<float>() == outMin || Scalar::max<float>() == outMax)
206*35238bceSAndroid Build Coastguard Worker             return 1.0f; // Infinite value range, anything goes
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker         // Transform range
209*35238bceSAndroid Build Coastguard Worker         float inMin, inMax;
210*35238bceSAndroid Build Coastguard Worker         if (!C::transformValueRange(outMin, outMax, inMin, inMax))
211*35238bceSAndroid Build Coastguard Worker             return 0.0f; // Not possible to transform value range (out of range perhaps)
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker         // Quantize
214*35238bceSAndroid Build Coastguard Worker         if (!quantizeFloatRange(inMin, inMax))
215*35238bceSAndroid Build Coastguard Worker             return 0.0f; // Not possible to quantize - would cause accuracy issues
216*35238bceSAndroid Build Coastguard Worker 
217*35238bceSAndroid Build Coastguard Worker         if (outMin == outMax)
218*35238bceSAndroid Build Coastguard Worker             return 1.0f; // Constant value and passed quantization
219*35238bceSAndroid Build Coastguard Worker 
220*35238bceSAndroid Build Coastguard Worker         // Evaluate new intersection
221*35238bceSAndroid Build Coastguard Worker         float intersectionLen = C::evaluateComp(inMax) - C::evaluateComp(inMin);
222*35238bceSAndroid Build Coastguard Worker         float valRangeLen     = outMax - outMin;
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker         return deFloatMax(0.1f, intersectionLen / valRangeLen);
225*35238bceSAndroid Build Coastguard Worker     }
226*35238bceSAndroid Build Coastguard Worker 
computeValueRange(float outMin,float outMax,float & inMin,float & inMax)227*35238bceSAndroid Build Coastguard Worker     static inline void computeValueRange(float outMin, float outMax, float &inMin, float &inMax)
228*35238bceSAndroid Build Coastguard Worker     {
229*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(C::transformValueRange(outMin, outMax, inMin, inMax));
230*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(quantizeFloatRange(inMin, inMax));
231*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(inMin <= inMax);
232*35238bceSAndroid Build Coastguard Worker     }
233*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)234*35238bceSAndroid Build Coastguard Worker     static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
235*35238bceSAndroid Build Coastguard Worker     {
236*35238bceSAndroid Build Coastguard Worker         if (state.getProgramParameters().trigonometricBaseWeight <= 0.0f)
237*35238bceSAndroid Build Coastguard Worker             return 0.0f;
238*35238bceSAndroid Build Coastguard Worker 
239*35238bceSAndroid Build Coastguard Worker         return UnaryBuiltinVecTemplateProxy<C>::getWeight(state, valueRange) *
240*35238bceSAndroid Build Coastguard Worker                state.getProgramParameters().trigonometricBaseWeight;
241*35238bceSAndroid Build Coastguard Worker     }
242*35238bceSAndroid Build Coastguard Worker };
243*35238bceSAndroid Build Coastguard Worker 
244*35238bceSAndroid Build Coastguard Worker class SinOp : public UnaryTrigonometricFunc<SinOp>
245*35238bceSAndroid Build Coastguard Worker {
246*35238bceSAndroid Build Coastguard Worker public:
SinOp(GeneratorState & state,ConstValueRangeAccess valueRange)247*35238bceSAndroid Build Coastguard Worker     SinOp(GeneratorState &state, ConstValueRangeAccess valueRange)
248*35238bceSAndroid Build Coastguard Worker         : UnaryTrigonometricFunc<SinOp>(state, "sin", valueRange)
249*35238bceSAndroid Build Coastguard Worker     {
250*35238bceSAndroid Build Coastguard Worker     }
251*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)252*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
253*35238bceSAndroid Build Coastguard Worker     {
254*35238bceSAndroid Build Coastguard Worker         if (outMax < -1.0f || outMin > 1.0f)
255*35238bceSAndroid Build Coastguard Worker             return false;
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker         inMin = (outMin >= -1.0f) ? deFloatAsin(outMin) : -0.5f * DE_PI;
258*35238bceSAndroid Build Coastguard Worker         inMax = (outMax <= +1.0f) ? deFloatAsin(outMax) : +0.5f * DE_PI;
259*35238bceSAndroid Build Coastguard Worker 
260*35238bceSAndroid Build Coastguard Worker         return true;
261*35238bceSAndroid Build Coastguard Worker     }
262*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)263*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
264*35238bceSAndroid Build Coastguard Worker     {
265*35238bceSAndroid Build Coastguard Worker         return deFloatSin(inVal);
266*35238bceSAndroid Build Coastguard Worker     }
267*35238bceSAndroid Build Coastguard Worker };
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker class CosOp : public UnaryTrigonometricFunc<CosOp>
270*35238bceSAndroid Build Coastguard Worker {
271*35238bceSAndroid Build Coastguard Worker public:
CosOp(GeneratorState & state,ConstValueRangeAccess valueRange)272*35238bceSAndroid Build Coastguard Worker     CosOp(GeneratorState &state, ConstValueRangeAccess valueRange)
273*35238bceSAndroid Build Coastguard Worker         : UnaryTrigonometricFunc<CosOp>(state, "cos", valueRange)
274*35238bceSAndroid Build Coastguard Worker     {
275*35238bceSAndroid Build Coastguard Worker     }
276*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)277*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
278*35238bceSAndroid Build Coastguard Worker     {
279*35238bceSAndroid Build Coastguard Worker         if (outMax < -1.0f || outMin > 1.0f)
280*35238bceSAndroid Build Coastguard Worker             return false;
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker         inMax = (outMin >= -1.0f) ? deFloatAcos(outMin) : +DE_PI;
283*35238bceSAndroid Build Coastguard Worker         inMin = (outMax <= +1.0f) ? deFloatAcos(outMax) : -DE_PI;
284*35238bceSAndroid Build Coastguard Worker 
285*35238bceSAndroid Build Coastguard Worker         return true;
286*35238bceSAndroid Build Coastguard Worker     }
287*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)288*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
289*35238bceSAndroid Build Coastguard Worker     {
290*35238bceSAndroid Build Coastguard Worker         return deFloatCos(inVal);
291*35238bceSAndroid Build Coastguard Worker     }
292*35238bceSAndroid Build Coastguard Worker };
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker class TanOp : public UnaryTrigonometricFunc<TanOp>
295*35238bceSAndroid Build Coastguard Worker {
296*35238bceSAndroid Build Coastguard Worker public:
TanOp(GeneratorState & state,ConstValueRangeAccess valueRange)297*35238bceSAndroid Build Coastguard Worker     TanOp(GeneratorState &state, ConstValueRangeAccess valueRange)
298*35238bceSAndroid Build Coastguard Worker         : UnaryTrigonometricFunc<TanOp>(state, "tan", valueRange)
299*35238bceSAndroid Build Coastguard Worker     {
300*35238bceSAndroid Build Coastguard Worker     }
301*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)302*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
303*35238bceSAndroid Build Coastguard Worker     {
304*35238bceSAndroid Build Coastguard Worker         // \note Currently tan() is limited to -4..4 range. Otherwise we will run into accuracy issues
305*35238bceSAndroid Build Coastguard Worker         const float rangeMin = -4.0f;
306*35238bceSAndroid Build Coastguard Worker         const float rangeMax = +4.0f;
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
309*35238bceSAndroid Build Coastguard Worker             return false;
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker         inMin = deFloatAtanOver(deFloatMax(outMin, rangeMin));
312*35238bceSAndroid Build Coastguard Worker         inMax = deFloatAtanOver(deFloatMin(outMax, rangeMax));
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker         return true;
315*35238bceSAndroid Build Coastguard Worker     }
316*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)317*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
318*35238bceSAndroid Build Coastguard Worker     {
319*35238bceSAndroid Build Coastguard Worker         return deFloatTan(inVal);
320*35238bceSAndroid Build Coastguard Worker     }
321*35238bceSAndroid Build Coastguard Worker };
322*35238bceSAndroid Build Coastguard Worker 
323*35238bceSAndroid Build Coastguard Worker class AsinOp : public UnaryTrigonometricFunc<AsinOp>
324*35238bceSAndroid Build Coastguard Worker {
325*35238bceSAndroid Build Coastguard Worker public:
AsinOp(GeneratorState & state,ConstValueRangeAccess valueRange)326*35238bceSAndroid Build Coastguard Worker     AsinOp(GeneratorState &state, ConstValueRangeAccess valueRange)
327*35238bceSAndroid Build Coastguard Worker         : UnaryTrigonometricFunc<AsinOp>(state, "asin", valueRange)
328*35238bceSAndroid Build Coastguard Worker     {
329*35238bceSAndroid Build Coastguard Worker     }
330*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)331*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
332*35238bceSAndroid Build Coastguard Worker     {
333*35238bceSAndroid Build Coastguard Worker         const float rangeMin = -DE_PI / 2.0f;
334*35238bceSAndroid Build Coastguard Worker         const float rangeMax = +DE_PI / 2.0f;
335*35238bceSAndroid Build Coastguard Worker 
336*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
337*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker         inMin = deFloatSin(deFloatMax(outMin, rangeMin));
340*35238bceSAndroid Build Coastguard Worker         inMax = deFloatSin(deFloatMin(outMax, rangeMax));
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker         return true;
343*35238bceSAndroid Build Coastguard Worker     }
344*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)345*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
346*35238bceSAndroid Build Coastguard Worker     {
347*35238bceSAndroid Build Coastguard Worker         return deFloatAsin(inVal);
348*35238bceSAndroid Build Coastguard Worker     }
349*35238bceSAndroid Build Coastguard Worker };
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker class AcosOp : public UnaryTrigonometricFunc<AcosOp>
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker public:
AcosOp(GeneratorState & state,ConstValueRangeAccess valueRange)354*35238bceSAndroid Build Coastguard Worker     AcosOp(GeneratorState &state, ConstValueRangeAccess valueRange)
355*35238bceSAndroid Build Coastguard Worker         : UnaryTrigonometricFunc<AcosOp>(state, "acos", valueRange)
356*35238bceSAndroid Build Coastguard Worker     {
357*35238bceSAndroid Build Coastguard Worker     }
358*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)359*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
360*35238bceSAndroid Build Coastguard Worker     {
361*35238bceSAndroid Build Coastguard Worker         const float rangeMin = 0.0f;
362*35238bceSAndroid Build Coastguard Worker         const float rangeMax = DE_PI;
363*35238bceSAndroid Build Coastguard Worker 
364*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
365*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
366*35238bceSAndroid Build Coastguard Worker 
367*35238bceSAndroid Build Coastguard Worker         inMax = deFloatCos(deFloatMax(outMin, rangeMin));
368*35238bceSAndroid Build Coastguard Worker         inMin = deFloatCos(deFloatMin(outMax, rangeMax));
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker         return true;
371*35238bceSAndroid Build Coastguard Worker     }
372*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)373*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
374*35238bceSAndroid Build Coastguard Worker     {
375*35238bceSAndroid Build Coastguard Worker         return deFloatAcos(inVal);
376*35238bceSAndroid Build Coastguard Worker     }
377*35238bceSAndroid Build Coastguard Worker };
378*35238bceSAndroid Build Coastguard Worker 
379*35238bceSAndroid Build Coastguard Worker class AtanOp : public UnaryTrigonometricFunc<AtanOp>
380*35238bceSAndroid Build Coastguard Worker {
381*35238bceSAndroid Build Coastguard Worker public:
AtanOp(GeneratorState & state,ConstValueRangeAccess valueRange)382*35238bceSAndroid Build Coastguard Worker     AtanOp(GeneratorState &state, ConstValueRangeAccess valueRange)
383*35238bceSAndroid Build Coastguard Worker         : UnaryTrigonometricFunc<AtanOp>(state, "atan", valueRange)
384*35238bceSAndroid Build Coastguard Worker     {
385*35238bceSAndroid Build Coastguard Worker     }
386*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)387*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
388*35238bceSAndroid Build Coastguard Worker     {
389*35238bceSAndroid Build Coastguard Worker         // \note For accuracy reasons output range is limited to -1..1
390*35238bceSAndroid Build Coastguard Worker         const float rangeMin = -1.0f;
391*35238bceSAndroid Build Coastguard Worker         const float rangeMax = +1.0f;
392*35238bceSAndroid Build Coastguard Worker 
393*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
394*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
395*35238bceSAndroid Build Coastguard Worker 
396*35238bceSAndroid Build Coastguard Worker         inMin = deFloatTan(deFloatMax(outMin, rangeMin));
397*35238bceSAndroid Build Coastguard Worker         inMax = deFloatTan(deFloatMin(outMax, rangeMax));
398*35238bceSAndroid Build Coastguard Worker 
399*35238bceSAndroid Build Coastguard Worker         return true;
400*35238bceSAndroid Build Coastguard Worker     }
401*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)402*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
403*35238bceSAndroid Build Coastguard Worker     {
404*35238bceSAndroid Build Coastguard Worker         return deFloatAtanOver(inVal);
405*35238bceSAndroid Build Coastguard Worker     }
406*35238bceSAndroid Build Coastguard Worker };
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker // Template for exponential function group.
409*35238bceSAndroid Build Coastguard Worker // \todo [2011-07-07 pyry] Shares most of the code with Trigonometric variant..
410*35238bceSAndroid Build Coastguard Worker template <class C>
411*35238bceSAndroid Build Coastguard Worker class UnaryExponentialFunc : public UnaryBuiltinVecTemplateProxy<C>
412*35238bceSAndroid Build Coastguard Worker {
413*35238bceSAndroid Build Coastguard Worker public:
UnaryExponentialFunc(GeneratorState & state,const char * function,ConstValueRangeAccess valueRange)414*35238bceSAndroid Build Coastguard Worker     UnaryExponentialFunc(GeneratorState &state, const char *function, ConstValueRangeAccess valueRange)
415*35238bceSAndroid Build Coastguard Worker         : UnaryBuiltinVecTemplateProxy<C>(state, function, valueRange)
416*35238bceSAndroid Build Coastguard Worker     {
417*35238bceSAndroid Build Coastguard Worker     }
418*35238bceSAndroid Build Coastguard Worker 
getCompWeight(float outMin,float outMax)419*35238bceSAndroid Build Coastguard Worker     static inline float getCompWeight(float outMin, float outMax)
420*35238bceSAndroid Build Coastguard Worker     {
421*35238bceSAndroid Build Coastguard Worker         if (Scalar::min<float>() == outMin || Scalar::max<float>() == outMax)
422*35238bceSAndroid Build Coastguard Worker             return 1.0f; // Infinite value range, anything goes
423*35238bceSAndroid Build Coastguard Worker 
424*35238bceSAndroid Build Coastguard Worker         // Transform range
425*35238bceSAndroid Build Coastguard Worker         float inMin, inMax;
426*35238bceSAndroid Build Coastguard Worker         if (!C::transformValueRange(outMin, outMax, inMin, inMax))
427*35238bceSAndroid Build Coastguard Worker             return 0.0f; // Not possible to transform value range (out of range perhaps)
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker         // Quantize
430*35238bceSAndroid Build Coastguard Worker         if (!quantizeFloatRange(inMin, inMax))
431*35238bceSAndroid Build Coastguard Worker             return 0.0f; // Not possible to quantize - would cause accuracy issues
432*35238bceSAndroid Build Coastguard Worker 
433*35238bceSAndroid Build Coastguard Worker         if (outMin == outMax)
434*35238bceSAndroid Build Coastguard Worker             return 1.0f; // Constant value and passed quantization
435*35238bceSAndroid Build Coastguard Worker 
436*35238bceSAndroid Build Coastguard Worker         // Evaluate new intersection
437*35238bceSAndroid Build Coastguard Worker         float intersectionLen = C::evaluateComp(inMax) - C::evaluateComp(inMin);
438*35238bceSAndroid Build Coastguard Worker         float valRangeLen     = outMax - outMin;
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker         return deFloatMax(0.1f, intersectionLen / valRangeLen);
441*35238bceSAndroid Build Coastguard Worker     }
442*35238bceSAndroid Build Coastguard Worker 
computeValueRange(float outMin,float outMax,float & inMin,float & inMax)443*35238bceSAndroid Build Coastguard Worker     static inline void computeValueRange(float outMin, float outMax, float &inMin, float &inMax)
444*35238bceSAndroid Build Coastguard Worker     {
445*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(C::transformValueRange(outMin, outMax, inMin, inMax));
446*35238bceSAndroid Build Coastguard Worker         DE_VERIFY(quantizeFloatRange(inMin, inMax));
447*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(inMin <= inMax);
448*35238bceSAndroid Build Coastguard Worker     }
449*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)450*35238bceSAndroid Build Coastguard Worker     static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
451*35238bceSAndroid Build Coastguard Worker     {
452*35238bceSAndroid Build Coastguard Worker         if (state.getProgramParameters().exponentialBaseWeight <= 0.0f)
453*35238bceSAndroid Build Coastguard Worker             return 0.0f;
454*35238bceSAndroid Build Coastguard Worker 
455*35238bceSAndroid Build Coastguard Worker         return UnaryBuiltinVecTemplateProxy<C>::getWeight(state, valueRange) *
456*35238bceSAndroid Build Coastguard Worker                state.getProgramParameters().exponentialBaseWeight;
457*35238bceSAndroid Build Coastguard Worker     }
458*35238bceSAndroid Build Coastguard Worker };
459*35238bceSAndroid Build Coastguard Worker 
460*35238bceSAndroid Build Coastguard Worker class ExpOp : public UnaryExponentialFunc<ExpOp>
461*35238bceSAndroid Build Coastguard Worker {
462*35238bceSAndroid Build Coastguard Worker public:
ExpOp(GeneratorState & state,ConstValueRangeAccess valueRange)463*35238bceSAndroid Build Coastguard Worker     ExpOp(GeneratorState &state, ConstValueRangeAccess valueRange)
464*35238bceSAndroid Build Coastguard Worker         : UnaryExponentialFunc<ExpOp>(state, "exp", valueRange)
465*35238bceSAndroid Build Coastguard Worker     {
466*35238bceSAndroid Build Coastguard Worker     }
467*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)468*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
469*35238bceSAndroid Build Coastguard Worker     {
470*35238bceSAndroid Build Coastguard Worker         // Limited due to accuracy reasons, should be 0..+inf
471*35238bceSAndroid Build Coastguard Worker         const float rangeMin = 0.1f;
472*35238bceSAndroid Build Coastguard Worker         const float rangeMax = 10.0f;
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
475*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker         inMin = deFloatLog(deFloatMax(outMin, rangeMin));
478*35238bceSAndroid Build Coastguard Worker         inMax = deFloatLog(deFloatMin(outMax, rangeMax));
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker         return true;
481*35238bceSAndroid Build Coastguard Worker     }
482*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)483*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
484*35238bceSAndroid Build Coastguard Worker     {
485*35238bceSAndroid Build Coastguard Worker         return deFloatExp(inVal);
486*35238bceSAndroid Build Coastguard Worker     }
487*35238bceSAndroid Build Coastguard Worker };
488*35238bceSAndroid Build Coastguard Worker 
489*35238bceSAndroid Build Coastguard Worker class LogOp : public UnaryExponentialFunc<LogOp>
490*35238bceSAndroid Build Coastguard Worker {
491*35238bceSAndroid Build Coastguard Worker public:
LogOp(GeneratorState & state,ConstValueRangeAccess valueRange)492*35238bceSAndroid Build Coastguard Worker     LogOp(GeneratorState &state, ConstValueRangeAccess valueRange)
493*35238bceSAndroid Build Coastguard Worker         : UnaryExponentialFunc<LogOp>(state, "log", valueRange)
494*35238bceSAndroid Build Coastguard Worker     {
495*35238bceSAndroid Build Coastguard Worker     }
496*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)497*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
498*35238bceSAndroid Build Coastguard Worker     {
499*35238bceSAndroid Build Coastguard Worker         // Limited due to accuracy reasons, should be -inf..+inf
500*35238bceSAndroid Build Coastguard Worker         const float rangeMin = 0.1f;
501*35238bceSAndroid Build Coastguard Worker         const float rangeMax = 6.0f;
502*35238bceSAndroid Build Coastguard Worker 
503*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
504*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker         inMin = deFloatExp(deFloatMax(outMin, rangeMin));
507*35238bceSAndroid Build Coastguard Worker         inMax = deFloatExp(deFloatMin(outMax, rangeMax));
508*35238bceSAndroid Build Coastguard Worker 
509*35238bceSAndroid Build Coastguard Worker         return true;
510*35238bceSAndroid Build Coastguard Worker     }
511*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)512*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
513*35238bceSAndroid Build Coastguard Worker     {
514*35238bceSAndroid Build Coastguard Worker         return deFloatLog(inVal);
515*35238bceSAndroid Build Coastguard Worker     }
516*35238bceSAndroid Build Coastguard Worker };
517*35238bceSAndroid Build Coastguard Worker 
518*35238bceSAndroid Build Coastguard Worker class Exp2Op : public UnaryExponentialFunc<Exp2Op>
519*35238bceSAndroid Build Coastguard Worker {
520*35238bceSAndroid Build Coastguard Worker public:
Exp2Op(GeneratorState & state,ConstValueRangeAccess valueRange)521*35238bceSAndroid Build Coastguard Worker     Exp2Op(GeneratorState &state, ConstValueRangeAccess valueRange)
522*35238bceSAndroid Build Coastguard Worker         : UnaryExponentialFunc<Exp2Op>(state, "exp2", valueRange)
523*35238bceSAndroid Build Coastguard Worker     {
524*35238bceSAndroid Build Coastguard Worker     }
525*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)526*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
527*35238bceSAndroid Build Coastguard Worker     {
528*35238bceSAndroid Build Coastguard Worker         // Limited due to accuracy reasons, should be 0..+inf
529*35238bceSAndroid Build Coastguard Worker         const float rangeMin = 0.1f;
530*35238bceSAndroid Build Coastguard Worker         const float rangeMax = 10.0f;
531*35238bceSAndroid Build Coastguard Worker 
532*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
533*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
534*35238bceSAndroid Build Coastguard Worker 
535*35238bceSAndroid Build Coastguard Worker         inMin = deFloatLog2(deFloatMax(outMin, rangeMin));
536*35238bceSAndroid Build Coastguard Worker         inMax = deFloatLog2(deFloatMin(outMax, rangeMax));
537*35238bceSAndroid Build Coastguard Worker 
538*35238bceSAndroid Build Coastguard Worker         return true;
539*35238bceSAndroid Build Coastguard Worker     }
540*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)541*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
542*35238bceSAndroid Build Coastguard Worker     {
543*35238bceSAndroid Build Coastguard Worker         return deFloatExp2(inVal);
544*35238bceSAndroid Build Coastguard Worker     }
545*35238bceSAndroid Build Coastguard Worker };
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker class Log2Op : public UnaryExponentialFunc<Log2Op>
548*35238bceSAndroid Build Coastguard Worker {
549*35238bceSAndroid Build Coastguard Worker public:
Log2Op(GeneratorState & state,ConstValueRangeAccess valueRange)550*35238bceSAndroid Build Coastguard Worker     Log2Op(GeneratorState &state, ConstValueRangeAccess valueRange)
551*35238bceSAndroid Build Coastguard Worker         : UnaryExponentialFunc<Log2Op>(state, "log2", valueRange)
552*35238bceSAndroid Build Coastguard Worker     {
553*35238bceSAndroid Build Coastguard Worker     }
554*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)555*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
556*35238bceSAndroid Build Coastguard Worker     {
557*35238bceSAndroid Build Coastguard Worker         // Limited due to accuracy reasons, should be -inf..+inf
558*35238bceSAndroid Build Coastguard Worker         const float rangeMin = 0.1f;
559*35238bceSAndroid Build Coastguard Worker         const float rangeMax = 6.0f;
560*35238bceSAndroid Build Coastguard Worker 
561*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
562*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
563*35238bceSAndroid Build Coastguard Worker 
564*35238bceSAndroid Build Coastguard Worker         inMin = deFloatExp2(deFloatMax(outMin, rangeMin));
565*35238bceSAndroid Build Coastguard Worker         inMax = deFloatExp2(deFloatMin(outMax, rangeMax));
566*35238bceSAndroid Build Coastguard Worker 
567*35238bceSAndroid Build Coastguard Worker         return true;
568*35238bceSAndroid Build Coastguard Worker     }
569*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)570*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
571*35238bceSAndroid Build Coastguard Worker     {
572*35238bceSAndroid Build Coastguard Worker         return deFloatLog2(inVal);
573*35238bceSAndroid Build Coastguard Worker     }
574*35238bceSAndroid Build Coastguard Worker };
575*35238bceSAndroid Build Coastguard Worker 
576*35238bceSAndroid Build Coastguard Worker class SqrtOp : public UnaryExponentialFunc<SqrtOp>
577*35238bceSAndroid Build Coastguard Worker {
578*35238bceSAndroid Build Coastguard Worker public:
SqrtOp(GeneratorState & state,ConstValueRangeAccess valueRange)579*35238bceSAndroid Build Coastguard Worker     SqrtOp(GeneratorState &state, ConstValueRangeAccess valueRange)
580*35238bceSAndroid Build Coastguard Worker         : UnaryExponentialFunc<SqrtOp>(state, "sqrt", valueRange)
581*35238bceSAndroid Build Coastguard Worker     {
582*35238bceSAndroid Build Coastguard Worker     }
583*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)584*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
585*35238bceSAndroid Build Coastguard Worker     {
586*35238bceSAndroid Build Coastguard Worker         // Limited due to accuracy reasons, should be 0..+inf
587*35238bceSAndroid Build Coastguard Worker         const float rangeMin = 0.0f;
588*35238bceSAndroid Build Coastguard Worker         const float rangeMax = 4.0f;
589*35238bceSAndroid Build Coastguard Worker 
590*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
591*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
592*35238bceSAndroid Build Coastguard Worker 
593*35238bceSAndroid Build Coastguard Worker         inMin = deFloatMax(outMin, rangeMin);
594*35238bceSAndroid Build Coastguard Worker         inMax = deFloatMin(outMax, rangeMax);
595*35238bceSAndroid Build Coastguard Worker 
596*35238bceSAndroid Build Coastguard Worker         inMin *= inMin;
597*35238bceSAndroid Build Coastguard Worker         inMax *= inMax;
598*35238bceSAndroid Build Coastguard Worker 
599*35238bceSAndroid Build Coastguard Worker         return true;
600*35238bceSAndroid Build Coastguard Worker     }
601*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)602*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
603*35238bceSAndroid Build Coastguard Worker     {
604*35238bceSAndroid Build Coastguard Worker         return deFloatSqrt(inVal);
605*35238bceSAndroid Build Coastguard Worker     }
606*35238bceSAndroid Build Coastguard Worker };
607*35238bceSAndroid Build Coastguard Worker 
608*35238bceSAndroid Build Coastguard Worker class InvSqrtOp : public UnaryExponentialFunc<InvSqrtOp>
609*35238bceSAndroid Build Coastguard Worker {
610*35238bceSAndroid Build Coastguard Worker public:
InvSqrtOp(GeneratorState & state,ConstValueRangeAccess valueRange)611*35238bceSAndroid Build Coastguard Worker     InvSqrtOp(GeneratorState &state, ConstValueRangeAccess valueRange)
612*35238bceSAndroid Build Coastguard Worker         : UnaryExponentialFunc<InvSqrtOp>(state, "inversesqrt", valueRange)
613*35238bceSAndroid Build Coastguard Worker     {
614*35238bceSAndroid Build Coastguard Worker     }
615*35238bceSAndroid Build Coastguard Worker 
transformValueRange(float outMin,float outMax,float & inMin,float & inMax)616*35238bceSAndroid Build Coastguard Worker     static inline bool transformValueRange(float outMin, float outMax, float &inMin, float &inMax)
617*35238bceSAndroid Build Coastguard Worker     {
618*35238bceSAndroid Build Coastguard Worker         // Limited due to accuracy reasons
619*35238bceSAndroid Build Coastguard Worker         const float rangeMin = 0.4f;
620*35238bceSAndroid Build Coastguard Worker         const float rangeMax = 3.0f;
621*35238bceSAndroid Build Coastguard Worker 
622*35238bceSAndroid Build Coastguard Worker         if (outMax < rangeMin || outMin > rangeMax)
623*35238bceSAndroid Build Coastguard Worker             return false; // Out of range
624*35238bceSAndroid Build Coastguard Worker 
625*35238bceSAndroid Build Coastguard Worker         inMax = 1.0f / deFloatMax(outMin, rangeMin);
626*35238bceSAndroid Build Coastguard Worker         inMin = 1.0f / deFloatMin(outMax, rangeMax);
627*35238bceSAndroid Build Coastguard Worker 
628*35238bceSAndroid Build Coastguard Worker         inMin *= inMin;
629*35238bceSAndroid Build Coastguard Worker         inMax *= inMax;
630*35238bceSAndroid Build Coastguard Worker 
631*35238bceSAndroid Build Coastguard Worker         return true;
632*35238bceSAndroid Build Coastguard Worker     }
633*35238bceSAndroid Build Coastguard Worker 
evaluateComp(float inVal)634*35238bceSAndroid Build Coastguard Worker     static inline float evaluateComp(float inVal)
635*35238bceSAndroid Build Coastguard Worker     {
636*35238bceSAndroid Build Coastguard Worker         return 1.0f / deFloatSqrt(inVal);
637*35238bceSAndroid Build Coastguard Worker     }
638*35238bceSAndroid Build Coastguard Worker };
639*35238bceSAndroid Build Coastguard Worker 
640*35238bceSAndroid Build Coastguard Worker } // namespace rsg
641*35238bceSAndroid Build Coastguard Worker 
642*35238bceSAndroid Build Coastguard Worker #endif // _RSGBUILTINFUNCTIONS_HPP
643