1 #ifndef _RSGBINARYOPS_HPP 2 #define _RSGBINARYOPS_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 Binary operators. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "rsgDefs.hpp" 27 #include "rsgExpression.hpp" 28 29 namespace rsg 30 { 31 32 enum Associativity 33 { 34 ASSOCIATIVITY_LEFT = 0, 35 ASSOCIATIVITY_RIGHT, 36 37 ASSOCIATIVITY_LAST 38 }; 39 40 template <int Precedence, Associativity Assoc> 41 class BinaryOp : public Expression 42 { 43 public: 44 BinaryOp (Token::Type operatorToken); 45 virtual ~BinaryOp (void); 46 47 Expression* createNextChild (GeneratorState& state); 48 void tokenize (GeneratorState& state, TokenStream& str) const; 49 void evaluate (ExecutionContext& execCtx); 50 ExecConstValueAccess getValue (void) const { return m_value.getValue(m_type); } 51 52 virtual void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b) = DE_NULL; 53 54 protected: 55 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 56 57 Token::Type m_operator; 58 VariableType m_type; 59 ExecValueStorage m_value; 60 61 ValueRange m_leftValueRange; 62 ValueRange m_rightValueRange; 63 64 Expression* m_leftValueExpr; 65 Expression* m_rightValueExpr; 66 }; 67 68 template <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp> 69 class BinaryVecOp : public BinaryOp<Precedence, ASSOCIATIVITY_LEFT> 70 { 71 public: 72 BinaryVecOp (GeneratorState& state, Token::Type operatorToken, ConstValueRangeAccess valueRange); 73 virtual ~BinaryVecOp (void); 74 75 void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); 76 }; 77 78 struct ComputeMulRange 79 { 80 void operator() (de::Random& rnd, float dstMin, float dstMax, float& aMin, float& aMax, float& bMin, float& bMax) const; 81 void operator() (de::Random& rnd, int dstMin, int dstMax, int& aMin, int& aMax, int& bMin, int& bMax) const; 82 void operator() (de::Random&, bool, bool, bool&, bool&, bool&, bool&) const { DE_ASSERT(DE_FALSE); } 83 }; 84 85 struct EvaluateMul 86 { 87 template <typename T> inline T operator() (T a, T b) const { return a*b; } 88 }; 89 90 typedef BinaryVecOp<4, true, true, false, ComputeMulRange, EvaluateMul> MulBase; 91 92 class MulOp : public MulBase 93 { 94 public: 95 MulOp (GeneratorState& state, ConstValueRangeAccess valueRange); 96 virtual ~MulOp (void) {} 97 98 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 99 }; 100 101 struct ComputeAddRange 102 { 103 template <typename T> 104 void operator() (de::Random& rnd, T dstMin, T dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; 105 }; 106 107 struct EvaluateAdd 108 { 109 template <typename T> inline T operator() (T a, T b) const { return a+b; } 110 }; 111 112 typedef BinaryVecOp<5, true, true, false, ComputeAddRange, EvaluateAdd> AddBase; 113 114 class AddOp : public AddBase 115 { 116 public: 117 AddOp (GeneratorState& state, ConstValueRangeAccess valueRange); 118 virtual ~AddOp (void) {} 119 120 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 121 }; 122 123 struct ComputeSubRange 124 { 125 template <typename T> 126 void operator() (de::Random& rnd, T dstMin, T dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; 127 }; 128 129 struct EvaluateSub 130 { 131 template <typename T> inline T operator() (T a, T b) const { return a-b; } 132 }; 133 134 typedef BinaryVecOp<5, true, true, false, ComputeSubRange, EvaluateSub> SubBase; 135 136 class SubOp : public SubBase 137 { 138 public: 139 SubOp (GeneratorState& state, ConstValueRangeAccess valueRange); 140 virtual ~SubOp (void) {} 141 142 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 143 }; 144 145 /* Template for Relational Operators. */ 146 147 template <class ComputeValueRange, class EvaluateComp> 148 class RelationalOp : public BinaryOp<7, ASSOCIATIVITY_LEFT> 149 { 150 public: 151 RelationalOp (GeneratorState& state, Token::Type operatorToken, ConstValueRangeAccess valueRange); 152 virtual ~RelationalOp (void); 153 154 void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); 155 156 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 157 }; 158 159 /* Less Than. */ 160 161 struct ComputeLessThanRange 162 { 163 template <typename T> 164 void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; 165 }; 166 167 struct EvaluateLessThan 168 { 169 template <typename T> inline bool operator() (T a, T b) const { return a < b; } 170 }; 171 172 typedef RelationalOp<ComputeLessThanRange, EvaluateLessThan> LessThanBase; 173 174 class LessThanOp : public LessThanBase 175 { 176 public: 177 LessThanOp (GeneratorState& state, ConstValueRangeAccess valueRange); 178 virtual ~LessThanOp (void) {} 179 180 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 181 }; 182 183 /* Less or Equal. */ 184 185 struct ComputeLessOrEqualRange 186 { 187 template <typename T> 188 void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const; 189 }; 190 191 struct EvaluateLessOrEqual 192 { 193 template <typename T> inline bool operator() (T a, T b) const { return a <= b; } 194 }; 195 196 typedef RelationalOp<ComputeLessOrEqualRange, EvaluateLessOrEqual> LessOrEqualBase; 197 198 class LessOrEqualOp : public LessOrEqualBase 199 { 200 public: 201 LessOrEqualOp (GeneratorState& state, ConstValueRangeAccess valueRange); 202 virtual ~LessOrEqualOp (void) {}; 203 204 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 205 }; 206 207 /* Greater Than. */ 208 209 struct ComputeGreaterThanRange 210 { 211 template <typename T> 212 void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const 213 { 214 ComputeLessThanRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax); 215 } 216 }; 217 218 struct EvaluateGreaterThan 219 { 220 template <typename T> inline bool operator() (T a, T b) const { return a > b; } 221 }; 222 223 typedef RelationalOp<ComputeGreaterThanRange, EvaluateGreaterThan> GreaterThanBase; 224 225 class GreaterThanOp : public GreaterThanBase 226 { 227 public: 228 GreaterThanOp (GeneratorState& state, ConstValueRangeAccess valueRange); 229 virtual ~GreaterThanOp (void) {} 230 231 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 232 }; 233 234 /* Greater or Equal. */ 235 236 struct ComputeGreaterOrEqualRange 237 { 238 template <typename T> 239 void operator() (de::Random& rnd, bool dstMin, bool dstMax, T& aMin, T& aMax, T& bMin, T& bMax) const 240 { 241 ComputeLessOrEqualRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax); 242 } 243 }; 244 245 struct EvaluateGreaterOrEqual 246 { 247 template <typename T> inline bool operator() (T a, T b) const { return a >= b; } 248 }; 249 250 typedef RelationalOp<ComputeGreaterOrEqualRange, EvaluateGreaterOrEqual> GreaterOrEqualBase; 251 252 class GreaterOrEqualOp : public GreaterOrEqualBase 253 { 254 public: 255 GreaterOrEqualOp (GeneratorState& state, ConstValueRangeAccess valueRange); 256 virtual ~GreaterOrEqualOp (void) {}; 257 258 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 259 }; 260 261 /* Equality comparison. */ 262 263 template <bool IsEqual> 264 class EqualityComparisonOp : public BinaryOp<8, ASSOCIATIVITY_LEFT> 265 { 266 public: 267 EqualityComparisonOp (GeneratorState& state, ConstValueRangeAccess valueRange); 268 virtual ~EqualityComparisonOp (void) {} 269 270 void evaluate (ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); 271 272 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 273 }; 274 275 // \note Since template implementation is in .cpp we have to reference specialized constructor and static functions from there. 276 class EqualOp : public EqualityComparisonOp<true> 277 { 278 public: 279 EqualOp (GeneratorState& state, ConstValueRangeAccess valueRange); 280 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 281 }; 282 283 class NotEqualOp : public EqualityComparisonOp<false> 284 { 285 public: 286 NotEqualOp (GeneratorState& state, ConstValueRangeAccess valueRange); 287 static float getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); 288 }; 289 290 } // rsg 291 292 #endif // _RSGBINARYOPS_HPP 293