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