| #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(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); |
| }; |
| |
| } // namespace rsg |
| |
| #endif // _RSGBINARYOPS_HPP |