blob: cb76ac969b1db07cb0bbda42a29d9244cf308a45 [file] [log] [blame]
#ifndef _RSGBINARYOPS_HPP
#define _RSGBINARYOPS_HPP
/*-------------------------------------------------------------------------
* drawElements Quality Program Random Shader Generator
* ----------------------------------------------------
*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Binary operators.
*//*--------------------------------------------------------------------*/
#include "rsgDefs.hpp"
#include "rsgExpression.hpp"
namespace rsg
{
enum Associativity
{
ASSOCIATIVITY_LEFT = 0,
ASSOCIATIVITY_RIGHT,
ASSOCIATIVITY_LAST
};
template <int Precedence, Associativity Assoc>
class BinaryOp : public Expression
{
public:
BinaryOp (Token::Type operatorToken);
virtual ~BinaryOp (void);
Expression* createNextChild (GeneratorState& state);
void tokenize (GeneratorState& state, TokenStream& str) const;
void evaluate (ExecutionContext& execCtx);
ExecConstValueAccess getValue (void) const { return m_value.getValue(m_type); }
virtual void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b) = DE_NULL;
protected:
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
Token::Type m_operator;
VariableType m_type;
ExecValueStorage m_value;
ValueRange m_leftValueRange;
ValueRange m_rightValueRange;
Expression* m_leftValueExpr;
Expression* m_rightValueExpr;
};
template <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp>
class BinaryVecOp : public BinaryOp<Precedence, ASSOCIATIVITY_LEFT>
{
public:
BinaryVecOp (GeneratorState& state, Token::Type operatorToken, ConstValueRangeAccess valueRange);
virtual ~BinaryVecOp (void);
void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b);
};
struct ComputeMulRange
{
void operator() (de::Random& rnd, float dstMin, float dstMax, float& aMin, float& aMax, float& bMin, float& bMax) const;
void operator() (de::Random& rnd, int dstMin, int dstMax, int& aMin, int& aMax, int& bMin, int& bMax) const;
void operator() (de::Random&, bool, bool, bool&, bool&, bool&, bool&) const { DE_ASSERT(DE_FALSE); }
};
struct EvaluateMul
{
template <typename T> inline T operator() (T a, T b) const { return a*b; }
};
typedef BinaryVecOp<4, true, true, false, ComputeMulRange, EvaluateMul> MulBase;
class MulOp : public MulBase
{
public:
MulOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~MulOp (void) {}
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
struct ComputeAddRange
{
template <typename T>
void operator() (de::Random& rnd, T dstMin, T dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const;
};
struct EvaluateAdd
{
template <typename T> inline T operator() (T a, T b) const { return a+b; }
};
typedef BinaryVecOp<5, true, true, false, ComputeAddRange, EvaluateAdd> AddBase;
class AddOp : public AddBase
{
public:
AddOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~AddOp (void) {}
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
struct ComputeSubRange
{
template <typename T>
void operator() (de::Random& rnd, T dstMin, T dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const;
};
struct EvaluateSub
{
template <typename T> inline T operator() (T a, T b) const { return a-b; }
};
typedef BinaryVecOp<5, true, true, false, ComputeSubRange, EvaluateSub> SubBase;
class SubOp : public SubBase
{
public:
SubOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~SubOp (void) {}
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
/* Template for Relational Operators. */
template <class ComputeValueRange, class EvaluateComp>
class RelationalOp : public BinaryOp<7, ASSOCIATIVITY_LEFT>
{
public:
RelationalOp (GeneratorState& state, Token::Type operatorToken, ConstValueRangeAccess valueRange);
virtual ~RelationalOp (void);
void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b);
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
/* Less Than. */
struct ComputeLessThanRange
{
template <typename T>
void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const;
};
struct EvaluateLessThan
{
template <typename T> inline bool operator() (T a, T b) const { return a < b; }
};
typedef RelationalOp<ComputeLessThanRange, EvaluateLessThan> LessThanBase;
class LessThanOp : public LessThanBase
{
public:
LessThanOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~LessThanOp (void) {}
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
/* Less or Equal. */
struct ComputeLessOrEqualRange
{
template <typename T>
void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const;
};
struct EvaluateLessOrEqual
{
template <typename T> inline bool operator() (T a, T b) const { return a <= b; }
};
typedef RelationalOp<ComputeLessOrEqualRange, EvaluateLessOrEqual> LessOrEqualBase;
class LessOrEqualOp : public LessOrEqualBase
{
public:
LessOrEqualOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~LessOrEqualOp (void) {};
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
/* Greater Than. */
struct ComputeGreaterThanRange
{
template <typename T>
void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const
{
ComputeLessThanRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax);
}
};
struct EvaluateGreaterThan
{
template <typename T> inline bool operator() (T a, T b) const { return a > b; }
};
typedef RelationalOp<ComputeGreaterThanRange, EvaluateGreaterThan> GreaterThanBase;
class GreaterThanOp : public GreaterThanBase
{
public:
GreaterThanOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~GreaterThanOp (void) {}
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
/* Greater or Equal. */
struct ComputeGreaterOrEqualRange
{
template <typename T>
void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const
{
ComputeLessOrEqualRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax);
}
};
struct EvaluateGreaterOrEqual
{
template <typename T> inline bool operator() (T a, T b) const { return a >= b; }
};
typedef RelationalOp<ComputeGreaterOrEqualRange, EvaluateGreaterOrEqual> GreaterOrEqualBase;
class GreaterOrEqualOp : public GreaterOrEqualBase
{
public:
GreaterOrEqualOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~GreaterOrEqualOp (void) {};
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
/* Equality comparison. */
template <bool IsEqual>
class EqualityComparisonOp : public BinaryOp<8, ASSOCIATIVITY_LEFT>
{
public:
EqualityComparisonOp (GeneratorState& state, ConstValueRangeAccess valueRange);
virtual ~EqualityComparisonOp (void) {}
void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b);
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
// \note Since template implementation is in .cpp we have to reference specialized constructor and static functions from there.
class EqualOp : public EqualityComparisonOp<true>
{
public:
EqualOp (GeneratorState& state, ConstValueRangeAccess valueRange);
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
class NotEqualOp : public EqualityComparisonOp<false>
{
public:
NotEqualOp (GeneratorState& state, ConstValueRangeAccess valueRange);
static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange);
};
} // rsg
#endif // _RSGBINARYOPS_HPP