xref: /aosp_15_r20/external/deqp/framework/randomshaders/rsgBinaryOps.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Random Shader Generator
3*35238bceSAndroid Build Coastguard Worker  * ----------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Binary ops.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "rsgBinaryOps.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "rsgVariableManager.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "rsgUtils.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker using std::vector;
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker namespace rsg
32*35238bceSAndroid Build Coastguard Worker {
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker // CustomAbsOp and CustomBinaryOp are used to resolve float comparision corner case.
35*35238bceSAndroid Build Coastguard Worker // This error happened when two floats with the same value were compared
36*35238bceSAndroid Build Coastguard Worker // without using epsilon. If result of this comparisment influenced the
37*35238bceSAndroid Build Coastguard Worker // output color then result and reference images could differ.
38*35238bceSAndroid Build Coastguard Worker class CustomAbsOp : public Expression
39*35238bceSAndroid Build Coastguard Worker {
40*35238bceSAndroid Build Coastguard Worker public:
41*35238bceSAndroid Build Coastguard Worker     CustomAbsOp(void);
42*35238bceSAndroid Build Coastguard Worker     virtual ~CustomAbsOp(void);
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker     void setChild(Expression *expression);
45*35238bceSAndroid Build Coastguard Worker     Expression *createNextChild(GeneratorState &state);
46*35238bceSAndroid Build Coastguard Worker     void tokenize(GeneratorState &state, TokenStream &str) const;
47*35238bceSAndroid Build Coastguard Worker 
48*35238bceSAndroid Build Coastguard Worker     void evaluate(ExecutionContext &execCtx);
getValue(void) const49*35238bceSAndroid Build Coastguard Worker     ExecConstValueAccess getValue(void) const
50*35238bceSAndroid Build Coastguard Worker     {
51*35238bceSAndroid Build Coastguard Worker         return m_value.getValue(m_type);
52*35238bceSAndroid Build Coastguard Worker     }
53*35238bceSAndroid Build Coastguard Worker 
54*35238bceSAndroid Build Coastguard Worker private:
55*35238bceSAndroid Build Coastguard Worker     std::string m_function;
56*35238bceSAndroid Build Coastguard Worker     VariableType m_type;
57*35238bceSAndroid Build Coastguard Worker     ExecValueStorage m_value;
58*35238bceSAndroid Build Coastguard Worker     Expression *m_child;
59*35238bceSAndroid Build Coastguard Worker };
60*35238bceSAndroid Build Coastguard Worker 
CustomAbsOp(void)61*35238bceSAndroid Build Coastguard Worker CustomAbsOp::CustomAbsOp(void) : m_function("abs"), m_type(VariableType::TYPE_FLOAT, 1), m_child(DE_NULL)
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker     m_value.setStorage(m_type);
64*35238bceSAndroid Build Coastguard Worker }
65*35238bceSAndroid Build Coastguard Worker 
~CustomAbsOp(void)66*35238bceSAndroid Build Coastguard Worker CustomAbsOp::~CustomAbsOp(void)
67*35238bceSAndroid Build Coastguard Worker {
68*35238bceSAndroid Build Coastguard Worker     delete m_child;
69*35238bceSAndroid Build Coastguard Worker }
70*35238bceSAndroid Build Coastguard Worker 
setChild(Expression * expression)71*35238bceSAndroid Build Coastguard Worker void CustomAbsOp::setChild(Expression *expression)
72*35238bceSAndroid Build Coastguard Worker {
73*35238bceSAndroid Build Coastguard Worker     m_child = expression;
74*35238bceSAndroid Build Coastguard Worker }
75*35238bceSAndroid Build Coastguard Worker 
createNextChild(GeneratorState &)76*35238bceSAndroid Build Coastguard Worker Expression *CustomAbsOp::createNextChild(GeneratorState &)
77*35238bceSAndroid Build Coastguard Worker {
78*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(0);
79*35238bceSAndroid Build Coastguard Worker     return DE_NULL;
80*35238bceSAndroid Build Coastguard Worker }
81*35238bceSAndroid Build Coastguard Worker 
tokenize(GeneratorState & state,TokenStream & str) const82*35238bceSAndroid Build Coastguard Worker void CustomAbsOp::tokenize(GeneratorState &state, TokenStream &str) const
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker     str << Token(m_function.c_str()) << Token::LEFT_PAREN;
85*35238bceSAndroid Build Coastguard Worker     m_child->tokenize(state, str);
86*35238bceSAndroid Build Coastguard Worker     str << Token::RIGHT_PAREN;
87*35238bceSAndroid Build Coastguard Worker }
88*35238bceSAndroid Build Coastguard Worker 
evaluate(ExecutionContext & execCtx)89*35238bceSAndroid Build Coastguard Worker void CustomAbsOp::evaluate(ExecutionContext &execCtx)
90*35238bceSAndroid Build Coastguard Worker {
91*35238bceSAndroid Build Coastguard Worker     m_child->evaluate(execCtx);
92*35238bceSAndroid Build Coastguard Worker 
93*35238bceSAndroid Build Coastguard Worker     ExecConstValueAccess srcValue = m_child->getValue();
94*35238bceSAndroid Build Coastguard Worker     ExecValueAccess dstValue      = m_value.getValue(m_type);
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < m_type.getNumElements(); elemNdx++)
97*35238bceSAndroid Build Coastguard Worker     {
98*35238bceSAndroid Build Coastguard Worker         ExecConstValueAccess srcComp = srcValue.component(elemNdx);
99*35238bceSAndroid Build Coastguard Worker         ExecValueAccess dstComp      = dstValue.component(elemNdx);
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
102*35238bceSAndroid Build Coastguard Worker             dstComp.asFloat(compNdx) = deFloatAbs(srcComp.asFloat(compNdx));
103*35238bceSAndroid Build Coastguard Worker     }
104*35238bceSAndroid Build Coastguard Worker }
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker typedef BinaryOp<5, ASSOCIATIVITY_LEFT> CustomBinaryBase;
107*35238bceSAndroid Build Coastguard Worker 
108*35238bceSAndroid Build Coastguard Worker // CustomBinaryOp and CustomAbsOp are used to resolve float comparision corner case.
109*35238bceSAndroid Build Coastguard Worker // CustomBinaryOp supports addition and substraction as only those functionalities
110*35238bceSAndroid Build Coastguard Worker // were needed.
111*35238bceSAndroid Build Coastguard Worker template <typename ComputeValue>
112*35238bceSAndroid Build Coastguard Worker class CustomBinaryOp : public CustomBinaryBase
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker public:
115*35238bceSAndroid Build Coastguard Worker     CustomBinaryOp();
~CustomBinaryOp(void)116*35238bceSAndroid Build Coastguard Worker     virtual ~CustomBinaryOp(void)
117*35238bceSAndroid Build Coastguard Worker     {
118*35238bceSAndroid Build Coastguard Worker     }
119*35238bceSAndroid Build Coastguard Worker 
120*35238bceSAndroid Build Coastguard Worker     void setLeftValue(Expression *expression);
121*35238bceSAndroid Build Coastguard Worker     void setRightValue(Expression *expression);
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker     void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b);
124*35238bceSAndroid Build Coastguard Worker };
125*35238bceSAndroid Build Coastguard Worker 
126*35238bceSAndroid Build Coastguard Worker template <typename ComputeValue>
CustomBinaryOp()127*35238bceSAndroid Build Coastguard Worker CustomBinaryOp<ComputeValue>::CustomBinaryOp() : CustomBinaryBase(Token::PLUS)
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker     // By default add operation is assumed, for every other operation
130*35238bceSAndroid Build Coastguard Worker     // separate constructor specialization should be implemented
131*35238bceSAndroid Build Coastguard Worker     m_type = VariableType(VariableType::TYPE_FLOAT, 1);
132*35238bceSAndroid Build Coastguard Worker     m_value.setStorage(m_type);
133*35238bceSAndroid Build Coastguard Worker }
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker template <>
CustomBinaryOp()136*35238bceSAndroid Build Coastguard Worker CustomBinaryOp<EvaluateSub>::CustomBinaryOp() : CustomBinaryBase(Token::MINUS)
137*35238bceSAndroid Build Coastguard Worker {
138*35238bceSAndroid Build Coastguard Worker     // Specialization for substraction
139*35238bceSAndroid Build Coastguard Worker     m_type            = VariableType(VariableType::TYPE_FLOAT, 1);
140*35238bceSAndroid Build Coastguard Worker     m_leftValueRange  = ValueRange(m_type);
141*35238bceSAndroid Build Coastguard Worker     m_rightValueRange = ValueRange(m_type);
142*35238bceSAndroid Build Coastguard Worker     m_value.setStorage(m_type);
143*35238bceSAndroid Build Coastguard Worker }
144*35238bceSAndroid Build Coastguard Worker 
145*35238bceSAndroid Build Coastguard Worker template <>
CustomBinaryOp()146*35238bceSAndroid Build Coastguard Worker CustomBinaryOp<EvaluateLessThan>::CustomBinaryOp() : CustomBinaryBase(Token::CMP_LT)
147*35238bceSAndroid Build Coastguard Worker {
148*35238bceSAndroid Build Coastguard Worker     // Specialization for less_then comparision
149*35238bceSAndroid Build Coastguard Worker     m_type                 = VariableType(VariableType::TYPE_BOOL, 1);
150*35238bceSAndroid Build Coastguard Worker     VariableType floatType = VariableType(VariableType::TYPE_FLOAT, 1);
151*35238bceSAndroid Build Coastguard Worker     m_leftValueRange       = ValueRange(floatType);
152*35238bceSAndroid Build Coastguard Worker     m_rightValueRange      = ValueRange(floatType);
153*35238bceSAndroid Build Coastguard Worker     m_value.setStorage(m_type);
154*35238bceSAndroid Build Coastguard Worker }
155*35238bceSAndroid Build Coastguard Worker 
156*35238bceSAndroid Build Coastguard Worker template <typename ComputeValue>
setLeftValue(Expression * expression)157*35238bceSAndroid Build Coastguard Worker void CustomBinaryOp<ComputeValue>::setLeftValue(Expression *expression)
158*35238bceSAndroid Build Coastguard Worker {
159*35238bceSAndroid Build Coastguard Worker     m_leftValueExpr = expression;
160*35238bceSAndroid Build Coastguard Worker }
161*35238bceSAndroid Build Coastguard Worker 
162*35238bceSAndroid Build Coastguard Worker template <typename ComputeValue>
setRightValue(Expression * expression)163*35238bceSAndroid Build Coastguard Worker void CustomBinaryOp<ComputeValue>::setRightValue(Expression *expression)
164*35238bceSAndroid Build Coastguard Worker {
165*35238bceSAndroid Build Coastguard Worker     m_rightValueExpr = expression;
166*35238bceSAndroid Build Coastguard Worker }
167*35238bceSAndroid Build Coastguard Worker 
168*35238bceSAndroid Build Coastguard Worker template <typename ComputeValue>
evaluate(ExecValueAccess dst,ExecConstValueAccess a,ExecConstValueAccess b)169*35238bceSAndroid Build Coastguard Worker void CustomBinaryOp<ComputeValue>::evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b)
170*35238bceSAndroid Build Coastguard Worker {
171*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getType() == a.getType());
172*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getType() == b.getType());
173*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getType().getBaseType() == VariableType::TYPE_FLOAT);
174*35238bceSAndroid Build Coastguard Worker 
175*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < dst.getType().getNumElements(); elemNdx++)
176*35238bceSAndroid Build Coastguard Worker     {
177*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
178*35238bceSAndroid Build Coastguard Worker             dst.component(elemNdx).asFloat(compNdx) =
179*35238bceSAndroid Build Coastguard Worker                 ComputeValue()(a.component(elemNdx).asFloat(compNdx), b.component(elemNdx).asFloat(compNdx));
180*35238bceSAndroid Build Coastguard Worker     }
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker 
183*35238bceSAndroid Build Coastguard Worker template <>
evaluate(ExecValueAccess dst,ExecConstValueAccess a,ExecConstValueAccess b)184*35238bceSAndroid Build Coastguard Worker void CustomBinaryOp<EvaluateLessThan>::evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b)
185*35238bceSAndroid Build Coastguard Worker {
186*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(a.getType() == b.getType());
187*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getType().getBaseType() == VariableType::TYPE_BOOL);
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < dst.getType().getNumElements(); elemNdx++)
190*35238bceSAndroid Build Coastguard Worker     {
191*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
192*35238bceSAndroid Build Coastguard Worker             dst.component(elemNdx).asBool(compNdx) =
193*35238bceSAndroid Build Coastguard Worker                 EvaluateLessThan()(a.component(elemNdx).asFloat(compNdx), b.component(elemNdx).asFloat(compNdx));
194*35238bceSAndroid Build Coastguard Worker     }
195*35238bceSAndroid Build Coastguard Worker }
196*35238bceSAndroid Build Coastguard Worker 
197*35238bceSAndroid Build Coastguard Worker template <int Precedence, Associativity Assoc>
BinaryOp(Token::Type operatorToken)198*35238bceSAndroid Build Coastguard Worker BinaryOp<Precedence, Assoc>::BinaryOp(Token::Type operatorToken)
199*35238bceSAndroid Build Coastguard Worker     : m_operator(operatorToken)
200*35238bceSAndroid Build Coastguard Worker     , m_leftValueRange(m_type)
201*35238bceSAndroid Build Coastguard Worker     , m_rightValueRange(m_type)
202*35238bceSAndroid Build Coastguard Worker     , m_leftValueExpr(DE_NULL)
203*35238bceSAndroid Build Coastguard Worker     , m_rightValueExpr(DE_NULL)
204*35238bceSAndroid Build Coastguard Worker {
205*35238bceSAndroid Build Coastguard Worker }
206*35238bceSAndroid Build Coastguard Worker 
207*35238bceSAndroid Build Coastguard Worker template <int Precedence, Associativity Assoc>
~BinaryOp(void)208*35238bceSAndroid Build Coastguard Worker BinaryOp<Precedence, Assoc>::~BinaryOp(void)
209*35238bceSAndroid Build Coastguard Worker {
210*35238bceSAndroid Build Coastguard Worker     delete m_leftValueExpr;
211*35238bceSAndroid Build Coastguard Worker     delete m_rightValueExpr;
212*35238bceSAndroid Build Coastguard Worker }
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker template <int Precedence, Associativity Assoc>
createNextChild(GeneratorState & state)215*35238bceSAndroid Build Coastguard Worker Expression *BinaryOp<Precedence, Assoc>::createNextChild(GeneratorState &state)
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker     int leftPrec  = Assoc == ASSOCIATIVITY_LEFT ? Precedence : Precedence - 1;
218*35238bceSAndroid Build Coastguard Worker     int rightPrec = Assoc == ASSOCIATIVITY_LEFT ? Precedence - 1 : Precedence;
219*35238bceSAndroid Build Coastguard Worker 
220*35238bceSAndroid Build Coastguard Worker     if (m_rightValueExpr == DE_NULL)
221*35238bceSAndroid Build Coastguard Worker     {
222*35238bceSAndroid Build Coastguard Worker         state.pushPrecedence(rightPrec);
223*35238bceSAndroid Build Coastguard Worker         m_rightValueExpr = Expression::createRandom(state, m_rightValueRange.asAccess());
224*35238bceSAndroid Build Coastguard Worker         state.popPrecedence();
225*35238bceSAndroid Build Coastguard Worker         return m_rightValueExpr;
226*35238bceSAndroid Build Coastguard Worker     }
227*35238bceSAndroid Build Coastguard Worker     else if (m_leftValueExpr == DE_NULL)
228*35238bceSAndroid Build Coastguard Worker     {
229*35238bceSAndroid Build Coastguard Worker         state.pushPrecedence(leftPrec);
230*35238bceSAndroid Build Coastguard Worker         m_leftValueExpr = Expression::createRandom(state, m_leftValueRange.asAccess());
231*35238bceSAndroid Build Coastguard Worker         state.popPrecedence();
232*35238bceSAndroid Build Coastguard Worker         return m_leftValueExpr;
233*35238bceSAndroid Build Coastguard Worker     }
234*35238bceSAndroid Build Coastguard Worker     else
235*35238bceSAndroid Build Coastguard Worker     {
236*35238bceSAndroid Build Coastguard Worker         // Check for corrner cases
237*35238bceSAndroid Build Coastguard Worker         switch (m_operator)
238*35238bceSAndroid Build Coastguard Worker         {
239*35238bceSAndroid Build Coastguard Worker         case Token::CMP_LE:
240*35238bceSAndroid Build Coastguard Worker         {
241*35238bceSAndroid Build Coastguard Worker             // When comparing two floats epsilon should be included
242*35238bceSAndroid Build Coastguard Worker             // to eliminate the risk that we get different results
243*35238bceSAndroid Build Coastguard Worker             // because of precission error
244*35238bceSAndroid Build Coastguard Worker             VariableType floatType(VariableType::TYPE_FLOAT, 1);
245*35238bceSAndroid Build Coastguard Worker             if (m_rightValueRange.getType() == floatType)
246*35238bceSAndroid Build Coastguard Worker             {
247*35238bceSAndroid Build Coastguard Worker                 FloatLiteral *epsilonLiteral = new FloatLiteral(0.001f);
248*35238bceSAndroid Build Coastguard Worker 
249*35238bceSAndroid Build Coastguard Worker                 typedef CustomBinaryOp<EvaluateAdd> CustomAddOp;
250*35238bceSAndroid Build Coastguard Worker                 CustomAddOp *addOperation = new CustomAddOp();
251*35238bceSAndroid Build Coastguard Worker                 addOperation->setLeftValue(m_rightValueExpr);
252*35238bceSAndroid Build Coastguard Worker                 addOperation->setRightValue(epsilonLiteral);
253*35238bceSAndroid Build Coastguard Worker 
254*35238bceSAndroid Build Coastguard Worker                 // add epsilon to right-hand side
255*35238bceSAndroid Build Coastguard Worker                 m_rightValueExpr = addOperation;
256*35238bceSAndroid Build Coastguard Worker             }
257*35238bceSAndroid Build Coastguard Worker             break;
258*35238bceSAndroid Build Coastguard Worker         }
259*35238bceSAndroid Build Coastguard Worker         case Token::CMP_GE:
260*35238bceSAndroid Build Coastguard Worker         {
261*35238bceSAndroid Build Coastguard Worker             // When comparing two floats epsilon should be included
262*35238bceSAndroid Build Coastguard Worker             // to eliminate the risk that we get different results
263*35238bceSAndroid Build Coastguard Worker             // because of precission error
264*35238bceSAndroid Build Coastguard Worker             VariableType floatType(VariableType::TYPE_FLOAT, 1);
265*35238bceSAndroid Build Coastguard Worker             if (m_leftValueRange.getType() == floatType)
266*35238bceSAndroid Build Coastguard Worker             {
267*35238bceSAndroid Build Coastguard Worker                 FloatLiteral *epsilonLiteral = new FloatLiteral(0.001f);
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker                 typedef CustomBinaryOp<EvaluateAdd> CustomAddOp;
270*35238bceSAndroid Build Coastguard Worker                 CustomAddOp *addOperation = new CustomAddOp();
271*35238bceSAndroid Build Coastguard Worker                 addOperation->setLeftValue(m_leftValueExpr);
272*35238bceSAndroid Build Coastguard Worker                 addOperation->setRightValue(epsilonLiteral);
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker                 // add epsilon to left-hand side
275*35238bceSAndroid Build Coastguard Worker                 m_leftValueExpr = addOperation;
276*35238bceSAndroid Build Coastguard Worker             }
277*35238bceSAndroid Build Coastguard Worker             break;
278*35238bceSAndroid Build Coastguard Worker         }
279*35238bceSAndroid Build Coastguard Worker         case Token::CMP_EQ:
280*35238bceSAndroid Build Coastguard Worker         {
281*35238bceSAndroid Build Coastguard Worker             // When comparing two floats epsilon should be included
282*35238bceSAndroid Build Coastguard Worker             // to eliminate the risk that we get different results
283*35238bceSAndroid Build Coastguard Worker             // because of precission error
284*35238bceSAndroid Build Coastguard Worker             VariableType floatType(VariableType::TYPE_FLOAT, 1);
285*35238bceSAndroid Build Coastguard Worker             if (m_leftValueRange.getType() == floatType)
286*35238bceSAndroid Build Coastguard Worker             {
287*35238bceSAndroid Build Coastguard Worker                 VariableType boolType(VariableType::TYPE_BOOL, 1);
288*35238bceSAndroid Build Coastguard Worker                 const ValueRange boolRange(boolType);
289*35238bceSAndroid Build Coastguard Worker 
290*35238bceSAndroid Build Coastguard Worker                 ParenOp *parenRight = new ParenOp(state, boolRange);
291*35238bceSAndroid Build Coastguard Worker                 parenRight->setChild(m_rightValueExpr);
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker                 typedef CustomBinaryOp<EvaluateSub> CustomSubOp;
294*35238bceSAndroid Build Coastguard Worker                 CustomSubOp *subOperation = new CustomSubOp();
295*35238bceSAndroid Build Coastguard Worker                 subOperation->setLeftValue(m_leftValueExpr);
296*35238bceSAndroid Build Coastguard Worker                 subOperation->setRightValue(parenRight);
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker                 CustomAbsOp *absOperation = new CustomAbsOp();
299*35238bceSAndroid Build Coastguard Worker                 absOperation->setChild(subOperation);
300*35238bceSAndroid Build Coastguard Worker                 FloatLiteral *epsilonLiteral = new FloatLiteral(0.001f);
301*35238bceSAndroid Build Coastguard Worker 
302*35238bceSAndroid Build Coastguard Worker                 typedef CustomBinaryOp<EvaluateLessThan> CustomLessThanOp;
303*35238bceSAndroid Build Coastguard Worker                 CustomLessThanOp *lessOperation = new CustomLessThanOp();
304*35238bceSAndroid Build Coastguard Worker                 lessOperation->setLeftValue(absOperation);
305*35238bceSAndroid Build Coastguard Worker                 lessOperation->setRightValue(epsilonLiteral);
306*35238bceSAndroid Build Coastguard Worker 
307*35238bceSAndroid Build Coastguard Worker                 ParenOp *parenOperation = new ParenOp(state, boolRange);
308*35238bceSAndroid Build Coastguard Worker                 parenOperation->setChild(lessOperation);
309*35238bceSAndroid Build Coastguard Worker                 BoolLiteral *trueLiteral = new BoolLiteral(true);
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker                 // EQ operation cant be removed so it is replaced with:
312*35238bceSAndroid Build Coastguard Worker                 // ((abs(lhs-rhs) < epsilon) == true).
313*35238bceSAndroid Build Coastguard Worker                 m_leftValueExpr  = parenOperation;
314*35238bceSAndroid Build Coastguard Worker                 m_rightValueExpr = trueLiteral;
315*35238bceSAndroid Build Coastguard Worker             }
316*35238bceSAndroid Build Coastguard Worker             break;
317*35238bceSAndroid Build Coastguard Worker         }
318*35238bceSAndroid Build Coastguard Worker         default:
319*35238bceSAndroid Build Coastguard Worker             break;
320*35238bceSAndroid Build Coastguard Worker         }
321*35238bceSAndroid Build Coastguard Worker 
322*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
323*35238bceSAndroid Build Coastguard Worker     }
324*35238bceSAndroid Build Coastguard Worker }
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker template <int Precedence, Associativity Assoc>
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)327*35238bceSAndroid Build Coastguard Worker float BinaryOp<Precedence, Assoc>::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
328*35238bceSAndroid Build Coastguard Worker {
329*35238bceSAndroid Build Coastguard Worker     if (state.getPrecedence() < Precedence)
330*35238bceSAndroid Build Coastguard Worker         return 0.0f;
331*35238bceSAndroid Build Coastguard Worker 
332*35238bceSAndroid Build Coastguard Worker     int availableLevels = state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid())
335*35238bceSAndroid Build Coastguard Worker         return availableLevels >= 2 ? unusedValueWeight : 0.0f;
336*35238bceSAndroid Build Coastguard Worker 
337*35238bceSAndroid Build Coastguard Worker     if (availableLevels < getConservativeValueExprDepth(state, valueRange) + 1)
338*35238bceSAndroid Build Coastguard Worker         return 0.0f;
339*35238bceSAndroid Build Coastguard Worker 
340*35238bceSAndroid Build Coastguard Worker     return 1.0f;
341*35238bceSAndroid Build Coastguard Worker }
342*35238bceSAndroid Build Coastguard Worker 
343*35238bceSAndroid Build Coastguard Worker template <int Precedence, Associativity Assoc>
tokenize(GeneratorState & state,TokenStream & str) const344*35238bceSAndroid Build Coastguard Worker void BinaryOp<Precedence, Assoc>::tokenize(GeneratorState &state, TokenStream &str) const
345*35238bceSAndroid Build Coastguard Worker {
346*35238bceSAndroid Build Coastguard Worker     m_leftValueExpr->tokenize(state, str);
347*35238bceSAndroid Build Coastguard Worker     str << m_operator;
348*35238bceSAndroid Build Coastguard Worker     m_rightValueExpr->tokenize(state, str);
349*35238bceSAndroid Build Coastguard Worker }
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker template <int Precedence, Associativity Assoc>
evaluate(ExecutionContext & execCtx)352*35238bceSAndroid Build Coastguard Worker void BinaryOp<Precedence, Assoc>::evaluate(ExecutionContext &execCtx)
353*35238bceSAndroid Build Coastguard Worker {
354*35238bceSAndroid Build Coastguard Worker     m_leftValueExpr->evaluate(execCtx);
355*35238bceSAndroid Build Coastguard Worker     m_rightValueExpr->evaluate(execCtx);
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker     ExecConstValueAccess leftVal  = m_leftValueExpr->getValue();
358*35238bceSAndroid Build Coastguard Worker     ExecConstValueAccess rightVal = m_rightValueExpr->getValue();
359*35238bceSAndroid Build Coastguard Worker     ExecValueAccess dst           = m_value.getValue(m_type);
360*35238bceSAndroid Build Coastguard Worker 
361*35238bceSAndroid Build Coastguard Worker     evaluate(dst, leftVal, rightVal);
362*35238bceSAndroid Build Coastguard Worker }
363*35238bceSAndroid Build Coastguard Worker 
364*35238bceSAndroid Build Coastguard Worker template <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp>
BinaryVecOp(GeneratorState & state,Token::Type operatorToken,ConstValueRangeAccess inValueRange)365*35238bceSAndroid Build Coastguard Worker BinaryVecOp<Precedence, Float, Int, Bool, ComputeValueRange, EvaluateComp>::BinaryVecOp(
366*35238bceSAndroid Build Coastguard Worker     GeneratorState &state, Token::Type operatorToken, ConstValueRangeAccess inValueRange)
367*35238bceSAndroid Build Coastguard Worker     : BinaryOp<Precedence, ASSOCIATIVITY_LEFT>(operatorToken)
368*35238bceSAndroid Build Coastguard Worker {
369*35238bceSAndroid Build Coastguard Worker     ValueRange valueRange = inValueRange;
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid())
372*35238bceSAndroid Build Coastguard Worker     {
373*35238bceSAndroid Build Coastguard Worker         int availableLevels = state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
374*35238bceSAndroid Build Coastguard Worker         vector<VariableType::Type> baseTypes;
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker         if (Float)
377*35238bceSAndroid Build Coastguard Worker             baseTypes.push_back(VariableType::TYPE_FLOAT);
378*35238bceSAndroid Build Coastguard Worker         if (Int)
379*35238bceSAndroid Build Coastguard Worker             baseTypes.push_back(VariableType::TYPE_INT);
380*35238bceSAndroid Build Coastguard Worker         if (Bool)
381*35238bceSAndroid Build Coastguard Worker             baseTypes.push_back(VariableType::TYPE_BOOL);
382*35238bceSAndroid Build Coastguard Worker 
383*35238bceSAndroid Build Coastguard Worker         VariableType::Type baseType = state.getRandom().choose<VariableType::Type>(baseTypes.begin(), baseTypes.end());
384*35238bceSAndroid Build Coastguard Worker         int numElements             = state.getRandom().getInt(1, availableLevels >= 3 ? 4 : 1);
385*35238bceSAndroid Build Coastguard Worker 
386*35238bceSAndroid Build Coastguard Worker         valueRange = ValueRange(VariableType(baseType, numElements));
387*35238bceSAndroid Build Coastguard Worker         computeRandomValueRange(state, valueRange.asAccess());
388*35238bceSAndroid Build Coastguard Worker     }
389*35238bceSAndroid Build Coastguard Worker 
390*35238bceSAndroid Build Coastguard Worker     // Choose type, allocate storage for execution
391*35238bceSAndroid Build Coastguard Worker     this->m_type = valueRange.getType();
392*35238bceSAndroid Build Coastguard Worker     this->m_value.setStorage(this->m_type);
393*35238bceSAndroid Build Coastguard Worker 
394*35238bceSAndroid Build Coastguard Worker     // Initialize storage for value ranges
395*35238bceSAndroid Build Coastguard Worker     this->m_rightValueRange = ValueRange(this->m_type);
396*35238bceSAndroid Build Coastguard Worker     this->m_leftValueRange  = ValueRange(this->m_type);
397*35238bceSAndroid Build Coastguard Worker 
398*35238bceSAndroid Build Coastguard Worker     VariableType::Type baseType = this->m_type.getBaseType();
399*35238bceSAndroid Build Coastguard Worker 
400*35238bceSAndroid Build Coastguard Worker     // Compute range for b that satisfies requested value range
401*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < this->m_type.getNumElements(); elemNdx++)
402*35238bceSAndroid Build Coastguard Worker     {
403*35238bceSAndroid Build Coastguard Worker         ConstValueRangeAccess dst = valueRange.asAccess().component(elemNdx);
404*35238bceSAndroid Build Coastguard Worker         ValueRangeAccess a        = this->m_leftValueRange.asAccess().component(
405*35238bceSAndroid Build Coastguard Worker             elemNdx); // \todo [2011-03-25 pyry] Commutative: randomize inputs
406*35238bceSAndroid Build Coastguard Worker         ValueRangeAccess b = this->m_rightValueRange.asAccess().component(elemNdx);
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker         // Just pass undefined ranges
409*35238bceSAndroid Build Coastguard Worker         if ((baseType == VariableType::TYPE_FLOAT || baseType == VariableType::TYPE_INT) && isUndefinedValueRange(dst))
410*35238bceSAndroid Build Coastguard Worker         {
411*35238bceSAndroid Build Coastguard Worker             a.getMin() = dst.getMin().value();
412*35238bceSAndroid Build Coastguard Worker             b.getMin() = dst.getMin().value();
413*35238bceSAndroid Build Coastguard Worker             a.getMax() = dst.getMax().value();
414*35238bceSAndroid Build Coastguard Worker             b.getMax() = dst.getMax().value();
415*35238bceSAndroid Build Coastguard Worker             continue;
416*35238bceSAndroid Build Coastguard Worker         }
417*35238bceSAndroid Build Coastguard Worker 
418*35238bceSAndroid Build Coastguard Worker         if (baseType == VariableType::TYPE_FLOAT)
419*35238bceSAndroid Build Coastguard Worker             ComputeValueRange()(state.getRandom(), dst.getMin().asFloat(), dst.getMax().asFloat(), a.getMin().asFloat(),
420*35238bceSAndroid Build Coastguard Worker                                 a.getMax().asFloat(), b.getMin().asFloat(), b.getMax().asFloat());
421*35238bceSAndroid Build Coastguard Worker         else if (baseType == VariableType::TYPE_INT)
422*35238bceSAndroid Build Coastguard Worker             ComputeValueRange()(state.getRandom(), dst.getMin().asInt(), dst.getMax().asInt(), a.getMin().asInt(),
423*35238bceSAndroid Build Coastguard Worker                                 a.getMax().asInt(), b.getMin().asInt(), b.getMax().asInt());
424*35238bceSAndroid Build Coastguard Worker         else
425*35238bceSAndroid Build Coastguard Worker         {
426*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(baseType == VariableType::TYPE_BOOL);
427*35238bceSAndroid Build Coastguard Worker             ComputeValueRange()(state.getRandom(), dst.getMin().asBool(), dst.getMax().asBool(), a.getMin().asBool(),
428*35238bceSAndroid Build Coastguard Worker                                 a.getMax().asBool(), b.getMin().asBool(), b.getMax().asBool());
429*35238bceSAndroid Build Coastguard Worker         }
430*35238bceSAndroid Build Coastguard Worker     }
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker 
433*35238bceSAndroid Build Coastguard Worker template <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp>
~BinaryVecOp(void)434*35238bceSAndroid Build Coastguard Worker BinaryVecOp<Precedence, Float, Int, Bool, ComputeValueRange, EvaluateComp>::~BinaryVecOp(void)
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker }
437*35238bceSAndroid Build Coastguard Worker 
438*35238bceSAndroid Build Coastguard Worker template <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp>
evaluate(ExecValueAccess dst,ExecConstValueAccess a,ExecConstValueAccess b)439*35238bceSAndroid Build Coastguard Worker void BinaryVecOp<Precedence, Float, Int, Bool, ComputeValueRange, EvaluateComp>::evaluate(ExecValueAccess dst,
440*35238bceSAndroid Build Coastguard Worker                                                                                           ExecConstValueAccess a,
441*35238bceSAndroid Build Coastguard Worker                                                                                           ExecConstValueAccess b)
442*35238bceSAndroid Build Coastguard Worker {
443*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getType() == a.getType());
444*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getType() == b.getType());
445*35238bceSAndroid Build Coastguard Worker     switch (dst.getType().getBaseType())
446*35238bceSAndroid Build Coastguard Worker     {
447*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_FLOAT:
448*35238bceSAndroid Build Coastguard Worker         for (int elemNdx = 0; elemNdx < dst.getType().getNumElements(); elemNdx++)
449*35238bceSAndroid Build Coastguard Worker         {
450*35238bceSAndroid Build Coastguard Worker             for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
451*35238bceSAndroid Build Coastguard Worker                 dst.component(elemNdx).asFloat(compNdx) =
452*35238bceSAndroid Build Coastguard Worker                     EvaluateComp()(a.component(elemNdx).asFloat(compNdx), b.component(elemNdx).asFloat(compNdx));
453*35238bceSAndroid Build Coastguard Worker         }
454*35238bceSAndroid Build Coastguard Worker         break;
455*35238bceSAndroid Build Coastguard Worker 
456*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_INT:
457*35238bceSAndroid Build Coastguard Worker         for (int elemNdx = 0; elemNdx < dst.getType().getNumElements(); elemNdx++)
458*35238bceSAndroid Build Coastguard Worker         {
459*35238bceSAndroid Build Coastguard Worker             for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
460*35238bceSAndroid Build Coastguard Worker                 dst.component(elemNdx).asInt(compNdx) =
461*35238bceSAndroid Build Coastguard Worker                     EvaluateComp()(a.component(elemNdx).asInt(compNdx), b.component(elemNdx).asInt(compNdx));
462*35238bceSAndroid Build Coastguard Worker         }
463*35238bceSAndroid Build Coastguard Worker         break;
464*35238bceSAndroid Build Coastguard Worker 
465*35238bceSAndroid Build Coastguard Worker     default:
466*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false); // Invalid type for multiplication
467*35238bceSAndroid Build Coastguard Worker     }
468*35238bceSAndroid Build Coastguard Worker }
469*35238bceSAndroid Build Coastguard Worker 
operator ()(de::Random & rnd,float dstMin,float dstMax,float & aMin,float & aMax,float & bMin,float & bMax) const470*35238bceSAndroid Build Coastguard Worker void ComputeMulRange::operator()(de::Random &rnd, float dstMin, float dstMax, float &aMin, float &aMax, float &bMin,
471*35238bceSAndroid Build Coastguard Worker                                  float &bMax) const
472*35238bceSAndroid Build Coastguard Worker {
473*35238bceSAndroid Build Coastguard Worker     const float minScale     = 0.25f;
474*35238bceSAndroid Build Coastguard Worker     const float maxScale     = 2.0f;
475*35238bceSAndroid Build Coastguard Worker     const float subRangeStep = 0.25f;
476*35238bceSAndroid Build Coastguard Worker     const float scaleStep    = 0.25f;
477*35238bceSAndroid Build Coastguard Worker 
478*35238bceSAndroid Build Coastguard Worker     float scale     = getQuantizedFloat(rnd, minScale, maxScale, scaleStep);
479*35238bceSAndroid Build Coastguard Worker     float scaledMin = dstMin / scale;
480*35238bceSAndroid Build Coastguard Worker     float scaledMax = dstMax / scale;
481*35238bceSAndroid Build Coastguard Worker 
482*35238bceSAndroid Build Coastguard Worker     // Quantize scaled value range if possible
483*35238bceSAndroid Build Coastguard Worker     if (!quantizeFloatRange(scaledMin, scaledMax))
484*35238bceSAndroid Build Coastguard Worker     {
485*35238bceSAndroid Build Coastguard Worker         // Fall back to 1.0 as a scale
486*35238bceSAndroid Build Coastguard Worker         scale     = 1.0f;
487*35238bceSAndroid Build Coastguard Worker         scaledMin = dstMin;
488*35238bceSAndroid Build Coastguard Worker         scaledMax = dstMax;
489*35238bceSAndroid Build Coastguard Worker     }
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker     float subRangeLen = getQuantizedFloat(rnd, 0.0f, scaledMax - scaledMin, subRangeStep);
492*35238bceSAndroid Build Coastguard Worker     aMin              = scaledMin + getQuantizedFloat(rnd, 0.0f, (scaledMax - scaledMin) - subRangeLen, subRangeStep);
493*35238bceSAndroid Build Coastguard Worker     aMax              = aMin + subRangeLen;
494*35238bceSAndroid Build Coastguard Worker 
495*35238bceSAndroid Build Coastguard Worker     // Find scale range
496*35238bceSAndroid Build Coastguard Worker     bMin = scale;
497*35238bceSAndroid Build Coastguard Worker     bMax = scale;
498*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 5; i++)
499*35238bceSAndroid Build Coastguard Worker     {
500*35238bceSAndroid Build Coastguard Worker         if (de::inBounds(aMin * (scale - (float)i * scaleStep), dstMin, dstMax) &&
501*35238bceSAndroid Build Coastguard Worker             de::inBounds(aMax * (scale - (float)i * scaleStep), dstMin, dstMax))
502*35238bceSAndroid Build Coastguard Worker             bMin = scale - (float)i * scaleStep;
503*35238bceSAndroid Build Coastguard Worker 
504*35238bceSAndroid Build Coastguard Worker         if (de::inBounds(aMin * (scale + (float)i * scaleStep), dstMin, dstMax) &&
505*35238bceSAndroid Build Coastguard Worker             de::inBounds(aMax * (scale + (float)i * scaleStep), dstMin, dstMax))
506*35238bceSAndroid Build Coastguard Worker             bMax = scale + (float)i * scaleStep;
507*35238bceSAndroid Build Coastguard Worker     }
508*35238bceSAndroid Build Coastguard Worker 
509*35238bceSAndroid Build Coastguard Worker     // Negative scale?
510*35238bceSAndroid Build Coastguard Worker     if (rnd.getBool())
511*35238bceSAndroid Build Coastguard Worker     {
512*35238bceSAndroid Build Coastguard Worker         std::swap(aMin, aMax);
513*35238bceSAndroid Build Coastguard Worker         std::swap(bMin, bMax);
514*35238bceSAndroid Build Coastguard Worker         aMin *= -1.0f;
515*35238bceSAndroid Build Coastguard Worker         aMax *= -1.0f;
516*35238bceSAndroid Build Coastguard Worker         bMin *= -1.0f;
517*35238bceSAndroid Build Coastguard Worker         bMax *= -1.0f;
518*35238bceSAndroid Build Coastguard Worker     }
519*35238bceSAndroid Build Coastguard Worker 
520*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
521*35238bceSAndroid Build Coastguard Worker     const float eps = 0.001f;
522*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(aMin <= aMax && bMin <= bMax);
523*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMin * bMin, dstMin - eps, dstMax + eps));
524*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMin * bMax, dstMin - eps, dstMax + eps));
525*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMax * bMin, dstMin - eps, dstMax + eps));
526*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMax * bMax, dstMin - eps, dstMax + eps));
527*35238bceSAndroid Build Coastguard Worker #endif
528*35238bceSAndroid Build Coastguard Worker }
529*35238bceSAndroid Build Coastguard Worker 
operator ()(de::Random & rnd,int dstMin,int dstMax,int & aMin,int & aMax,int & bMin,int & bMax) const530*35238bceSAndroid Build Coastguard Worker void ComputeMulRange::operator()(de::Random &rnd, int dstMin, int dstMax, int &aMin, int &aMax, int &bMin,
531*35238bceSAndroid Build Coastguard Worker                                  int &bMax) const
532*35238bceSAndroid Build Coastguard Worker {
533*35238bceSAndroid Build Coastguard Worker     DE_UNREF(rnd);
534*35238bceSAndroid Build Coastguard Worker     aMin = dstMin;
535*35238bceSAndroid Build Coastguard Worker     aMax = dstMax;
536*35238bceSAndroid Build Coastguard Worker     bMin = 1;
537*35238bceSAndroid Build Coastguard Worker     bMax = 1;
538*35238bceSAndroid Build Coastguard Worker }
539*35238bceSAndroid Build Coastguard Worker 
MulOp(GeneratorState & state,ConstValueRangeAccess valueRange)540*35238bceSAndroid Build Coastguard Worker MulOp::MulOp(GeneratorState &state, ConstValueRangeAccess valueRange) : MulBase(state, Token::MUL, valueRange)
541*35238bceSAndroid Build Coastguard Worker {
542*35238bceSAndroid Build Coastguard Worker }
543*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)544*35238bceSAndroid Build Coastguard Worker float MulOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
545*35238bceSAndroid Build Coastguard Worker {
546*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid() || valueRange.getType().isFloatOrVec() || valueRange.getType().isIntOrVec())
547*35238bceSAndroid Build Coastguard Worker         return MulBase::getWeight(state, valueRange);
548*35238bceSAndroid Build Coastguard Worker     else
549*35238bceSAndroid Build Coastguard Worker         return 0.0f;
550*35238bceSAndroid Build Coastguard Worker }
551*35238bceSAndroid Build Coastguard Worker 
552*35238bceSAndroid Build Coastguard Worker template <typename T>
operator ()(de::Random & random,T dstMin,T dstMax,T & aMin,T & aMax,T & bMin,T & bMax) const553*35238bceSAndroid Build Coastguard Worker void ComputeAddRange::operator()(de::Random &random, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const
554*35238bceSAndroid Build Coastguard Worker {
555*35238bceSAndroid Build Coastguard Worker     struct GetRandom
556*35238bceSAndroid Build Coastguard Worker     {
557*35238bceSAndroid Build Coastguard Worker         int operator()(de::Random &rnd, int min, int max) const
558*35238bceSAndroid Build Coastguard Worker         {
559*35238bceSAndroid Build Coastguard Worker             return rnd.getInt(min, max);
560*35238bceSAndroid Build Coastguard Worker         }
561*35238bceSAndroid Build Coastguard Worker         float operator()(de::Random &rnd, float min, float max) const
562*35238bceSAndroid Build Coastguard Worker         {
563*35238bceSAndroid Build Coastguard Worker             return getQuantizedFloat(rnd, min, max, 0.5f);
564*35238bceSAndroid Build Coastguard Worker         }
565*35238bceSAndroid Build Coastguard Worker     };
566*35238bceSAndroid Build Coastguard Worker 
567*35238bceSAndroid Build Coastguard Worker     T rangeLen    = dstMax - dstMin;
568*35238bceSAndroid Build Coastguard Worker     T subRangeLen = GetRandom()(random, T(0), rangeLen);
569*35238bceSAndroid Build Coastguard Worker     T aOffset     = GetRandom()(random, T(-8), T(8));
570*35238bceSAndroid Build Coastguard Worker 
571*35238bceSAndroid Build Coastguard Worker     aMin = dstMin + aOffset;
572*35238bceSAndroid Build Coastguard Worker     aMax = aMin + subRangeLen;
573*35238bceSAndroid Build Coastguard Worker 
574*35238bceSAndroid Build Coastguard Worker     bMin = -aOffset;
575*35238bceSAndroid Build Coastguard Worker     bMax = -aOffset + (rangeLen - subRangeLen);
576*35238bceSAndroid Build Coastguard Worker 
577*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
578*35238bceSAndroid Build Coastguard Worker     T eps = T(0.001);
579*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(aMin <= aMax && bMin <= bMax);
580*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMin + bMin, dstMin - eps, dstMax + eps));
581*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMin + bMax, dstMin - eps, dstMax + eps));
582*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMax + bMin, dstMin - eps, dstMax + eps));
583*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMax + bMax, dstMin - eps, dstMax + eps));
584*35238bceSAndroid Build Coastguard Worker #endif
585*35238bceSAndroid Build Coastguard Worker }
586*35238bceSAndroid Build Coastguard Worker 
587*35238bceSAndroid Build Coastguard Worker template <>
operator()588*35238bceSAndroid Build Coastguard Worker void ComputeAddRange::operator()<bool>(de::Random &, bool, bool, bool &, bool &, bool &, bool &) const
589*35238bceSAndroid Build Coastguard Worker {
590*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker 
AddOp(GeneratorState & state,ConstValueRangeAccess valueRange)593*35238bceSAndroid Build Coastguard Worker AddOp::AddOp(GeneratorState &state, ConstValueRangeAccess valueRange) : AddBase(state, Token::PLUS, valueRange)
594*35238bceSAndroid Build Coastguard Worker {
595*35238bceSAndroid Build Coastguard Worker }
596*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)597*35238bceSAndroid Build Coastguard Worker float AddOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
598*35238bceSAndroid Build Coastguard Worker {
599*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid() || valueRange.getType().isFloatOrVec() || valueRange.getType().isIntOrVec())
600*35238bceSAndroid Build Coastguard Worker         return AddBase::getWeight(state, valueRange);
601*35238bceSAndroid Build Coastguard Worker     else
602*35238bceSAndroid Build Coastguard Worker         return 0.0f;
603*35238bceSAndroid Build Coastguard Worker }
604*35238bceSAndroid Build Coastguard Worker 
605*35238bceSAndroid Build Coastguard Worker template <typename T>
operator ()(de::Random & random,T dstMin,T dstMax,T & aMin,T & aMax,T & bMin,T & bMax) const606*35238bceSAndroid Build Coastguard Worker void ComputeSubRange::operator()(de::Random &random, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const
607*35238bceSAndroid Build Coastguard Worker {
608*35238bceSAndroid Build Coastguard Worker     struct GetRandom
609*35238bceSAndroid Build Coastguard Worker     {
610*35238bceSAndroid Build Coastguard Worker         int operator()(de::Random &rnd, int min, int max) const
611*35238bceSAndroid Build Coastguard Worker         {
612*35238bceSAndroid Build Coastguard Worker             return rnd.getInt(min, max);
613*35238bceSAndroid Build Coastguard Worker         }
614*35238bceSAndroid Build Coastguard Worker         float operator()(de::Random &rnd, float min, float max) const
615*35238bceSAndroid Build Coastguard Worker         {
616*35238bceSAndroid Build Coastguard Worker             return getQuantizedFloat(rnd, min, max, 0.5f);
617*35238bceSAndroid Build Coastguard Worker         }
618*35238bceSAndroid Build Coastguard Worker     };
619*35238bceSAndroid Build Coastguard Worker 
620*35238bceSAndroid Build Coastguard Worker     T rangeLen    = dstMax - dstMin;
621*35238bceSAndroid Build Coastguard Worker     T subRangeLen = GetRandom()(random, T(0), rangeLen);
622*35238bceSAndroid Build Coastguard Worker     T aOffset     = GetRandom()(random, T(-8), T(8));
623*35238bceSAndroid Build Coastguard Worker 
624*35238bceSAndroid Build Coastguard Worker     aMin = dstMin + aOffset;
625*35238bceSAndroid Build Coastguard Worker     aMax = aMin + subRangeLen;
626*35238bceSAndroid Build Coastguard Worker 
627*35238bceSAndroid Build Coastguard Worker     bMin = aOffset - (rangeLen - subRangeLen);
628*35238bceSAndroid Build Coastguard Worker     bMax = aOffset;
629*35238bceSAndroid Build Coastguard Worker 
630*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
631*35238bceSAndroid Build Coastguard Worker     T eps = T(0.001);
632*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(aMin <= aMax && bMin <= bMax);
633*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMin - bMin, dstMin - eps, dstMax + eps));
634*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMin - bMax, dstMin - eps, dstMax + eps));
635*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMax - bMin, dstMin - eps, dstMax + eps));
636*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(aMax - bMax, dstMin - eps, dstMax + eps));
637*35238bceSAndroid Build Coastguard Worker #endif
638*35238bceSAndroid Build Coastguard Worker }
639*35238bceSAndroid Build Coastguard Worker 
640*35238bceSAndroid Build Coastguard Worker template <>
operator()641*35238bceSAndroid Build Coastguard Worker void ComputeSubRange::operator()<bool>(de::Random &, bool, bool, bool &, bool &, bool &, bool &) const
642*35238bceSAndroid Build Coastguard Worker {
643*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(false);
644*35238bceSAndroid Build Coastguard Worker }
645*35238bceSAndroid Build Coastguard Worker 
SubOp(GeneratorState & state,ConstValueRangeAccess valueRange)646*35238bceSAndroid Build Coastguard Worker SubOp::SubOp(GeneratorState &state, ConstValueRangeAccess valueRange) : SubBase(state, Token::MINUS, valueRange)
647*35238bceSAndroid Build Coastguard Worker {
648*35238bceSAndroid Build Coastguard Worker }
649*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)650*35238bceSAndroid Build Coastguard Worker float SubOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
651*35238bceSAndroid Build Coastguard Worker {
652*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid() || valueRange.getType().isFloatOrVec() || valueRange.getType().isIntOrVec())
653*35238bceSAndroid Build Coastguard Worker         return SubBase::getWeight(state, valueRange);
654*35238bceSAndroid Build Coastguard Worker     else
655*35238bceSAndroid Build Coastguard Worker         return 0.0f;
656*35238bceSAndroid Build Coastguard Worker }
657*35238bceSAndroid Build Coastguard Worker 
658*35238bceSAndroid Build Coastguard Worker template <class ComputeValueRange, class EvaluateComp>
RelationalOp(GeneratorState & state,Token::Type operatorToken,ConstValueRangeAccess inValueRange)659*35238bceSAndroid Build Coastguard Worker RelationalOp<ComputeValueRange, EvaluateComp>::RelationalOp(GeneratorState &state, Token::Type operatorToken,
660*35238bceSAndroid Build Coastguard Worker                                                             ConstValueRangeAccess inValueRange)
661*35238bceSAndroid Build Coastguard Worker     : BinaryOp<7, ASSOCIATIVITY_LEFT>(operatorToken)
662*35238bceSAndroid Build Coastguard Worker {
663*35238bceSAndroid Build Coastguard Worker     ValueRange valueRange = inValueRange;
664*35238bceSAndroid Build Coastguard Worker 
665*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid())
666*35238bceSAndroid Build Coastguard Worker     {
667*35238bceSAndroid Build Coastguard Worker         valueRange = ValueRange(VariableType(VariableType::TYPE_BOOL, 1));
668*35238bceSAndroid Build Coastguard Worker         computeRandomValueRange(state, valueRange.asAccess());
669*35238bceSAndroid Build Coastguard Worker     }
670*35238bceSAndroid Build Coastguard Worker 
671*35238bceSAndroid Build Coastguard Worker     // Choose type, allocate storage for execution
672*35238bceSAndroid Build Coastguard Worker     this->m_type = valueRange.getType();
673*35238bceSAndroid Build Coastguard Worker     this->m_value.setStorage(this->m_type);
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker     // Choose random input type
676*35238bceSAndroid Build Coastguard Worker     VariableType::Type inBaseTypes[] = {VariableType::TYPE_FLOAT, VariableType::TYPE_INT};
677*35238bceSAndroid Build Coastguard Worker     VariableType::Type inBaseType =
678*35238bceSAndroid Build Coastguard Worker         state.getRandom().choose<VariableType::Type>(&inBaseTypes[0], &inBaseTypes[DE_LENGTH_OF_ARRAY(inBaseTypes)]);
679*35238bceSAndroid Build Coastguard Worker 
680*35238bceSAndroid Build Coastguard Worker     // Initialize storage for input value ranges
681*35238bceSAndroid Build Coastguard Worker     this->m_rightValueRange = ValueRange(VariableType(inBaseType, 1));
682*35238bceSAndroid Build Coastguard Worker     this->m_leftValueRange  = ValueRange(VariableType(inBaseType, 1));
683*35238bceSAndroid Build Coastguard Worker 
684*35238bceSAndroid Build Coastguard Worker     // Compute range for b that satisfies requested value range
685*35238bceSAndroid Build Coastguard Worker     {
686*35238bceSAndroid Build Coastguard Worker         bool dstMin        = valueRange.getMin().asBool();
687*35238bceSAndroid Build Coastguard Worker         bool dstMax        = valueRange.getMax().asBool();
688*35238bceSAndroid Build Coastguard Worker         ValueRangeAccess a = this->m_leftValueRange.asAccess();
689*35238bceSAndroid Build Coastguard Worker         ValueRangeAccess b = this->m_rightValueRange.asAccess();
690*35238bceSAndroid Build Coastguard Worker 
691*35238bceSAndroid Build Coastguard Worker         if (inBaseType == VariableType::TYPE_FLOAT)
692*35238bceSAndroid Build Coastguard Worker             ComputeValueRange()(state.getRandom(), dstMin, dstMax, a.getMin().asFloat(), a.getMax().asFloat(),
693*35238bceSAndroid Build Coastguard Worker                                 b.getMin().asFloat(), b.getMax().asFloat());
694*35238bceSAndroid Build Coastguard Worker         else if (inBaseType == VariableType::TYPE_INT)
695*35238bceSAndroid Build Coastguard Worker             ComputeValueRange()(state.getRandom(), dstMin, dstMax, a.getMin().asInt(), a.getMax().asInt(),
696*35238bceSAndroid Build Coastguard Worker                                 b.getMin().asInt(), b.getMax().asInt());
697*35238bceSAndroid Build Coastguard Worker     }
698*35238bceSAndroid Build Coastguard Worker }
699*35238bceSAndroid Build Coastguard Worker 
700*35238bceSAndroid Build Coastguard Worker template <class ComputeValueRange, class EvaluateComp>
~RelationalOp(void)701*35238bceSAndroid Build Coastguard Worker RelationalOp<ComputeValueRange, EvaluateComp>::~RelationalOp(void)
702*35238bceSAndroid Build Coastguard Worker {
703*35238bceSAndroid Build Coastguard Worker }
704*35238bceSAndroid Build Coastguard Worker 
705*35238bceSAndroid Build Coastguard Worker template <class ComputeValueRange, class EvaluateComp>
evaluate(ExecValueAccess dst,ExecConstValueAccess a,ExecConstValueAccess b)706*35238bceSAndroid Build Coastguard Worker void RelationalOp<ComputeValueRange, EvaluateComp>::evaluate(ExecValueAccess dst, ExecConstValueAccess a,
707*35238bceSAndroid Build Coastguard Worker                                                              ExecConstValueAccess b)
708*35238bceSAndroid Build Coastguard Worker {
709*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(a.getType() == b.getType());
710*35238bceSAndroid Build Coastguard Worker     switch (a.getType().getBaseType())
711*35238bceSAndroid Build Coastguard Worker     {
712*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_FLOAT:
713*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
714*35238bceSAndroid Build Coastguard Worker             dst.asBool(compNdx) = EvaluateComp()(a.asFloat(compNdx), b.asFloat(compNdx));
715*35238bceSAndroid Build Coastguard Worker         break;
716*35238bceSAndroid Build Coastguard Worker 
717*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_INT:
718*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
719*35238bceSAndroid Build Coastguard Worker             dst.asBool(compNdx) = EvaluateComp()(a.asInt(compNdx), b.asInt(compNdx));
720*35238bceSAndroid Build Coastguard Worker         break;
721*35238bceSAndroid Build Coastguard Worker 
722*35238bceSAndroid Build Coastguard Worker     default:
723*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
724*35238bceSAndroid Build Coastguard Worker     }
725*35238bceSAndroid Build Coastguard Worker }
726*35238bceSAndroid Build Coastguard Worker 
727*35238bceSAndroid Build Coastguard Worker template <class ComputeValueRange, class EvaluateComp>
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)728*35238bceSAndroid Build Coastguard Worker float RelationalOp<ComputeValueRange, EvaluateComp>::getWeight(const GeneratorState &state,
729*35238bceSAndroid Build Coastguard Worker                                                                ConstValueRangeAccess valueRange)
730*35238bceSAndroid Build Coastguard Worker {
731*35238bceSAndroid Build Coastguard Worker     if (!state.getProgramParameters().useComparisonOps)
732*35238bceSAndroid Build Coastguard Worker         return 0.0f;
733*35238bceSAndroid Build Coastguard Worker 
734*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid() ||
735*35238bceSAndroid Build Coastguard Worker         (valueRange.getType().getBaseType() == VariableType::TYPE_BOOL && valueRange.getType().getNumElements() == 1))
736*35238bceSAndroid Build Coastguard Worker         return BinaryOp<7, ASSOCIATIVITY_LEFT>::getWeight(state, valueRange);
737*35238bceSAndroid Build Coastguard Worker     else
738*35238bceSAndroid Build Coastguard Worker         return 0.0f;
739*35238bceSAndroid Build Coastguard Worker }
740*35238bceSAndroid Build Coastguard Worker 
741*35238bceSAndroid Build Coastguard Worker namespace
742*35238bceSAndroid Build Coastguard Worker {
743*35238bceSAndroid Build Coastguard Worker 
744*35238bceSAndroid Build Coastguard Worker template <typename T>
745*35238bceSAndroid Build Coastguard Worker T getStep(void);
746*35238bceSAndroid Build Coastguard Worker template <>
getStep(void)747*35238bceSAndroid Build Coastguard Worker inline float getStep(void)
748*35238bceSAndroid Build Coastguard Worker {
749*35238bceSAndroid Build Coastguard Worker     return 0.25f;
750*35238bceSAndroid Build Coastguard Worker }
751*35238bceSAndroid Build Coastguard Worker template <>
getStep(void)752*35238bceSAndroid Build Coastguard Worker inline int getStep(void)
753*35238bceSAndroid Build Coastguard Worker {
754*35238bceSAndroid Build Coastguard Worker     return 1;
755*35238bceSAndroid Build Coastguard Worker }
756*35238bceSAndroid Build Coastguard Worker 
757*35238bceSAndroid Build Coastguard Worker } // namespace
758*35238bceSAndroid Build Coastguard Worker 
759*35238bceSAndroid Build Coastguard Worker template <typename T>
operator ()(de::Random & rnd,bool dstMin,bool dstMax,T & aMin,T & aMax,T & bMin,T & bMax) const760*35238bceSAndroid Build Coastguard Worker void ComputeLessThanRange::operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin,
761*35238bceSAndroid Build Coastguard Worker                                       T &bMax) const
762*35238bceSAndroid Build Coastguard Worker {
763*35238bceSAndroid Build Coastguard Worker     struct GetRandom
764*35238bceSAndroid Build Coastguard Worker     {
765*35238bceSAndroid Build Coastguard Worker         int operator()(de::Random &random, int min, int max) const
766*35238bceSAndroid Build Coastguard Worker         {
767*35238bceSAndroid Build Coastguard Worker             return random.getInt(min, max);
768*35238bceSAndroid Build Coastguard Worker         }
769*35238bceSAndroid Build Coastguard Worker         float operator()(de::Random &random, float min, float max) const
770*35238bceSAndroid Build Coastguard Worker         {
771*35238bceSAndroid Build Coastguard Worker             return getQuantizedFloat(random, min, max, getStep<float>());
772*35238bceSAndroid Build Coastguard Worker         }
773*35238bceSAndroid Build Coastguard Worker     };
774*35238bceSAndroid Build Coastguard Worker 
775*35238bceSAndroid Build Coastguard Worker     // One random range
776*35238bceSAndroid Build Coastguard Worker     T rLen = GetRandom()(rnd, T(0), T(8));
777*35238bceSAndroid Build Coastguard Worker     T rMin = GetRandom()(rnd, T(-4), T(4));
778*35238bceSAndroid Build Coastguard Worker     T rMax = rMin + rLen;
779*35238bceSAndroid Build Coastguard Worker 
780*35238bceSAndroid Build Coastguard Worker     if (dstMin == false && dstMax == true)
781*35238bceSAndroid Build Coastguard Worker     {
782*35238bceSAndroid Build Coastguard Worker         // Both values are possible, use same range for both inputs
783*35238bceSAndroid Build Coastguard Worker         aMin = rMin;
784*35238bceSAndroid Build Coastguard Worker         aMax = rMax;
785*35238bceSAndroid Build Coastguard Worker         bMin = rMin;
786*35238bceSAndroid Build Coastguard Worker         bMax = rMax;
787*35238bceSAndroid Build Coastguard Worker     }
788*35238bceSAndroid Build Coastguard Worker     else if (dstMin == true && dstMax == true)
789*35238bceSAndroid Build Coastguard Worker     {
790*35238bceSAndroid Build Coastguard Worker         // Compute range that is less than rMin..rMax
791*35238bceSAndroid Build Coastguard Worker         T aLen = GetRandom()(rnd, T(0), T(8) - rLen);
792*35238bceSAndroid Build Coastguard Worker 
793*35238bceSAndroid Build Coastguard Worker         aMax = rMin - getStep<T>();
794*35238bceSAndroid Build Coastguard Worker         aMin = aMax - aLen;
795*35238bceSAndroid Build Coastguard Worker 
796*35238bceSAndroid Build Coastguard Worker         bMin = rMin;
797*35238bceSAndroid Build Coastguard Worker         bMax = rMax;
798*35238bceSAndroid Build Coastguard Worker     }
799*35238bceSAndroid Build Coastguard Worker     else
800*35238bceSAndroid Build Coastguard Worker     {
801*35238bceSAndroid Build Coastguard Worker         // Compute range that is greater than or equal to rMin..rMax
802*35238bceSAndroid Build Coastguard Worker         T aLen = GetRandom()(rnd, T(0), T(8) - rLen);
803*35238bceSAndroid Build Coastguard Worker 
804*35238bceSAndroid Build Coastguard Worker         aMin = rMax;
805*35238bceSAndroid Build Coastguard Worker         aMax = aMin + aLen;
806*35238bceSAndroid Build Coastguard Worker 
807*35238bceSAndroid Build Coastguard Worker         bMin = rMin;
808*35238bceSAndroid Build Coastguard Worker         bMax = rMax;
809*35238bceSAndroid Build Coastguard Worker     }
810*35238bceSAndroid Build Coastguard Worker }
811*35238bceSAndroid Build Coastguard Worker 
LessThanOp(GeneratorState & state,ConstValueRangeAccess valueRange)812*35238bceSAndroid Build Coastguard Worker LessThanOp::LessThanOp(GeneratorState &state, ConstValueRangeAccess valueRange)
813*35238bceSAndroid Build Coastguard Worker     : LessThanBase(state, Token::CMP_LT, valueRange)
814*35238bceSAndroid Build Coastguard Worker {
815*35238bceSAndroid Build Coastguard Worker }
816*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)817*35238bceSAndroid Build Coastguard Worker float LessThanOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
818*35238bceSAndroid Build Coastguard Worker {
819*35238bceSAndroid Build Coastguard Worker     return LessThanBase::getWeight(state, valueRange);
820*35238bceSAndroid Build Coastguard Worker }
821*35238bceSAndroid Build Coastguard Worker 
822*35238bceSAndroid Build Coastguard Worker template <typename T>
operator ()(de::Random & rnd,bool dstMin,bool dstMax,T & aMin,T & aMax,T & bMin,T & bMax) const823*35238bceSAndroid Build Coastguard Worker void ComputeLessOrEqualRange::operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin,
824*35238bceSAndroid Build Coastguard Worker                                          T &bMax) const
825*35238bceSAndroid Build Coastguard Worker {
826*35238bceSAndroid Build Coastguard Worker     struct GetRandom
827*35238bceSAndroid Build Coastguard Worker     {
828*35238bceSAndroid Build Coastguard Worker         int operator()(de::Random &random, int min, int max) const
829*35238bceSAndroid Build Coastguard Worker         {
830*35238bceSAndroid Build Coastguard Worker             return random.getInt(min, max);
831*35238bceSAndroid Build Coastguard Worker         }
832*35238bceSAndroid Build Coastguard Worker         float operator()(de::Random &random, float min, float max) const
833*35238bceSAndroid Build Coastguard Worker         {
834*35238bceSAndroid Build Coastguard Worker             return getQuantizedFloat(random, min, max, getStep<float>());
835*35238bceSAndroid Build Coastguard Worker         }
836*35238bceSAndroid Build Coastguard Worker     };
837*35238bceSAndroid Build Coastguard Worker 
838*35238bceSAndroid Build Coastguard Worker     // One random range
839*35238bceSAndroid Build Coastguard Worker     T rLen = GetRandom()(rnd, T(0), T(8));
840*35238bceSAndroid Build Coastguard Worker     T rMin = GetRandom()(rnd, T(-4), T(4));
841*35238bceSAndroid Build Coastguard Worker     T rMax = rMin + rLen;
842*35238bceSAndroid Build Coastguard Worker 
843*35238bceSAndroid Build Coastguard Worker     if (dstMin == false && dstMax == true)
844*35238bceSAndroid Build Coastguard Worker     {
845*35238bceSAndroid Build Coastguard Worker         // Both values are possible, use same range for both inputs
846*35238bceSAndroid Build Coastguard Worker         aMin = rMin;
847*35238bceSAndroid Build Coastguard Worker         aMax = rMax;
848*35238bceSAndroid Build Coastguard Worker         bMin = rMin;
849*35238bceSAndroid Build Coastguard Worker         bMax = rMax;
850*35238bceSAndroid Build Coastguard Worker     }
851*35238bceSAndroid Build Coastguard Worker     else if (dstMin == true && dstMax == true)
852*35238bceSAndroid Build Coastguard Worker     {
853*35238bceSAndroid Build Coastguard Worker         // Compute range that is less than or equal to rMin..rMax
854*35238bceSAndroid Build Coastguard Worker         T aLen = GetRandom()(rnd, T(0), T(8) - rLen);
855*35238bceSAndroid Build Coastguard Worker 
856*35238bceSAndroid Build Coastguard Worker         aMax = rMin;
857*35238bceSAndroid Build Coastguard Worker         aMin = aMax - aLen;
858*35238bceSAndroid Build Coastguard Worker 
859*35238bceSAndroid Build Coastguard Worker         bMin = rMin;
860*35238bceSAndroid Build Coastguard Worker         bMax = rMax;
861*35238bceSAndroid Build Coastguard Worker     }
862*35238bceSAndroid Build Coastguard Worker     else
863*35238bceSAndroid Build Coastguard Worker     {
864*35238bceSAndroid Build Coastguard Worker         // Compute range that is greater than rMin..rMax
865*35238bceSAndroid Build Coastguard Worker         T aLen = GetRandom()(rnd, T(0), T(8) - rLen);
866*35238bceSAndroid Build Coastguard Worker 
867*35238bceSAndroid Build Coastguard Worker         aMin = rMax + getStep<T>();
868*35238bceSAndroid Build Coastguard Worker         aMax = aMin + aLen;
869*35238bceSAndroid Build Coastguard Worker 
870*35238bceSAndroid Build Coastguard Worker         bMin = rMin;
871*35238bceSAndroid Build Coastguard Worker         bMax = rMax;
872*35238bceSAndroid Build Coastguard Worker     }
873*35238bceSAndroid Build Coastguard Worker }
874*35238bceSAndroid Build Coastguard Worker 
LessOrEqualOp(GeneratorState & state,ConstValueRangeAccess valueRange)875*35238bceSAndroid Build Coastguard Worker LessOrEqualOp::LessOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange)
876*35238bceSAndroid Build Coastguard Worker     : LessOrEqualBase(state, Token::CMP_LE, valueRange)
877*35238bceSAndroid Build Coastguard Worker {
878*35238bceSAndroid Build Coastguard Worker }
879*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)880*35238bceSAndroid Build Coastguard Worker float LessOrEqualOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
881*35238bceSAndroid Build Coastguard Worker {
882*35238bceSAndroid Build Coastguard Worker     return LessOrEqualBase::getWeight(state, valueRange);
883*35238bceSAndroid Build Coastguard Worker }
884*35238bceSAndroid Build Coastguard Worker 
GreaterThanOp(GeneratorState & state,ConstValueRangeAccess valueRange)885*35238bceSAndroid Build Coastguard Worker GreaterThanOp::GreaterThanOp(GeneratorState &state, ConstValueRangeAccess valueRange)
886*35238bceSAndroid Build Coastguard Worker     : GreaterThanBase(state, Token::CMP_GT, valueRange)
887*35238bceSAndroid Build Coastguard Worker {
888*35238bceSAndroid Build Coastguard Worker }
889*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)890*35238bceSAndroid Build Coastguard Worker float GreaterThanOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
891*35238bceSAndroid Build Coastguard Worker {
892*35238bceSAndroid Build Coastguard Worker     return GreaterThanBase::getWeight(state, valueRange);
893*35238bceSAndroid Build Coastguard Worker }
894*35238bceSAndroid Build Coastguard Worker 
GreaterOrEqualOp(GeneratorState & state,ConstValueRangeAccess valueRange)895*35238bceSAndroid Build Coastguard Worker GreaterOrEqualOp::GreaterOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange)
896*35238bceSAndroid Build Coastguard Worker     : GreaterOrEqualBase(state, Token::CMP_GE, valueRange)
897*35238bceSAndroid Build Coastguard Worker {
898*35238bceSAndroid Build Coastguard Worker }
899*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)900*35238bceSAndroid Build Coastguard Worker float GreaterOrEqualOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
901*35238bceSAndroid Build Coastguard Worker {
902*35238bceSAndroid Build Coastguard Worker     return GreaterOrEqualBase::getWeight(state, valueRange);
903*35238bceSAndroid Build Coastguard Worker }
904*35238bceSAndroid Build Coastguard Worker 
905*35238bceSAndroid Build Coastguard Worker namespace
906*35238bceSAndroid Build Coastguard Worker {
907*35238bceSAndroid Build Coastguard Worker 
908*35238bceSAndroid Build Coastguard Worker template <bool IsEqual, typename T>
computeEqualityValueRange(de::Random & rnd,bool dstMin,bool dstMax,T & aMin,T & aMax,T & bMin,T & bMax)909*35238bceSAndroid Build Coastguard Worker void computeEqualityValueRange(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax)
910*35238bceSAndroid Build Coastguard Worker {
911*35238bceSAndroid Build Coastguard Worker     if (dstMin == false && dstMax == true)
912*35238bceSAndroid Build Coastguard Worker         ComputeLessThanRange()(rnd, false, true, aMin, aMax, bMin, bMax);
913*35238bceSAndroid Build Coastguard Worker     else if (IsEqual && dstMin == false)
914*35238bceSAndroid Build Coastguard Worker         ComputeLessThanRange()(rnd, true, true, aMin, aMax, bMin, bMax);
915*35238bceSAndroid Build Coastguard Worker     else if (!IsEqual && dstMin == true)
916*35238bceSAndroid Build Coastguard Worker         ComputeLessThanRange()(rnd, true, true, aMin, aMax, bMin, bMax);
917*35238bceSAndroid Build Coastguard Worker     else
918*35238bceSAndroid Build Coastguard Worker     {
919*35238bceSAndroid Build Coastguard Worker         // Must have exactly same values.
920*35238bceSAndroid Build Coastguard Worker         struct GetRandom
921*35238bceSAndroid Build Coastguard Worker         {
922*35238bceSAndroid Build Coastguard Worker             int operator()(de::Random &random, int min, int max) const
923*35238bceSAndroid Build Coastguard Worker             {
924*35238bceSAndroid Build Coastguard Worker                 return random.getInt(min, max);
925*35238bceSAndroid Build Coastguard Worker             }
926*35238bceSAndroid Build Coastguard Worker             float operator()(de::Random &random, float min, float max) const
927*35238bceSAndroid Build Coastguard Worker             {
928*35238bceSAndroid Build Coastguard Worker                 return getQuantizedFloat(random, min, max, 0.5f);
929*35238bceSAndroid Build Coastguard Worker             }
930*35238bceSAndroid Build Coastguard Worker         };
931*35238bceSAndroid Build Coastguard Worker 
932*35238bceSAndroid Build Coastguard Worker         T val = GetRandom()(rnd, T(-1), T(1));
933*35238bceSAndroid Build Coastguard Worker 
934*35238bceSAndroid Build Coastguard Worker         aMin = val;
935*35238bceSAndroid Build Coastguard Worker         aMax = val;
936*35238bceSAndroid Build Coastguard Worker         bMin = val;
937*35238bceSAndroid Build Coastguard Worker         bMax = val;
938*35238bceSAndroid Build Coastguard Worker     }
939*35238bceSAndroid Build Coastguard Worker }
940*35238bceSAndroid Build Coastguard Worker 
941*35238bceSAndroid Build Coastguard Worker template <>
computeEqualityValueRange(de::Random & rnd,bool dstMin,bool dstMax,bool & aMin,bool & aMax,bool & bMin,bool & bMax)942*35238bceSAndroid Build Coastguard Worker void computeEqualityValueRange<true, bool>(de::Random &rnd, bool dstMin, bool dstMax, bool &aMin, bool &aMax,
943*35238bceSAndroid Build Coastguard Worker                                            bool &bMin, bool &bMax)
944*35238bceSAndroid Build Coastguard Worker {
945*35238bceSAndroid Build Coastguard Worker     if (dstMin == false && dstMax == true)
946*35238bceSAndroid Build Coastguard Worker     {
947*35238bceSAndroid Build Coastguard Worker         aMin = false;
948*35238bceSAndroid Build Coastguard Worker         aMax = true;
949*35238bceSAndroid Build Coastguard Worker         bMin = false;
950*35238bceSAndroid Build Coastguard Worker         bMax = true;
951*35238bceSAndroid Build Coastguard Worker     }
952*35238bceSAndroid Build Coastguard Worker     else if (dstMin == false)
953*35238bceSAndroid Build Coastguard Worker     {
954*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(dstMax == false);
955*35238bceSAndroid Build Coastguard Worker         bool val = rnd.getBool();
956*35238bceSAndroid Build Coastguard Worker 
957*35238bceSAndroid Build Coastguard Worker         aMin = val;
958*35238bceSAndroid Build Coastguard Worker         aMax = val;
959*35238bceSAndroid Build Coastguard Worker         bMin = !val;
960*35238bceSAndroid Build Coastguard Worker         bMax = !val;
961*35238bceSAndroid Build Coastguard Worker     }
962*35238bceSAndroid Build Coastguard Worker     else
963*35238bceSAndroid Build Coastguard Worker     {
964*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(dstMin == true && dstMax == true);
965*35238bceSAndroid Build Coastguard Worker         bool val = rnd.getBool();
966*35238bceSAndroid Build Coastguard Worker 
967*35238bceSAndroid Build Coastguard Worker         aMin = val;
968*35238bceSAndroid Build Coastguard Worker         aMax = val;
969*35238bceSAndroid Build Coastguard Worker         bMin = val;
970*35238bceSAndroid Build Coastguard Worker         bMax = val;
971*35238bceSAndroid Build Coastguard Worker     }
972*35238bceSAndroid Build Coastguard Worker }
973*35238bceSAndroid Build Coastguard Worker 
974*35238bceSAndroid Build Coastguard Worker template <>
computeEqualityValueRange(de::Random & rnd,bool dstMin,bool dstMax,bool & aMin,bool & aMax,bool & bMin,bool & bMax)975*35238bceSAndroid Build Coastguard Worker void computeEqualityValueRange<false, bool>(de::Random &rnd, bool dstMin, bool dstMax, bool &aMin, bool &aMax,
976*35238bceSAndroid Build Coastguard Worker                                             bool &bMin, bool &bMax)
977*35238bceSAndroid Build Coastguard Worker {
978*35238bceSAndroid Build Coastguard Worker     if (dstMin == false && dstMax == true)
979*35238bceSAndroid Build Coastguard Worker         computeEqualityValueRange<true>(rnd, dstMin, dstMax, aMin, aMax, bMin, bMax);
980*35238bceSAndroid Build Coastguard Worker     else
981*35238bceSAndroid Build Coastguard Worker         computeEqualityValueRange<true>(rnd, !dstMin, !dstMax, aMin, aMax, bMin, bMax);
982*35238bceSAndroid Build Coastguard Worker }
983*35238bceSAndroid Build Coastguard Worker 
984*35238bceSAndroid Build Coastguard Worker } // namespace
985*35238bceSAndroid Build Coastguard Worker 
986*35238bceSAndroid Build Coastguard Worker template <bool IsEqual>
EqualityComparisonOp(GeneratorState & state,ConstValueRangeAccess inValueRange)987*35238bceSAndroid Build Coastguard Worker EqualityComparisonOp<IsEqual>::EqualityComparisonOp(GeneratorState &state, ConstValueRangeAccess inValueRange)
988*35238bceSAndroid Build Coastguard Worker     : BinaryOp<8, ASSOCIATIVITY_LEFT>(IsEqual ? Token::CMP_EQ : Token::CMP_NE)
989*35238bceSAndroid Build Coastguard Worker {
990*35238bceSAndroid Build Coastguard Worker     ValueRange valueRange = inValueRange;
991*35238bceSAndroid Build Coastguard Worker 
992*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid())
993*35238bceSAndroid Build Coastguard Worker     {
994*35238bceSAndroid Build Coastguard Worker         valueRange = ValueRange(VariableType(VariableType::TYPE_BOOL, 1));
995*35238bceSAndroid Build Coastguard Worker         computeRandomValueRange(state, valueRange.asAccess());
996*35238bceSAndroid Build Coastguard Worker     }
997*35238bceSAndroid Build Coastguard Worker 
998*35238bceSAndroid Build Coastguard Worker     // Choose type, allocate storage for execution
999*35238bceSAndroid Build Coastguard Worker     this->m_type = valueRange.getType();
1000*35238bceSAndroid Build Coastguard Worker     this->m_value.setStorage(this->m_type);
1001*35238bceSAndroid Build Coastguard Worker 
1002*35238bceSAndroid Build Coastguard Worker     // Choose random input type
1003*35238bceSAndroid Build Coastguard Worker     VariableType::Type inBaseTypes[] = {VariableType::TYPE_FLOAT, VariableType::TYPE_INT};
1004*35238bceSAndroid Build Coastguard Worker     VariableType::Type inBaseType =
1005*35238bceSAndroid Build Coastguard Worker         state.getRandom().choose<VariableType::Type>(&inBaseTypes[0], &inBaseTypes[DE_LENGTH_OF_ARRAY(inBaseTypes)]);
1006*35238bceSAndroid Build Coastguard Worker     int availableLevels = state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
1007*35238bceSAndroid Build Coastguard Worker     int numElements     = state.getRandom().getInt(1, availableLevels >= 3 ? 4 : 1);
1008*35238bceSAndroid Build Coastguard Worker 
1009*35238bceSAndroid Build Coastguard Worker     // Initialize storage for input value ranges
1010*35238bceSAndroid Build Coastguard Worker     this->m_rightValueRange = ValueRange(VariableType(inBaseType, numElements));
1011*35238bceSAndroid Build Coastguard Worker     this->m_leftValueRange  = ValueRange(VariableType(inBaseType, numElements));
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker     // Compute range for b that satisfies requested value range
1014*35238bceSAndroid Build Coastguard Worker     for (int elementNdx = 0; elementNdx < numElements; elementNdx++)
1015*35238bceSAndroid Build Coastguard Worker     {
1016*35238bceSAndroid Build Coastguard Worker         bool dstMin = valueRange.getMin().asBool();
1017*35238bceSAndroid Build Coastguard Worker         bool dstMax = valueRange.getMax().asBool();
1018*35238bceSAndroid Build Coastguard Worker 
1019*35238bceSAndroid Build Coastguard Worker         ValueRangeAccess a = this->m_leftValueRange.asAccess().component(elementNdx);
1020*35238bceSAndroid Build Coastguard Worker         ValueRangeAccess b = this->m_rightValueRange.asAccess().component(elementNdx);
1021*35238bceSAndroid Build Coastguard Worker 
1022*35238bceSAndroid Build Coastguard Worker         if (inBaseType == VariableType::TYPE_FLOAT)
1023*35238bceSAndroid Build Coastguard Worker             computeEqualityValueRange<IsEqual>(state.getRandom(), dstMin, dstMax, a.getMin().asFloat(),
1024*35238bceSAndroid Build Coastguard Worker                                                a.getMax().asFloat(), b.getMin().asFloat(), b.getMax().asFloat());
1025*35238bceSAndroid Build Coastguard Worker         else if (inBaseType == VariableType::TYPE_INT)
1026*35238bceSAndroid Build Coastguard Worker             computeEqualityValueRange<IsEqual>(state.getRandom(), dstMin, dstMax, a.getMin().asInt(),
1027*35238bceSAndroid Build Coastguard Worker                                                a.getMax().asInt(), b.getMin().asInt(), b.getMax().asInt());
1028*35238bceSAndroid Build Coastguard Worker         else
1029*35238bceSAndroid Build Coastguard Worker         {
1030*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(inBaseType == VariableType::TYPE_BOOL);
1031*35238bceSAndroid Build Coastguard Worker             computeEqualityValueRange<IsEqual>(state.getRandom(), dstMin, dstMax, a.getMin().asBool(),
1032*35238bceSAndroid Build Coastguard Worker                                                a.getMax().asBool(), b.getMin().asBool(), b.getMax().asBool());
1033*35238bceSAndroid Build Coastguard Worker         }
1034*35238bceSAndroid Build Coastguard Worker     }
1035*35238bceSAndroid Build Coastguard Worker }
1036*35238bceSAndroid Build Coastguard Worker 
1037*35238bceSAndroid Build Coastguard Worker template <bool IsEqual>
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)1038*35238bceSAndroid Build Coastguard Worker float EqualityComparisonOp<IsEqual>::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
1039*35238bceSAndroid Build Coastguard Worker {
1040*35238bceSAndroid Build Coastguard Worker     if (!state.getProgramParameters().useComparisonOps)
1041*35238bceSAndroid Build Coastguard Worker         return 0.0f;
1042*35238bceSAndroid Build Coastguard Worker 
1043*35238bceSAndroid Build Coastguard Worker     // \todo [2011-06-13 pyry] Weight down cases that would force constant inputs.
1044*35238bceSAndroid Build Coastguard Worker 
1045*35238bceSAndroid Build Coastguard Worker     if (valueRange.getType().isVoid() ||
1046*35238bceSAndroid Build Coastguard Worker         (valueRange.getType().getBaseType() == VariableType::TYPE_BOOL && valueRange.getType().getNumElements() == 1))
1047*35238bceSAndroid Build Coastguard Worker         return BinaryOp<8, ASSOCIATIVITY_LEFT>::getWeight(state, valueRange);
1048*35238bceSAndroid Build Coastguard Worker     else
1049*35238bceSAndroid Build Coastguard Worker         return 0.0f;
1050*35238bceSAndroid Build Coastguard Worker }
1051*35238bceSAndroid Build Coastguard Worker 
1052*35238bceSAndroid Build Coastguard Worker namespace
1053*35238bceSAndroid Build Coastguard Worker {
1054*35238bceSAndroid Build Coastguard Worker 
1055*35238bceSAndroid Build Coastguard Worker template <bool IsEqual>
1056*35238bceSAndroid Build Coastguard Worker struct EqualityCompare
1057*35238bceSAndroid Build Coastguard Worker {
1058*35238bceSAndroid Build Coastguard Worker     template <typename T>
1059*35238bceSAndroid Build Coastguard Worker     static bool compare(T a, T b);
1060*35238bceSAndroid Build Coastguard Worker     static bool combine(bool a, bool b);
1061*35238bceSAndroid Build Coastguard Worker };
1062*35238bceSAndroid Build Coastguard Worker 
1063*35238bceSAndroid Build Coastguard Worker template <>
1064*35238bceSAndroid Build Coastguard Worker template <typename T>
compare(T a,T b)1065*35238bceSAndroid Build Coastguard Worker inline bool EqualityCompare<true>::compare(T a, T b)
1066*35238bceSAndroid Build Coastguard Worker {
1067*35238bceSAndroid Build Coastguard Worker     return a == b;
1068*35238bceSAndroid Build Coastguard Worker }
1069*35238bceSAndroid Build Coastguard Worker 
1070*35238bceSAndroid Build Coastguard Worker template <>
combine(bool a,bool b)1071*35238bceSAndroid Build Coastguard Worker inline bool EqualityCompare<true>::combine(bool a, bool b)
1072*35238bceSAndroid Build Coastguard Worker {
1073*35238bceSAndroid Build Coastguard Worker     return a && b;
1074*35238bceSAndroid Build Coastguard Worker }
1075*35238bceSAndroid Build Coastguard Worker 
1076*35238bceSAndroid Build Coastguard Worker template <>
1077*35238bceSAndroid Build Coastguard Worker template <typename T>
compare(T a,T b)1078*35238bceSAndroid Build Coastguard Worker inline bool EqualityCompare<false>::compare(T a, T b)
1079*35238bceSAndroid Build Coastguard Worker {
1080*35238bceSAndroid Build Coastguard Worker     return a != b;
1081*35238bceSAndroid Build Coastguard Worker }
1082*35238bceSAndroid Build Coastguard Worker 
1083*35238bceSAndroid Build Coastguard Worker template <>
combine(bool a,bool b)1084*35238bceSAndroid Build Coastguard Worker inline bool EqualityCompare<false>::combine(bool a, bool b)
1085*35238bceSAndroid Build Coastguard Worker {
1086*35238bceSAndroid Build Coastguard Worker     return a || b;
1087*35238bceSAndroid Build Coastguard Worker }
1088*35238bceSAndroid Build Coastguard Worker 
1089*35238bceSAndroid Build Coastguard Worker } // namespace
1090*35238bceSAndroid Build Coastguard Worker 
1091*35238bceSAndroid Build Coastguard Worker template <bool IsEqual>
evaluate(ExecValueAccess dst,ExecConstValueAccess a,ExecConstValueAccess b)1092*35238bceSAndroid Build Coastguard Worker void EqualityComparisonOp<IsEqual>::evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b)
1093*35238bceSAndroid Build Coastguard Worker {
1094*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(a.getType() == b.getType());
1095*35238bceSAndroid Build Coastguard Worker 
1096*35238bceSAndroid Build Coastguard Worker     switch (a.getType().getBaseType())
1097*35238bceSAndroid Build Coastguard Worker     {
1098*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_FLOAT:
1099*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
1100*35238bceSAndroid Build Coastguard Worker         {
1101*35238bceSAndroid Build Coastguard Worker             bool result = IsEqual ? true : false;
1102*35238bceSAndroid Build Coastguard Worker 
1103*35238bceSAndroid Build Coastguard Worker             for (int elemNdx = 0; elemNdx < a.getType().getNumElements(); elemNdx++)
1104*35238bceSAndroid Build Coastguard Worker                 result = EqualityCompare<IsEqual>::combine(
1105*35238bceSAndroid Build Coastguard Worker                     result, EqualityCompare<IsEqual>::compare(a.component(elemNdx).asFloat(compNdx),
1106*35238bceSAndroid Build Coastguard Worker                                                               b.component(elemNdx).asFloat(compNdx)));
1107*35238bceSAndroid Build Coastguard Worker 
1108*35238bceSAndroid Build Coastguard Worker             dst.asBool(compNdx) = result;
1109*35238bceSAndroid Build Coastguard Worker         }
1110*35238bceSAndroid Build Coastguard Worker         break;
1111*35238bceSAndroid Build Coastguard Worker 
1112*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_INT:
1113*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
1114*35238bceSAndroid Build Coastguard Worker         {
1115*35238bceSAndroid Build Coastguard Worker             bool result = IsEqual ? true : false;
1116*35238bceSAndroid Build Coastguard Worker 
1117*35238bceSAndroid Build Coastguard Worker             for (int elemNdx = 0; elemNdx < a.getType().getNumElements(); elemNdx++)
1118*35238bceSAndroid Build Coastguard Worker                 result = EqualityCompare<IsEqual>::combine(
1119*35238bceSAndroid Build Coastguard Worker                     result, EqualityCompare<IsEqual>::compare(a.component(elemNdx).asInt(compNdx),
1120*35238bceSAndroid Build Coastguard Worker                                                               b.component(elemNdx).asInt(compNdx)));
1121*35238bceSAndroid Build Coastguard Worker 
1122*35238bceSAndroid Build Coastguard Worker             dst.asBool(compNdx) = result;
1123*35238bceSAndroid Build Coastguard Worker         }
1124*35238bceSAndroid Build Coastguard Worker         break;
1125*35238bceSAndroid Build Coastguard Worker 
1126*35238bceSAndroid Build Coastguard Worker     case VariableType::TYPE_BOOL:
1127*35238bceSAndroid Build Coastguard Worker         for (int compNdx = 0; compNdx < EXEC_VEC_WIDTH; compNdx++)
1128*35238bceSAndroid Build Coastguard Worker         {
1129*35238bceSAndroid Build Coastguard Worker             bool result = IsEqual ? true : false;
1130*35238bceSAndroid Build Coastguard Worker 
1131*35238bceSAndroid Build Coastguard Worker             for (int elemNdx = 0; elemNdx < a.getType().getNumElements(); elemNdx++)
1132*35238bceSAndroid Build Coastguard Worker                 result = EqualityCompare<IsEqual>::combine(
1133*35238bceSAndroid Build Coastguard Worker                     result, EqualityCompare<IsEqual>::compare(a.component(elemNdx).asBool(compNdx),
1134*35238bceSAndroid Build Coastguard Worker                                                               b.component(elemNdx).asBool(compNdx)));
1135*35238bceSAndroid Build Coastguard Worker 
1136*35238bceSAndroid Build Coastguard Worker             dst.asBool(compNdx) = result;
1137*35238bceSAndroid Build Coastguard Worker         }
1138*35238bceSAndroid Build Coastguard Worker         break;
1139*35238bceSAndroid Build Coastguard Worker 
1140*35238bceSAndroid Build Coastguard Worker     default:
1141*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1142*35238bceSAndroid Build Coastguard Worker     }
1143*35238bceSAndroid Build Coastguard Worker }
1144*35238bceSAndroid Build Coastguard Worker 
EqualOp(GeneratorState & state,ConstValueRangeAccess valueRange)1145*35238bceSAndroid Build Coastguard Worker EqualOp::EqualOp(GeneratorState &state, ConstValueRangeAccess valueRange)
1146*35238bceSAndroid Build Coastguard Worker     : EqualityComparisonOp<true>(state, valueRange)
1147*35238bceSAndroid Build Coastguard Worker {
1148*35238bceSAndroid Build Coastguard Worker }
1149*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)1150*35238bceSAndroid Build Coastguard Worker float EqualOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
1151*35238bceSAndroid Build Coastguard Worker {
1152*35238bceSAndroid Build Coastguard Worker     return EqualityComparisonOp<true>::getWeight(state, valueRange);
1153*35238bceSAndroid Build Coastguard Worker }
1154*35238bceSAndroid Build Coastguard Worker 
NotEqualOp(GeneratorState & state,ConstValueRangeAccess valueRange)1155*35238bceSAndroid Build Coastguard Worker NotEqualOp::NotEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange)
1156*35238bceSAndroid Build Coastguard Worker     : EqualityComparisonOp<false>(state, valueRange)
1157*35238bceSAndroid Build Coastguard Worker {
1158*35238bceSAndroid Build Coastguard Worker }
1159*35238bceSAndroid Build Coastguard Worker 
getWeight(const GeneratorState & state,ConstValueRangeAccess valueRange)1160*35238bceSAndroid Build Coastguard Worker float NotEqualOp::getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange)
1161*35238bceSAndroid Build Coastguard Worker {
1162*35238bceSAndroid Build Coastguard Worker     return EqualityComparisonOp<false>::getWeight(state, valueRange);
1163*35238bceSAndroid Build Coastguard Worker }
1164*35238bceSAndroid Build Coastguard Worker 
1165*35238bceSAndroid Build Coastguard Worker } // namespace rsg
1166