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 { 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;
operator ()rsg::ComputeMulRange82 	void operator() (de::Random&, bool, bool, bool&, bool&, bool&, bool&) const { DE_ASSERT(DE_FALSE); }
83 };
84 
85 struct EvaluateMul
86 {
operator ()rsg::EvaluateMul87 	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);
~MulOp(void)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 {
operator ()rsg::EvaluateAdd109 	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);
~AddOp(void)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 {
operator ()rsg::EvaluateSub131 	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);
~SubOp(void)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 {
operator ()rsg::EvaluateLessThan169 	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);
~LessThanOp(void)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 {
operator ()rsg::EvaluateLessOrEqual193 	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);
~LessOrEqualOp(void)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>
operator ()rsg::ComputeGreaterThanRange212 	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 {
operator ()rsg::EvaluateGreaterThan220 	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);
~GreaterThanOp(void)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>
operator ()rsg::ComputeGreaterOrEqualRange239 	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 {
operator ()rsg::EvaluateGreaterOrEqual247 	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);
~GreaterOrEqualOp(void)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);
~EqualityComparisonOp(void)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