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); getValue(void) const50 ExecConstValueAccess getValue(void) const 51 { 52 return m_value.getValue(m_type); 53 } 54 55 virtual void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b) = DE_NULL; 56 57 protected: 58 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 59 60 Token::Type m_operator; 61 VariableType m_type; 62 ExecValueStorage m_value; 63 64 ValueRange m_leftValueRange; 65 ValueRange m_rightValueRange; 66 67 Expression *m_leftValueExpr; 68 Expression *m_rightValueExpr; 69 }; 70 71 template <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp> 72 class BinaryVecOp : public BinaryOp<Precedence, ASSOCIATIVITY_LEFT> 73 { 74 public: 75 BinaryVecOp(GeneratorState &state, Token::Type operatorToken, ConstValueRangeAccess valueRange); 76 virtual ~BinaryVecOp(void); 77 78 void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); 79 }; 80 81 struct ComputeMulRange 82 { 83 void operator()(de::Random &rnd, float dstMin, float dstMax, float &aMin, float &aMax, float &bMin, 84 float &bMax) const; 85 void operator()(de::Random &rnd, int dstMin, int dstMax, int &aMin, int &aMax, int &bMin, int &bMax) const; operator ()rsg::ComputeMulRange86 void operator()(de::Random &, bool, bool, bool &, bool &, bool &, bool &) const 87 { 88 DE_ASSERT(false); 89 } 90 }; 91 92 struct EvaluateMul 93 { 94 template <typename T> operator ()rsg::EvaluateMul95 inline T operator()(T a, T b) const 96 { 97 return a * b; 98 } 99 }; 100 101 typedef BinaryVecOp<4, true, true, false, ComputeMulRange, EvaluateMul> MulBase; 102 103 class MulOp : public MulBase 104 { 105 public: 106 MulOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~MulOp(void)107 virtual ~MulOp(void) 108 { 109 } 110 111 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 112 }; 113 114 struct ComputeAddRange 115 { 116 template <typename T> 117 void operator()(de::Random &rnd, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; 118 }; 119 120 struct EvaluateAdd 121 { 122 template <typename T> operator ()rsg::EvaluateAdd123 inline T operator()(T a, T b) const 124 { 125 return a + b; 126 } 127 }; 128 129 typedef BinaryVecOp<5, true, true, false, ComputeAddRange, EvaluateAdd> AddBase; 130 131 class AddOp : public AddBase 132 { 133 public: 134 AddOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~AddOp(void)135 virtual ~AddOp(void) 136 { 137 } 138 139 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 140 }; 141 142 struct ComputeSubRange 143 { 144 template <typename T> 145 void operator()(de::Random &rnd, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; 146 }; 147 148 struct EvaluateSub 149 { 150 template <typename T> operator ()rsg::EvaluateSub151 inline T operator()(T a, T b) const 152 { 153 return a - b; 154 } 155 }; 156 157 typedef BinaryVecOp<5, true, true, false, ComputeSubRange, EvaluateSub> SubBase; 158 159 class SubOp : public SubBase 160 { 161 public: 162 SubOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~SubOp(void)163 virtual ~SubOp(void) 164 { 165 } 166 167 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 168 }; 169 170 /* Template for Relational Operators. */ 171 172 template <class ComputeValueRange, class EvaluateComp> 173 class RelationalOp : public BinaryOp<7, ASSOCIATIVITY_LEFT> 174 { 175 public: 176 RelationalOp(GeneratorState &state, Token::Type operatorToken, ConstValueRangeAccess valueRange); 177 virtual ~RelationalOp(void); 178 179 void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); 180 181 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 182 }; 183 184 /* Less Than. */ 185 186 struct ComputeLessThanRange 187 { 188 template <typename T> 189 void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; 190 }; 191 192 struct EvaluateLessThan 193 { 194 template <typename T> operator ()rsg::EvaluateLessThan195 inline bool operator()(T a, T b) const 196 { 197 return a < b; 198 } 199 }; 200 201 typedef RelationalOp<ComputeLessThanRange, EvaluateLessThan> LessThanBase; 202 203 class LessThanOp : public LessThanBase 204 { 205 public: 206 LessThanOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~LessThanOp(void)207 virtual ~LessThanOp(void) 208 { 209 } 210 211 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 212 }; 213 214 /* Less or Equal. */ 215 216 struct ComputeLessOrEqualRange 217 { 218 template <typename T> 219 void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const; 220 }; 221 222 struct EvaluateLessOrEqual 223 { 224 template <typename T> operator ()rsg::EvaluateLessOrEqual225 inline bool operator()(T a, T b) const 226 { 227 return a <= b; 228 } 229 }; 230 231 typedef RelationalOp<ComputeLessOrEqualRange, EvaluateLessOrEqual> LessOrEqualBase; 232 233 class LessOrEqualOp : public LessOrEqualBase 234 { 235 public: 236 LessOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~LessOrEqualOp(void)237 virtual ~LessOrEqualOp(void) 238 { 239 } 240 241 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 242 }; 243 244 /* Greater Than. */ 245 246 struct ComputeGreaterThanRange 247 { 248 template <typename T> operator ()rsg::ComputeGreaterThanRange249 void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const 250 { 251 ComputeLessThanRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax); 252 } 253 }; 254 255 struct EvaluateGreaterThan 256 { 257 template <typename T> operator ()rsg::EvaluateGreaterThan258 inline bool operator()(T a, T b) const 259 { 260 return a > b; 261 } 262 }; 263 264 typedef RelationalOp<ComputeGreaterThanRange, EvaluateGreaterThan> GreaterThanBase; 265 266 class GreaterThanOp : public GreaterThanBase 267 { 268 public: 269 GreaterThanOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~GreaterThanOp(void)270 virtual ~GreaterThanOp(void) 271 { 272 } 273 274 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 275 }; 276 277 /* Greater or Equal. */ 278 279 struct ComputeGreaterOrEqualRange 280 { 281 template <typename T> operator ()rsg::ComputeGreaterOrEqualRange282 void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const 283 { 284 ComputeLessOrEqualRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax); 285 } 286 }; 287 288 struct EvaluateGreaterOrEqual 289 { 290 template <typename T> operator ()rsg::EvaluateGreaterOrEqual291 inline bool operator()(T a, T b) const 292 { 293 return a >= b; 294 } 295 }; 296 297 typedef RelationalOp<ComputeGreaterOrEqualRange, EvaluateGreaterOrEqual> GreaterOrEqualBase; 298 299 class GreaterOrEqualOp : public GreaterOrEqualBase 300 { 301 public: 302 GreaterOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~GreaterOrEqualOp(void)303 virtual ~GreaterOrEqualOp(void) 304 { 305 } 306 307 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 308 }; 309 310 /* Equality comparison. */ 311 312 template <bool IsEqual> 313 class EqualityComparisonOp : public BinaryOp<8, ASSOCIATIVITY_LEFT> 314 { 315 public: 316 EqualityComparisonOp(GeneratorState &state, ConstValueRangeAccess valueRange); ~EqualityComparisonOp(void)317 virtual ~EqualityComparisonOp(void) 318 { 319 } 320 321 void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b); 322 323 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 324 }; 325 326 // \note Since template implementation is in .cpp we have to reference specialized constructor and static functions from there. 327 class EqualOp : public EqualityComparisonOp<true> 328 { 329 public: 330 EqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); 331 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 332 }; 333 334 class NotEqualOp : public EqualityComparisonOp<false> 335 { 336 public: 337 NotEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange); 338 static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); 339 }; 340 341 } // namespace rsg 342 343 #endif // _RSGBINARYOPS_HPP 344