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