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