1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL (ES) Module
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 Precision and range tests for GLSL builtins and types.
22*35238bceSAndroid Build Coastguard Worker *
23*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
24*35238bceSAndroid Build Coastguard Worker
25*35238bceSAndroid Build Coastguard Worker #include "glsBuiltinPrecisionTests.hpp"
26*35238bceSAndroid Build Coastguard Worker
27*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
28*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
29*35238bceSAndroid Build Coastguard Worker #include "deDefs.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deSTLUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "deSharedPtr.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "deArrayUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "tcuFloatFormat.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "tcuInterval.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "tcuTestCase.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "tcuMatrix.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "tcuResultCollector.hpp"
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "gluVarType.hpp"
48*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
49*35238bceSAndroid Build Coastguard Worker #include "glwDefs.hpp"
50*35238bceSAndroid Build Coastguard Worker
51*35238bceSAndroid Build Coastguard Worker #include "glsShaderExecUtil.hpp"
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker #include <cmath>
54*35238bceSAndroid Build Coastguard Worker #include <string>
55*35238bceSAndroid Build Coastguard Worker #include <sstream>
56*35238bceSAndroid Build Coastguard Worker #include <iostream>
57*35238bceSAndroid Build Coastguard Worker #include <map>
58*35238bceSAndroid Build Coastguard Worker #include <utility>
59*35238bceSAndroid Build Coastguard Worker #include <limits>
60*35238bceSAndroid Build Coastguard Worker
61*35238bceSAndroid Build Coastguard Worker // Uncomment this to get evaluation trace dumps to std::cerr
62*35238bceSAndroid Build Coastguard Worker // #define GLS_ENABLE_TRACE
63*35238bceSAndroid Build Coastguard Worker
64*35238bceSAndroid Build Coastguard Worker // set this to true to dump even passing results
65*35238bceSAndroid Build Coastguard Worker #define GLS_LOG_ALL_RESULTS false
66*35238bceSAndroid Build Coastguard Worker
67*35238bceSAndroid Build Coastguard Worker enum
68*35238bceSAndroid Build Coastguard Worker {
69*35238bceSAndroid Build Coastguard Worker // Computing reference intervals can take a non-trivial amount of time, especially on
70*35238bceSAndroid Build Coastguard Worker // platforms where toggling floating-point rounding mode is slow (emulated arm on x86).
71*35238bceSAndroid Build Coastguard Worker // As a workaround watchdog is kept happy by touching it periodically during reference
72*35238bceSAndroid Build Coastguard Worker // interval computation.
73*35238bceSAndroid Build Coastguard Worker TOUCH_WATCHDOG_VALUE_FREQUENCY = 4096
74*35238bceSAndroid Build Coastguard Worker };
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Worker namespace deqp
77*35238bceSAndroid Build Coastguard Worker {
78*35238bceSAndroid Build Coastguard Worker namespace gls
79*35238bceSAndroid Build Coastguard Worker {
80*35238bceSAndroid Build Coastguard Worker namespace BuiltinPrecisionTests
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker
83*35238bceSAndroid Build Coastguard Worker using std::map;
84*35238bceSAndroid Build Coastguard Worker using std::ostream;
85*35238bceSAndroid Build Coastguard Worker using std::ostringstream;
86*35238bceSAndroid Build Coastguard Worker using std::pair;
87*35238bceSAndroid Build Coastguard Worker using std::set;
88*35238bceSAndroid Build Coastguard Worker using std::string;
89*35238bceSAndroid Build Coastguard Worker using std::vector;
90*35238bceSAndroid Build Coastguard Worker
91*35238bceSAndroid Build Coastguard Worker using de::MovePtr;
92*35238bceSAndroid Build Coastguard Worker using de::Random;
93*35238bceSAndroid Build Coastguard Worker using de::SharedPtr;
94*35238bceSAndroid Build Coastguard Worker using de::UniquePtr;
95*35238bceSAndroid Build Coastguard Worker using tcu::FloatFormat;
96*35238bceSAndroid Build Coastguard Worker using tcu::Interval;
97*35238bceSAndroid Build Coastguard Worker using tcu::Matrix;
98*35238bceSAndroid Build Coastguard Worker using tcu::MessageBuilder;
99*35238bceSAndroid Build Coastguard Worker using tcu::TestCase;
100*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
101*35238bceSAndroid Build Coastguard Worker using tcu::Vector;
102*35238bceSAndroid Build Coastguard Worker namespace matrix = tcu::matrix;
103*35238bceSAndroid Build Coastguard Worker using gls::ShaderExecUtil::Symbol;
104*35238bceSAndroid Build Coastguard Worker using glu::ContextInfo;
105*35238bceSAndroid Build Coastguard Worker using glu::DataType;
106*35238bceSAndroid Build Coastguard Worker using glu::Precision;
107*35238bceSAndroid Build Coastguard Worker using glu::RenderContext;
108*35238bceSAndroid Build Coastguard Worker using glu::ShaderType;
109*35238bceSAndroid Build Coastguard Worker using glu::VarType;
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker typedef TestCase::IterateResult IterateResult;
112*35238bceSAndroid Build Coastguard Worker
113*35238bceSAndroid Build Coastguard Worker using namespace glw;
114*35238bceSAndroid Build Coastguard Worker using namespace tcu;
115*35238bceSAndroid Build Coastguard Worker
116*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
117*35238bceSAndroid Build Coastguard Worker * \brief Generic singleton creator.
118*35238bceSAndroid Build Coastguard Worker *
119*35238bceSAndroid Build Coastguard Worker * instance<T>() returns a reference to a unique default-constructed instance
120*35238bceSAndroid Build Coastguard Worker * of T. This is mainly used for our GLSL function implementations: each
121*35238bceSAndroid Build Coastguard Worker * function is implemented by an object, and each of the objects has a
122*35238bceSAndroid Build Coastguard Worker * distinct class. It would be extremely toilsome to maintain a separate
123*35238bceSAndroid Build Coastguard Worker * context object that contained individual instances of the function classes,
124*35238bceSAndroid Build Coastguard Worker * so we have to resort to global singleton instances.
125*35238bceSAndroid Build Coastguard Worker *
126*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
127*35238bceSAndroid Build Coastguard Worker template <typename T>
instance(void)128*35238bceSAndroid Build Coastguard Worker const T &instance(void)
129*35238bceSAndroid Build Coastguard Worker {
130*35238bceSAndroid Build Coastguard Worker static const T s_instance = T();
131*35238bceSAndroid Build Coastguard Worker return s_instance;
132*35238bceSAndroid Build Coastguard Worker }
133*35238bceSAndroid Build Coastguard Worker
134*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
135*35238bceSAndroid Build Coastguard Worker * \brief A placeholder type for unused template parameters.
136*35238bceSAndroid Build Coastguard Worker *
137*35238bceSAndroid Build Coastguard Worker * In the precision tests we are dealing with functions of different arities.
138*35238bceSAndroid Build Coastguard Worker * To minimize code duplication, we only define templates with the maximum
139*35238bceSAndroid Build Coastguard Worker * number of arguments, currently four. If a function's arity is less than the
140*35238bceSAndroid Build Coastguard Worker * maximum, Void us used as the type for unused arguments.
141*35238bceSAndroid Build Coastguard Worker *
142*35238bceSAndroid Build Coastguard Worker * Although Voids are not used at run-time, they still must be compilable, so
143*35238bceSAndroid Build Coastguard Worker * they must support all operations that other types do.
144*35238bceSAndroid Build Coastguard Worker *
145*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
146*35238bceSAndroid Build Coastguard Worker struct Void
147*35238bceSAndroid Build Coastguard Worker {
148*35238bceSAndroid Build Coastguard Worker typedef Void Element;
149*35238bceSAndroid Build Coastguard Worker enum
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker SIZE = 0,
152*35238bceSAndroid Build Coastguard Worker };
153*35238bceSAndroid Build Coastguard Worker
154*35238bceSAndroid Build Coastguard Worker template <typename T>
Voiddeqp::gls::BuiltinPrecisionTests::Void155*35238bceSAndroid Build Coastguard Worker explicit Void(const T &)
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker }
Voiddeqp::gls::BuiltinPrecisionTests::Void158*35238bceSAndroid Build Coastguard Worker Void(void)
159*35238bceSAndroid Build Coastguard Worker {
160*35238bceSAndroid Build Coastguard Worker }
operator doubledeqp::gls::BuiltinPrecisionTests::Void161*35238bceSAndroid Build Coastguard Worker operator double(void) const
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker return TCU_NAN;
164*35238bceSAndroid Build Coastguard Worker }
165*35238bceSAndroid Build Coastguard Worker
166*35238bceSAndroid Build Coastguard Worker // These are used to make Voids usable as containers in container-generic code.
operator []deqp::gls::BuiltinPrecisionTests::Void167*35238bceSAndroid Build Coastguard Worker Void &operator[](int)
168*35238bceSAndroid Build Coastguard Worker {
169*35238bceSAndroid Build Coastguard Worker return *this;
170*35238bceSAndroid Build Coastguard Worker }
operator []deqp::gls::BuiltinPrecisionTests::Void171*35238bceSAndroid Build Coastguard Worker const Void &operator[](int) const
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker return *this;
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker };
176*35238bceSAndroid Build Coastguard Worker
operator <<(ostream & os,Void)177*35238bceSAndroid Build Coastguard Worker ostream &operator<<(ostream &os, Void)
178*35238bceSAndroid Build Coastguard Worker {
179*35238bceSAndroid Build Coastguard Worker return os << "()";
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker
182*35238bceSAndroid Build Coastguard Worker //! Returns true for all other types except Void
183*35238bceSAndroid Build Coastguard Worker template <typename T>
isTypeValid(void)184*35238bceSAndroid Build Coastguard Worker bool isTypeValid(void)
185*35238bceSAndroid Build Coastguard Worker {
186*35238bceSAndroid Build Coastguard Worker return true;
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker template <>
isTypeValid(void)189*35238bceSAndroid Build Coastguard Worker bool isTypeValid<Void>(void)
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker return false;
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker
194*35238bceSAndroid Build Coastguard Worker //! Utility function for getting the name of a data type.
195*35238bceSAndroid Build Coastguard Worker //! This is used in vector and matrix constructors.
196*35238bceSAndroid Build Coastguard Worker template <typename T>
dataTypeNameOf(void)197*35238bceSAndroid Build Coastguard Worker const char *dataTypeNameOf(void)
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker return glu::getDataTypeName(glu::dataTypeOf<T>());
200*35238bceSAndroid Build Coastguard Worker }
201*35238bceSAndroid Build Coastguard Worker
202*35238bceSAndroid Build Coastguard Worker template <>
dataTypeNameOf(void)203*35238bceSAndroid Build Coastguard Worker const char *dataTypeNameOf<Void>(void)
204*35238bceSAndroid Build Coastguard Worker {
205*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
206*35238bceSAndroid Build Coastguard Worker return DE_NULL;
207*35238bceSAndroid Build Coastguard Worker }
208*35238bceSAndroid Build Coastguard Worker
209*35238bceSAndroid Build Coastguard Worker //! A hack to get Void support for VarType.
210*35238bceSAndroid Build Coastguard Worker template <typename T>
getVarTypeOf(Precision prec=glu::PRECISION_LAST)211*35238bceSAndroid Build Coastguard Worker VarType getVarTypeOf(Precision prec = glu::PRECISION_LAST)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker return glu::varTypeOf<T>(prec);
214*35238bceSAndroid Build Coastguard Worker }
215*35238bceSAndroid Build Coastguard Worker
216*35238bceSAndroid Build Coastguard Worker template <>
getVarTypeOf(Precision)217*35238bceSAndroid Build Coastguard Worker VarType getVarTypeOf<Void>(Precision)
218*35238bceSAndroid Build Coastguard Worker {
219*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
220*35238bceSAndroid Build Coastguard Worker return VarType();
221*35238bceSAndroid Build Coastguard Worker }
222*35238bceSAndroid Build Coastguard Worker
223*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
224*35238bceSAndroid Build Coastguard Worker * \brief Type traits for generalized interval types.
225*35238bceSAndroid Build Coastguard Worker *
226*35238bceSAndroid Build Coastguard Worker * We are trying to compute sets of acceptable values not only for
227*35238bceSAndroid Build Coastguard Worker * float-valued expressions but also for compound values: vectors and
228*35238bceSAndroid Build Coastguard Worker * matrices. We approximate a set of vectors as a vector of intervals and
229*35238bceSAndroid Build Coastguard Worker * likewise for matrices.
230*35238bceSAndroid Build Coastguard Worker *
231*35238bceSAndroid Build Coastguard Worker * We now need generalized operations for each type and its interval
232*35238bceSAndroid Build Coastguard Worker * approximation. These are given in the type Traits<T>.
233*35238bceSAndroid Build Coastguard Worker *
234*35238bceSAndroid Build Coastguard Worker * The type Traits<T>::IVal is the approximation of T: it is `Interval` for
235*35238bceSAndroid Build Coastguard Worker * scalar types, and a vector or matrix of intervals for container types.
236*35238bceSAndroid Build Coastguard Worker *
237*35238bceSAndroid Build Coastguard Worker * To allow template inference to take place, there are function wrappers for
238*35238bceSAndroid Build Coastguard Worker * the actual operations in Traits<T>. Hence we can just use:
239*35238bceSAndroid Build Coastguard Worker *
240*35238bceSAndroid Build Coastguard Worker * makeIVal(someFloat)
241*35238bceSAndroid Build Coastguard Worker *
242*35238bceSAndroid Build Coastguard Worker * instead of:
243*35238bceSAndroid Build Coastguard Worker *
244*35238bceSAndroid Build Coastguard Worker * Traits<float>::doMakeIVal(value)
245*35238bceSAndroid Build Coastguard Worker *
246*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
247*35238bceSAndroid Build Coastguard Worker
248*35238bceSAndroid Build Coastguard Worker template <typename T>
249*35238bceSAndroid Build Coastguard Worker struct Traits;
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker //! Create container from elementwise singleton values.
252*35238bceSAndroid Build Coastguard Worker template <typename T>
makeIVal(const T & value)253*35238bceSAndroid Build Coastguard Worker typename Traits<T>::IVal makeIVal(const T &value)
254*35238bceSAndroid Build Coastguard Worker {
255*35238bceSAndroid Build Coastguard Worker return Traits<T>::doMakeIVal(value);
256*35238bceSAndroid Build Coastguard Worker }
257*35238bceSAndroid Build Coastguard Worker
258*35238bceSAndroid Build Coastguard Worker //! Elementwise union of intervals.
259*35238bceSAndroid Build Coastguard Worker template <typename T>
unionIVal(const typename Traits<T>::IVal & a,const typename Traits<T>::IVal & b)260*35238bceSAndroid Build Coastguard Worker typename Traits<T>::IVal unionIVal(const typename Traits<T>::IVal &a, const typename Traits<T>::IVal &b)
261*35238bceSAndroid Build Coastguard Worker {
262*35238bceSAndroid Build Coastguard Worker return Traits<T>::doUnion(a, b);
263*35238bceSAndroid Build Coastguard Worker }
264*35238bceSAndroid Build Coastguard Worker
265*35238bceSAndroid Build Coastguard Worker //! Returns true iff every element of `ival` contains the corresponding element of `value`.
266*35238bceSAndroid Build Coastguard Worker template <typename T>
contains(const typename Traits<T>::IVal & ival,const T & value)267*35238bceSAndroid Build Coastguard Worker bool contains(const typename Traits<T>::IVal &ival, const T &value)
268*35238bceSAndroid Build Coastguard Worker {
269*35238bceSAndroid Build Coastguard Worker return Traits<T>::doContains(ival, value);
270*35238bceSAndroid Build Coastguard Worker }
271*35238bceSAndroid Build Coastguard Worker
272*35238bceSAndroid Build Coastguard Worker //! Returns true iff every element of `ival` contains corresponding element of `value` within the warning interval
273*35238bceSAndroid Build Coastguard Worker template <typename T>
containsWarning(const typename Traits<T>::IVal & ival,const T & value)274*35238bceSAndroid Build Coastguard Worker bool containsWarning(const typename Traits<T>::IVal &ival, const T &value)
275*35238bceSAndroid Build Coastguard Worker {
276*35238bceSAndroid Build Coastguard Worker return Traits<T>::doContainsWarning(ival, value);
277*35238bceSAndroid Build Coastguard Worker }
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker //! Print out an interval with the precision of `fmt`.
280*35238bceSAndroid Build Coastguard Worker template <typename T>
printIVal(const FloatFormat & fmt,const typename Traits<T>::IVal & ival,ostream & os)281*35238bceSAndroid Build Coastguard Worker void printIVal(const FloatFormat &fmt, const typename Traits<T>::IVal &ival, ostream &os)
282*35238bceSAndroid Build Coastguard Worker {
283*35238bceSAndroid Build Coastguard Worker Traits<T>::doPrintIVal(fmt, ival, os);
284*35238bceSAndroid Build Coastguard Worker }
285*35238bceSAndroid Build Coastguard Worker
286*35238bceSAndroid Build Coastguard Worker template <typename T>
intervalToString(const FloatFormat & fmt,const typename Traits<T>::IVal & ival)287*35238bceSAndroid Build Coastguard Worker string intervalToString(const FloatFormat &fmt, const typename Traits<T>::IVal &ival)
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker ostringstream oss;
290*35238bceSAndroid Build Coastguard Worker printIVal<T>(fmt, ival, oss);
291*35238bceSAndroid Build Coastguard Worker return oss.str();
292*35238bceSAndroid Build Coastguard Worker }
293*35238bceSAndroid Build Coastguard Worker
294*35238bceSAndroid Build Coastguard Worker //! Print out a value with the precision of `fmt`.
295*35238bceSAndroid Build Coastguard Worker template <typename T>
printValue(const FloatFormat & fmt,const T & value,ostream & os)296*35238bceSAndroid Build Coastguard Worker void printValue(const FloatFormat &fmt, const T &value, ostream &os)
297*35238bceSAndroid Build Coastguard Worker {
298*35238bceSAndroid Build Coastguard Worker Traits<T>::doPrintValue(fmt, value, os);
299*35238bceSAndroid Build Coastguard Worker }
300*35238bceSAndroid Build Coastguard Worker
301*35238bceSAndroid Build Coastguard Worker template <typename T>
valueToString(const FloatFormat & fmt,const T & val)302*35238bceSAndroid Build Coastguard Worker string valueToString(const FloatFormat &fmt, const T &val)
303*35238bceSAndroid Build Coastguard Worker {
304*35238bceSAndroid Build Coastguard Worker ostringstream oss;
305*35238bceSAndroid Build Coastguard Worker printValue(fmt, val, oss);
306*35238bceSAndroid Build Coastguard Worker return oss.str();
307*35238bceSAndroid Build Coastguard Worker }
308*35238bceSAndroid Build Coastguard Worker
309*35238bceSAndroid Build Coastguard Worker //! Approximate `value` elementwise to the float precision defined in `fmt`.
310*35238bceSAndroid Build Coastguard Worker //! The resulting interval might not be a singleton if rounding in both
311*35238bceSAndroid Build Coastguard Worker //! directions is allowed.
312*35238bceSAndroid Build Coastguard Worker template <typename T>
round(const FloatFormat & fmt,const T & value)313*35238bceSAndroid Build Coastguard Worker typename Traits<T>::IVal round(const FloatFormat &fmt, const T &value)
314*35238bceSAndroid Build Coastguard Worker {
315*35238bceSAndroid Build Coastguard Worker return Traits<T>::doRound(fmt, value);
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker
318*35238bceSAndroid Build Coastguard Worker template <typename T>
convert(const FloatFormat & fmt,const typename Traits<T>::IVal & value)319*35238bceSAndroid Build Coastguard Worker typename Traits<T>::IVal convert(const FloatFormat &fmt, const typename Traits<T>::IVal &value)
320*35238bceSAndroid Build Coastguard Worker {
321*35238bceSAndroid Build Coastguard Worker return Traits<T>::doConvert(fmt, value);
322*35238bceSAndroid Build Coastguard Worker }
323*35238bceSAndroid Build Coastguard Worker
324*35238bceSAndroid Build Coastguard Worker //! Common traits for scalar types.
325*35238bceSAndroid Build Coastguard Worker template <typename T>
326*35238bceSAndroid Build Coastguard Worker struct ScalarTraits
327*35238bceSAndroid Build Coastguard Worker {
328*35238bceSAndroid Build Coastguard Worker typedef Interval IVal;
329*35238bceSAndroid Build Coastguard Worker
doMakeIValdeqp::gls::BuiltinPrecisionTests::ScalarTraits330*35238bceSAndroid Build Coastguard Worker static Interval doMakeIVal(const T &value)
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker // Thankfully all scalar types have a well-defined conversion to `double`,
333*35238bceSAndroid Build Coastguard Worker // hence Interval can represent their ranges without problems.
334*35238bceSAndroid Build Coastguard Worker return Interval(double(value));
335*35238bceSAndroid Build Coastguard Worker }
336*35238bceSAndroid Build Coastguard Worker
doUniondeqp::gls::BuiltinPrecisionTests::ScalarTraits337*35238bceSAndroid Build Coastguard Worker static Interval doUnion(const Interval &a, const Interval &b)
338*35238bceSAndroid Build Coastguard Worker {
339*35238bceSAndroid Build Coastguard Worker return a | b;
340*35238bceSAndroid Build Coastguard Worker }
341*35238bceSAndroid Build Coastguard Worker
doContainsdeqp::gls::BuiltinPrecisionTests::ScalarTraits342*35238bceSAndroid Build Coastguard Worker static bool doContains(const Interval &a, T value)
343*35238bceSAndroid Build Coastguard Worker {
344*35238bceSAndroid Build Coastguard Worker return a.contains(double(value));
345*35238bceSAndroid Build Coastguard Worker }
346*35238bceSAndroid Build Coastguard Worker
doContainsWarningdeqp::gls::BuiltinPrecisionTests::ScalarTraits347*35238bceSAndroid Build Coastguard Worker static bool doContainsWarning(const Interval &a, T value)
348*35238bceSAndroid Build Coastguard Worker {
349*35238bceSAndroid Build Coastguard Worker return a.containsWarning(double(value));
350*35238bceSAndroid Build Coastguard Worker }
351*35238bceSAndroid Build Coastguard Worker
doConvertdeqp::gls::BuiltinPrecisionTests::ScalarTraits352*35238bceSAndroid Build Coastguard Worker static Interval doConvert(const FloatFormat &fmt, const IVal &ival)
353*35238bceSAndroid Build Coastguard Worker {
354*35238bceSAndroid Build Coastguard Worker return fmt.convert(ival);
355*35238bceSAndroid Build Coastguard Worker }
356*35238bceSAndroid Build Coastguard Worker
doRounddeqp::gls::BuiltinPrecisionTests::ScalarTraits357*35238bceSAndroid Build Coastguard Worker static Interval doRound(const FloatFormat &fmt, T value)
358*35238bceSAndroid Build Coastguard Worker {
359*35238bceSAndroid Build Coastguard Worker return fmt.roundOut(double(value), false);
360*35238bceSAndroid Build Coastguard Worker }
361*35238bceSAndroid Build Coastguard Worker };
362*35238bceSAndroid Build Coastguard Worker
363*35238bceSAndroid Build Coastguard Worker template <>
364*35238bceSAndroid Build Coastguard Worker struct Traits<float> : ScalarTraits<float>
365*35238bceSAndroid Build Coastguard Worker {
doPrintIValdeqp::gls::BuiltinPrecisionTests::Traits366*35238bceSAndroid Build Coastguard Worker static void doPrintIVal(const FloatFormat &fmt, const Interval &ival, ostream &os)
367*35238bceSAndroid Build Coastguard Worker {
368*35238bceSAndroid Build Coastguard Worker os << fmt.intervalToHex(ival);
369*35238bceSAndroid Build Coastguard Worker }
370*35238bceSAndroid Build Coastguard Worker
doPrintValuedeqp::gls::BuiltinPrecisionTests::Traits371*35238bceSAndroid Build Coastguard Worker static void doPrintValue(const FloatFormat &fmt, const float &value, ostream &os)
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker os << fmt.floatToHex(value);
374*35238bceSAndroid Build Coastguard Worker }
375*35238bceSAndroid Build Coastguard Worker };
376*35238bceSAndroid Build Coastguard Worker
377*35238bceSAndroid Build Coastguard Worker template <>
378*35238bceSAndroid Build Coastguard Worker struct Traits<bool> : ScalarTraits<bool>
379*35238bceSAndroid Build Coastguard Worker {
doPrintValuedeqp::gls::BuiltinPrecisionTests::Traits380*35238bceSAndroid Build Coastguard Worker static void doPrintValue(const FloatFormat &, const float &value, ostream &os)
381*35238bceSAndroid Build Coastguard Worker {
382*35238bceSAndroid Build Coastguard Worker os << (value != 0.0f ? "true" : "false");
383*35238bceSAndroid Build Coastguard Worker }
384*35238bceSAndroid Build Coastguard Worker
doPrintIValdeqp::gls::BuiltinPrecisionTests::Traits385*35238bceSAndroid Build Coastguard Worker static void doPrintIVal(const FloatFormat &, const Interval &ival, ostream &os)
386*35238bceSAndroid Build Coastguard Worker {
387*35238bceSAndroid Build Coastguard Worker os << "{";
388*35238bceSAndroid Build Coastguard Worker if (ival.contains(false))
389*35238bceSAndroid Build Coastguard Worker os << "false";
390*35238bceSAndroid Build Coastguard Worker if (ival.contains(false) && ival.contains(true))
391*35238bceSAndroid Build Coastguard Worker os << ", ";
392*35238bceSAndroid Build Coastguard Worker if (ival.contains(true))
393*35238bceSAndroid Build Coastguard Worker os << "true";
394*35238bceSAndroid Build Coastguard Worker os << "}";
395*35238bceSAndroid Build Coastguard Worker }
396*35238bceSAndroid Build Coastguard Worker };
397*35238bceSAndroid Build Coastguard Worker
398*35238bceSAndroid Build Coastguard Worker template <>
399*35238bceSAndroid Build Coastguard Worker struct Traits<int> : ScalarTraits<int>
400*35238bceSAndroid Build Coastguard Worker {
doPrintValuedeqp::gls::BuiltinPrecisionTests::Traits401*35238bceSAndroid Build Coastguard Worker static void doPrintValue(const FloatFormat &, const int &value, ostream &os)
402*35238bceSAndroid Build Coastguard Worker {
403*35238bceSAndroid Build Coastguard Worker os << value;
404*35238bceSAndroid Build Coastguard Worker }
405*35238bceSAndroid Build Coastguard Worker
doPrintIValdeqp::gls::BuiltinPrecisionTests::Traits406*35238bceSAndroid Build Coastguard Worker static void doPrintIVal(const FloatFormat &, const Interval &ival, ostream &os)
407*35238bceSAndroid Build Coastguard Worker {
408*35238bceSAndroid Build Coastguard Worker os << "[" << int(ival.lo()) << ", " << int(ival.hi()) << "]";
409*35238bceSAndroid Build Coastguard Worker }
410*35238bceSAndroid Build Coastguard Worker };
411*35238bceSAndroid Build Coastguard Worker
412*35238bceSAndroid Build Coastguard Worker //! Common traits for containers, i.e. vectors and matrices.
413*35238bceSAndroid Build Coastguard Worker //! T is the container type itself, I is the same type with interval elements.
414*35238bceSAndroid Build Coastguard Worker template <typename T, typename I>
415*35238bceSAndroid Build Coastguard Worker struct ContainerTraits
416*35238bceSAndroid Build Coastguard Worker {
417*35238bceSAndroid Build Coastguard Worker typedef typename T::Element Element;
418*35238bceSAndroid Build Coastguard Worker typedef I IVal;
419*35238bceSAndroid Build Coastguard Worker
doMakeIValdeqp::gls::BuiltinPrecisionTests::ContainerTraits420*35238bceSAndroid Build Coastguard Worker static IVal doMakeIVal(const T &value)
421*35238bceSAndroid Build Coastguard Worker {
422*35238bceSAndroid Build Coastguard Worker IVal ret;
423*35238bceSAndroid Build Coastguard Worker
424*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
425*35238bceSAndroid Build Coastguard Worker ret[ndx] = makeIVal(value[ndx]);
426*35238bceSAndroid Build Coastguard Worker
427*35238bceSAndroid Build Coastguard Worker return ret;
428*35238bceSAndroid Build Coastguard Worker }
429*35238bceSAndroid Build Coastguard Worker
doUniondeqp::gls::BuiltinPrecisionTests::ContainerTraits430*35238bceSAndroid Build Coastguard Worker static IVal doUnion(const IVal &a, const IVal &b)
431*35238bceSAndroid Build Coastguard Worker {
432*35238bceSAndroid Build Coastguard Worker IVal ret;
433*35238bceSAndroid Build Coastguard Worker
434*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
435*35238bceSAndroid Build Coastguard Worker ret[ndx] = unionIVal<Element>(a[ndx], b[ndx]);
436*35238bceSAndroid Build Coastguard Worker
437*35238bceSAndroid Build Coastguard Worker return ret;
438*35238bceSAndroid Build Coastguard Worker }
439*35238bceSAndroid Build Coastguard Worker
doContainsdeqp::gls::BuiltinPrecisionTests::ContainerTraits440*35238bceSAndroid Build Coastguard Worker static bool doContains(const IVal &ival, const T &value)
441*35238bceSAndroid Build Coastguard Worker {
442*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
443*35238bceSAndroid Build Coastguard Worker if (!contains(ival[ndx], value[ndx]))
444*35238bceSAndroid Build Coastguard Worker return false;
445*35238bceSAndroid Build Coastguard Worker
446*35238bceSAndroid Build Coastguard Worker return true;
447*35238bceSAndroid Build Coastguard Worker }
448*35238bceSAndroid Build Coastguard Worker
doContainsWarningdeqp::gls::BuiltinPrecisionTests::ContainerTraits449*35238bceSAndroid Build Coastguard Worker static bool doContainsWarning(const IVal &ival, const T &value)
450*35238bceSAndroid Build Coastguard Worker {
451*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
452*35238bceSAndroid Build Coastguard Worker if (!containsWarning(ival[ndx], value[ndx]))
453*35238bceSAndroid Build Coastguard Worker return false;
454*35238bceSAndroid Build Coastguard Worker
455*35238bceSAndroid Build Coastguard Worker return true;
456*35238bceSAndroid Build Coastguard Worker }
457*35238bceSAndroid Build Coastguard Worker
doPrintIValdeqp::gls::BuiltinPrecisionTests::ContainerTraits458*35238bceSAndroid Build Coastguard Worker static void doPrintIVal(const FloatFormat &fmt, const IVal ival, ostream &os)
459*35238bceSAndroid Build Coastguard Worker {
460*35238bceSAndroid Build Coastguard Worker os << "(";
461*35238bceSAndroid Build Coastguard Worker
462*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
463*35238bceSAndroid Build Coastguard Worker {
464*35238bceSAndroid Build Coastguard Worker if (ndx > 0)
465*35238bceSAndroid Build Coastguard Worker os << ", ";
466*35238bceSAndroid Build Coastguard Worker
467*35238bceSAndroid Build Coastguard Worker printIVal<Element>(fmt, ival[ndx], os);
468*35238bceSAndroid Build Coastguard Worker }
469*35238bceSAndroid Build Coastguard Worker
470*35238bceSAndroid Build Coastguard Worker os << ")";
471*35238bceSAndroid Build Coastguard Worker }
472*35238bceSAndroid Build Coastguard Worker
doPrintValuedeqp::gls::BuiltinPrecisionTests::ContainerTraits473*35238bceSAndroid Build Coastguard Worker static void doPrintValue(const FloatFormat &fmt, const T &value, ostream &os)
474*35238bceSAndroid Build Coastguard Worker {
475*35238bceSAndroid Build Coastguard Worker os << dataTypeNameOf<T>() << "(";
476*35238bceSAndroid Build Coastguard Worker
477*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
478*35238bceSAndroid Build Coastguard Worker {
479*35238bceSAndroid Build Coastguard Worker if (ndx > 0)
480*35238bceSAndroid Build Coastguard Worker os << ", ";
481*35238bceSAndroid Build Coastguard Worker
482*35238bceSAndroid Build Coastguard Worker printValue<Element>(fmt, value[ndx], os);
483*35238bceSAndroid Build Coastguard Worker }
484*35238bceSAndroid Build Coastguard Worker
485*35238bceSAndroid Build Coastguard Worker os << ")";
486*35238bceSAndroid Build Coastguard Worker }
487*35238bceSAndroid Build Coastguard Worker
doConvertdeqp::gls::BuiltinPrecisionTests::ContainerTraits488*35238bceSAndroid Build Coastguard Worker static IVal doConvert(const FloatFormat &fmt, const IVal &value)
489*35238bceSAndroid Build Coastguard Worker {
490*35238bceSAndroid Build Coastguard Worker IVal ret;
491*35238bceSAndroid Build Coastguard Worker
492*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
493*35238bceSAndroid Build Coastguard Worker ret[ndx] = convert<Element>(fmt, value[ndx]);
494*35238bceSAndroid Build Coastguard Worker
495*35238bceSAndroid Build Coastguard Worker return ret;
496*35238bceSAndroid Build Coastguard Worker }
497*35238bceSAndroid Build Coastguard Worker
doRounddeqp::gls::BuiltinPrecisionTests::ContainerTraits498*35238bceSAndroid Build Coastguard Worker static IVal doRound(const FloatFormat &fmt, T value)
499*35238bceSAndroid Build Coastguard Worker {
500*35238bceSAndroid Build Coastguard Worker IVal ret;
501*35238bceSAndroid Build Coastguard Worker
502*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < T::SIZE; ++ndx)
503*35238bceSAndroid Build Coastguard Worker ret[ndx] = round(fmt, value[ndx]);
504*35238bceSAndroid Build Coastguard Worker
505*35238bceSAndroid Build Coastguard Worker return ret;
506*35238bceSAndroid Build Coastguard Worker }
507*35238bceSAndroid Build Coastguard Worker };
508*35238bceSAndroid Build Coastguard Worker
509*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
510*35238bceSAndroid Build Coastguard Worker struct Traits<Vector<T, Size>> : ContainerTraits<Vector<T, Size>, Vector<typename Traits<T>::IVal, Size>>
511*35238bceSAndroid Build Coastguard Worker {
512*35238bceSAndroid Build Coastguard Worker };
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
515*35238bceSAndroid Build Coastguard Worker struct Traits<Matrix<T, Rows, Cols>>
516*35238bceSAndroid Build Coastguard Worker : ContainerTraits<Matrix<T, Rows, Cols>, Matrix<typename Traits<T>::IVal, Rows, Cols>>
517*35238bceSAndroid Build Coastguard Worker {
518*35238bceSAndroid Build Coastguard Worker };
519*35238bceSAndroid Build Coastguard Worker
520*35238bceSAndroid Build Coastguard Worker //! Void traits. These are just dummies, but technically valid: a Void is a
521*35238bceSAndroid Build Coastguard Worker //! unit type with a single possible value.
522*35238bceSAndroid Build Coastguard Worker template <>
523*35238bceSAndroid Build Coastguard Worker struct Traits<Void>
524*35238bceSAndroid Build Coastguard Worker {
525*35238bceSAndroid Build Coastguard Worker typedef Void IVal;
526*35238bceSAndroid Build Coastguard Worker
doMakeIValdeqp::gls::BuiltinPrecisionTests::Traits527*35238bceSAndroid Build Coastguard Worker static Void doMakeIVal(const Void &value)
528*35238bceSAndroid Build Coastguard Worker {
529*35238bceSAndroid Build Coastguard Worker return value;
530*35238bceSAndroid Build Coastguard Worker }
doUniondeqp::gls::BuiltinPrecisionTests::Traits531*35238bceSAndroid Build Coastguard Worker static Void doUnion(const Void &, const Void &)
532*35238bceSAndroid Build Coastguard Worker {
533*35238bceSAndroid Build Coastguard Worker return Void();
534*35238bceSAndroid Build Coastguard Worker }
doContainsdeqp::gls::BuiltinPrecisionTests::Traits535*35238bceSAndroid Build Coastguard Worker static bool doContains(const Void &, Void)
536*35238bceSAndroid Build Coastguard Worker {
537*35238bceSAndroid Build Coastguard Worker return true;
538*35238bceSAndroid Build Coastguard Worker }
doContainsWarningdeqp::gls::BuiltinPrecisionTests::Traits539*35238bceSAndroid Build Coastguard Worker static bool doContainsWarning(const Void &, Void)
540*35238bceSAndroid Build Coastguard Worker {
541*35238bceSAndroid Build Coastguard Worker return true;
542*35238bceSAndroid Build Coastguard Worker }
doRounddeqp::gls::BuiltinPrecisionTests::Traits543*35238bceSAndroid Build Coastguard Worker static Void doRound(const FloatFormat &, const Void &value)
544*35238bceSAndroid Build Coastguard Worker {
545*35238bceSAndroid Build Coastguard Worker return value;
546*35238bceSAndroid Build Coastguard Worker }
doConvertdeqp::gls::BuiltinPrecisionTests::Traits547*35238bceSAndroid Build Coastguard Worker static Void doConvert(const FloatFormat &, const Void &value)
548*35238bceSAndroid Build Coastguard Worker {
549*35238bceSAndroid Build Coastguard Worker return value;
550*35238bceSAndroid Build Coastguard Worker }
551*35238bceSAndroid Build Coastguard Worker
doPrintValuedeqp::gls::BuiltinPrecisionTests::Traits552*35238bceSAndroid Build Coastguard Worker static void doPrintValue(const FloatFormat &, const Void &, ostream &os)
553*35238bceSAndroid Build Coastguard Worker {
554*35238bceSAndroid Build Coastguard Worker os << "()";
555*35238bceSAndroid Build Coastguard Worker }
556*35238bceSAndroid Build Coastguard Worker
doPrintIValdeqp::gls::BuiltinPrecisionTests::Traits557*35238bceSAndroid Build Coastguard Worker static void doPrintIVal(const FloatFormat &, const Void &, ostream &os)
558*35238bceSAndroid Build Coastguard Worker {
559*35238bceSAndroid Build Coastguard Worker os << "()";
560*35238bceSAndroid Build Coastguard Worker }
561*35238bceSAndroid Build Coastguard Worker };
562*35238bceSAndroid Build Coastguard Worker
563*35238bceSAndroid Build Coastguard Worker //! This is needed for container-generic operations.
564*35238bceSAndroid Build Coastguard Worker //! We want a scalar type T to be its own "one-element vector".
565*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
566*35238bceSAndroid Build Coastguard Worker struct ContainerOf
567*35238bceSAndroid Build Coastguard Worker {
568*35238bceSAndroid Build Coastguard Worker typedef Vector<T, Size> Container;
569*35238bceSAndroid Build Coastguard Worker };
570*35238bceSAndroid Build Coastguard Worker
571*35238bceSAndroid Build Coastguard Worker template <typename T>
572*35238bceSAndroid Build Coastguard Worker struct ContainerOf<T, 1>
573*35238bceSAndroid Build Coastguard Worker {
574*35238bceSAndroid Build Coastguard Worker typedef T Container;
575*35238bceSAndroid Build Coastguard Worker };
576*35238bceSAndroid Build Coastguard Worker template <int Size>
577*35238bceSAndroid Build Coastguard Worker struct ContainerOf<Void, Size>
578*35238bceSAndroid Build Coastguard Worker {
579*35238bceSAndroid Build Coastguard Worker typedef Void Container;
580*35238bceSAndroid Build Coastguard Worker };
581*35238bceSAndroid Build Coastguard Worker
582*35238bceSAndroid Build Coastguard Worker // This is a kludge that is only needed to get the ExprP::operator[] syntactic sugar to work.
583*35238bceSAndroid Build Coastguard Worker template <typename T>
584*35238bceSAndroid Build Coastguard Worker struct ElementOf
585*35238bceSAndroid Build Coastguard Worker {
586*35238bceSAndroid Build Coastguard Worker typedef typename T::Element Element;
587*35238bceSAndroid Build Coastguard Worker };
588*35238bceSAndroid Build Coastguard Worker template <>
589*35238bceSAndroid Build Coastguard Worker struct ElementOf<float>
590*35238bceSAndroid Build Coastguard Worker {
591*35238bceSAndroid Build Coastguard Worker typedef void Element;
592*35238bceSAndroid Build Coastguard Worker };
593*35238bceSAndroid Build Coastguard Worker template <>
594*35238bceSAndroid Build Coastguard Worker struct ElementOf<bool>
595*35238bceSAndroid Build Coastguard Worker {
596*35238bceSAndroid Build Coastguard Worker typedef void Element;
597*35238bceSAndroid Build Coastguard Worker };
598*35238bceSAndroid Build Coastguard Worker template <>
599*35238bceSAndroid Build Coastguard Worker struct ElementOf<int>
600*35238bceSAndroid Build Coastguard Worker {
601*35238bceSAndroid Build Coastguard Worker typedef void Element;
602*35238bceSAndroid Build Coastguard Worker };
603*35238bceSAndroid Build Coastguard Worker
604*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
605*35238bceSAndroid Build Coastguard Worker *
606*35238bceSAndroid Build Coastguard Worker * \name Abstract syntax for expressions and statements.
607*35238bceSAndroid Build Coastguard Worker *
608*35238bceSAndroid Build Coastguard Worker * We represent GLSL programs as syntax objects: an Expr<T> represents an
609*35238bceSAndroid Build Coastguard Worker * expression whose GLSL type corresponds to the C++ type T, and a Statement
610*35238bceSAndroid Build Coastguard Worker * represents a statement.
611*35238bceSAndroid Build Coastguard Worker *
612*35238bceSAndroid Build Coastguard Worker * To ease memory management, we use shared pointers to refer to expressions
613*35238bceSAndroid Build Coastguard Worker * and statements. ExprP<T> is a shared pointer to an Expr<T>, and StatementP
614*35238bceSAndroid Build Coastguard Worker * is a shared pointer to a Statement.
615*35238bceSAndroid Build Coastguard Worker *
616*35238bceSAndroid Build Coastguard Worker * \{
617*35238bceSAndroid Build Coastguard Worker *
618*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
619*35238bceSAndroid Build Coastguard Worker
620*35238bceSAndroid Build Coastguard Worker class ExprBase;
621*35238bceSAndroid Build Coastguard Worker class ExpandContext;
622*35238bceSAndroid Build Coastguard Worker class Statement;
623*35238bceSAndroid Build Coastguard Worker class StatementP;
624*35238bceSAndroid Build Coastguard Worker class FuncBase;
625*35238bceSAndroid Build Coastguard Worker template <typename T>
626*35238bceSAndroid Build Coastguard Worker class ExprP;
627*35238bceSAndroid Build Coastguard Worker template <typename T>
628*35238bceSAndroid Build Coastguard Worker class Variable;
629*35238bceSAndroid Build Coastguard Worker template <typename T>
630*35238bceSAndroid Build Coastguard Worker class VariableP;
631*35238bceSAndroid Build Coastguard Worker template <typename T>
632*35238bceSAndroid Build Coastguard Worker class DefaultSampling;
633*35238bceSAndroid Build Coastguard Worker
634*35238bceSAndroid Build Coastguard Worker typedef set<const FuncBase *> FuncSet;
635*35238bceSAndroid Build Coastguard Worker
636*35238bceSAndroid Build Coastguard Worker template <typename T>
637*35238bceSAndroid Build Coastguard Worker VariableP<T> variable(const string &name);
638*35238bceSAndroid Build Coastguard Worker StatementP compoundStatement(const vector<StatementP> &statements);
639*35238bceSAndroid Build Coastguard Worker
640*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
641*35238bceSAndroid Build Coastguard Worker * \brief A variable environment.
642*35238bceSAndroid Build Coastguard Worker *
643*35238bceSAndroid Build Coastguard Worker * An Environment object maintains the mapping between variables of the
644*35238bceSAndroid Build Coastguard Worker * abstract syntax tree and their values.
645*35238bceSAndroid Build Coastguard Worker *
646*35238bceSAndroid Build Coastguard Worker * \todo [2014-03-28 lauri] At least run-time type safety.
647*35238bceSAndroid Build Coastguard Worker *
648*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
649*35238bceSAndroid Build Coastguard Worker class Environment
650*35238bceSAndroid Build Coastguard Worker {
651*35238bceSAndroid Build Coastguard Worker public:
652*35238bceSAndroid Build Coastguard Worker template <typename T>
bind(const Variable<T> & variable,const typename Traits<T>::IVal & value)653*35238bceSAndroid Build Coastguard Worker void bind(const Variable<T> &variable, const typename Traits<T>::IVal &value)
654*35238bceSAndroid Build Coastguard Worker {
655*35238bceSAndroid Build Coastguard Worker uint8_t *const data = new uint8_t[sizeof(value)];
656*35238bceSAndroid Build Coastguard Worker
657*35238bceSAndroid Build Coastguard Worker deMemcpy(data, &value, sizeof(value));
658*35238bceSAndroid Build Coastguard Worker de::insert(m_map, variable.getName(), SharedPtr<uint8_t>(data, de::ArrayDeleter<uint8_t>()));
659*35238bceSAndroid Build Coastguard Worker }
660*35238bceSAndroid Build Coastguard Worker
661*35238bceSAndroid Build Coastguard Worker template <typename T>
lookup(const Variable<T> & variable) const662*35238bceSAndroid Build Coastguard Worker typename Traits<T>::IVal &lookup(const Variable<T> &variable) const
663*35238bceSAndroid Build Coastguard Worker {
664*35238bceSAndroid Build Coastguard Worker uint8_t *const data = de::lookup(m_map, variable.getName()).get();
665*35238bceSAndroid Build Coastguard Worker
666*35238bceSAndroid Build Coastguard Worker return *reinterpret_cast<typename Traits<T>::IVal *>(data);
667*35238bceSAndroid Build Coastguard Worker }
668*35238bceSAndroid Build Coastguard Worker
669*35238bceSAndroid Build Coastguard Worker private:
670*35238bceSAndroid Build Coastguard Worker map<string, SharedPtr<uint8_t>> m_map;
671*35238bceSAndroid Build Coastguard Worker };
672*35238bceSAndroid Build Coastguard Worker
673*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
674*35238bceSAndroid Build Coastguard Worker * \brief Evaluation context.
675*35238bceSAndroid Build Coastguard Worker *
676*35238bceSAndroid Build Coastguard Worker * The evaluation context contains everything that separates one execution of
677*35238bceSAndroid Build Coastguard Worker * an expression from the next. Currently this means the desired floating
678*35238bceSAndroid Build Coastguard Worker * point precision and the current variable environment.
679*35238bceSAndroid Build Coastguard Worker *
680*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
681*35238bceSAndroid Build Coastguard Worker struct EvalContext
682*35238bceSAndroid Build Coastguard Worker {
EvalContextdeqp::gls::BuiltinPrecisionTests::EvalContext683*35238bceSAndroid Build Coastguard Worker EvalContext(const FloatFormat &format_, Precision floatPrecision_, Environment &env_, int callDepth_ = 0)
684*35238bceSAndroid Build Coastguard Worker : format(format_)
685*35238bceSAndroid Build Coastguard Worker , floatPrecision(floatPrecision_)
686*35238bceSAndroid Build Coastguard Worker , env(env_)
687*35238bceSAndroid Build Coastguard Worker , callDepth(callDepth_)
688*35238bceSAndroid Build Coastguard Worker {
689*35238bceSAndroid Build Coastguard Worker }
690*35238bceSAndroid Build Coastguard Worker
691*35238bceSAndroid Build Coastguard Worker FloatFormat format;
692*35238bceSAndroid Build Coastguard Worker Precision floatPrecision;
693*35238bceSAndroid Build Coastguard Worker Environment &env;
694*35238bceSAndroid Build Coastguard Worker int callDepth;
695*35238bceSAndroid Build Coastguard Worker };
696*35238bceSAndroid Build Coastguard Worker
697*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
698*35238bceSAndroid Build Coastguard Worker * \brief Simple incremental counter.
699*35238bceSAndroid Build Coastguard Worker *
700*35238bceSAndroid Build Coastguard Worker * This is used to make sure that different ExpandContexts will not produce
701*35238bceSAndroid Build Coastguard Worker * overlapping temporary names.
702*35238bceSAndroid Build Coastguard Worker *
703*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
704*35238bceSAndroid Build Coastguard Worker class Counter
705*35238bceSAndroid Build Coastguard Worker {
706*35238bceSAndroid Build Coastguard Worker public:
Counter(int count=0)707*35238bceSAndroid Build Coastguard Worker Counter(int count = 0) : m_count(count)
708*35238bceSAndroid Build Coastguard Worker {
709*35238bceSAndroid Build Coastguard Worker }
operator ()(void)710*35238bceSAndroid Build Coastguard Worker int operator()(void)
711*35238bceSAndroid Build Coastguard Worker {
712*35238bceSAndroid Build Coastguard Worker return m_count++;
713*35238bceSAndroid Build Coastguard Worker }
714*35238bceSAndroid Build Coastguard Worker
715*35238bceSAndroid Build Coastguard Worker private:
716*35238bceSAndroid Build Coastguard Worker int m_count;
717*35238bceSAndroid Build Coastguard Worker };
718*35238bceSAndroid Build Coastguard Worker
719*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
720*35238bceSAndroid Build Coastguard Worker * \brief A statement or declaration.
721*35238bceSAndroid Build Coastguard Worker *
722*35238bceSAndroid Build Coastguard Worker * Statements have no values. Instead, they are executed for their side
723*35238bceSAndroid Build Coastguard Worker * effects only: the execute() method should modify at least one variable in
724*35238bceSAndroid Build Coastguard Worker * the environment.
725*35238bceSAndroid Build Coastguard Worker *
726*35238bceSAndroid Build Coastguard Worker * As a bit of a kludge, a Statement object can also represent a declaration:
727*35238bceSAndroid Build Coastguard Worker * when it is evaluated, it can add a variable binding to the environment
728*35238bceSAndroid Build Coastguard Worker * instead of modifying a current one.
729*35238bceSAndroid Build Coastguard Worker *
730*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
731*35238bceSAndroid Build Coastguard Worker class Statement
732*35238bceSAndroid Build Coastguard Worker {
733*35238bceSAndroid Build Coastguard Worker public:
~Statement(void)734*35238bceSAndroid Build Coastguard Worker virtual ~Statement(void)
735*35238bceSAndroid Build Coastguard Worker {
736*35238bceSAndroid Build Coastguard Worker }
737*35238bceSAndroid Build Coastguard Worker //! Execute the statement, modifying the environment of `ctx`
execute(EvalContext & ctx) const738*35238bceSAndroid Build Coastguard Worker void execute(EvalContext &ctx) const
739*35238bceSAndroid Build Coastguard Worker {
740*35238bceSAndroid Build Coastguard Worker this->doExecute(ctx);
741*35238bceSAndroid Build Coastguard Worker }
print(ostream & os) const742*35238bceSAndroid Build Coastguard Worker void print(ostream &os) const
743*35238bceSAndroid Build Coastguard Worker {
744*35238bceSAndroid Build Coastguard Worker this->doPrint(os);
745*35238bceSAndroid Build Coastguard Worker }
746*35238bceSAndroid Build Coastguard Worker //! Add the functions used in this statement to `dst`.
getUsedFuncs(FuncSet & dst) const747*35238bceSAndroid Build Coastguard Worker void getUsedFuncs(FuncSet &dst) const
748*35238bceSAndroid Build Coastguard Worker {
749*35238bceSAndroid Build Coastguard Worker this->doGetUsedFuncs(dst);
750*35238bceSAndroid Build Coastguard Worker }
751*35238bceSAndroid Build Coastguard Worker
752*35238bceSAndroid Build Coastguard Worker protected:
753*35238bceSAndroid Build Coastguard Worker virtual void doPrint(ostream &os) const = 0;
754*35238bceSAndroid Build Coastguard Worker virtual void doExecute(EvalContext &ctx) const = 0;
755*35238bceSAndroid Build Coastguard Worker virtual void doGetUsedFuncs(FuncSet &dst) const = 0;
756*35238bceSAndroid Build Coastguard Worker };
757*35238bceSAndroid Build Coastguard Worker
operator <<(ostream & os,const Statement & stmt)758*35238bceSAndroid Build Coastguard Worker ostream &operator<<(ostream &os, const Statement &stmt)
759*35238bceSAndroid Build Coastguard Worker {
760*35238bceSAndroid Build Coastguard Worker stmt.print(os);
761*35238bceSAndroid Build Coastguard Worker return os;
762*35238bceSAndroid Build Coastguard Worker }
763*35238bceSAndroid Build Coastguard Worker
764*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
765*35238bceSAndroid Build Coastguard Worker * \brief Smart pointer for statements (and declarations)
766*35238bceSAndroid Build Coastguard Worker *
767*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
768*35238bceSAndroid Build Coastguard Worker class StatementP : public SharedPtr<const Statement>
769*35238bceSAndroid Build Coastguard Worker {
770*35238bceSAndroid Build Coastguard Worker public:
771*35238bceSAndroid Build Coastguard Worker typedef SharedPtr<const Statement> Super;
772*35238bceSAndroid Build Coastguard Worker
StatementP(void)773*35238bceSAndroid Build Coastguard Worker StatementP(void)
774*35238bceSAndroid Build Coastguard Worker {
775*35238bceSAndroid Build Coastguard Worker }
StatementP(const Statement * ptr)776*35238bceSAndroid Build Coastguard Worker explicit StatementP(const Statement *ptr) : Super(ptr)
777*35238bceSAndroid Build Coastguard Worker {
778*35238bceSAndroid Build Coastguard Worker }
StatementP(const Super & ptr)779*35238bceSAndroid Build Coastguard Worker StatementP(const Super &ptr) : Super(ptr)
780*35238bceSAndroid Build Coastguard Worker {
781*35238bceSAndroid Build Coastguard Worker }
782*35238bceSAndroid Build Coastguard Worker };
783*35238bceSAndroid Build Coastguard Worker
784*35238bceSAndroid Build Coastguard Worker class ExpandContext
785*35238bceSAndroid Build Coastguard Worker {
786*35238bceSAndroid Build Coastguard Worker public:
ExpandContext(Counter & symCounter)787*35238bceSAndroid Build Coastguard Worker ExpandContext(Counter &symCounter) : m_symCounter(symCounter)
788*35238bceSAndroid Build Coastguard Worker {
789*35238bceSAndroid Build Coastguard Worker }
ExpandContext(const ExpandContext & parent)790*35238bceSAndroid Build Coastguard Worker ExpandContext(const ExpandContext &parent) : m_symCounter(parent.m_symCounter)
791*35238bceSAndroid Build Coastguard Worker {
792*35238bceSAndroid Build Coastguard Worker }
793*35238bceSAndroid Build Coastguard Worker
794*35238bceSAndroid Build Coastguard Worker template <typename T>
genSym(const string & baseName)795*35238bceSAndroid Build Coastguard Worker VariableP<T> genSym(const string &baseName)
796*35238bceSAndroid Build Coastguard Worker {
797*35238bceSAndroid Build Coastguard Worker return variable<T>(baseName + de::toString(m_symCounter()));
798*35238bceSAndroid Build Coastguard Worker }
799*35238bceSAndroid Build Coastguard Worker
addStatement(const StatementP & stmt)800*35238bceSAndroid Build Coastguard Worker void addStatement(const StatementP &stmt)
801*35238bceSAndroid Build Coastguard Worker {
802*35238bceSAndroid Build Coastguard Worker m_statements.push_back(stmt);
803*35238bceSAndroid Build Coastguard Worker }
804*35238bceSAndroid Build Coastguard Worker
getStatements(void) const805*35238bceSAndroid Build Coastguard Worker vector<StatementP> getStatements(void) const
806*35238bceSAndroid Build Coastguard Worker {
807*35238bceSAndroid Build Coastguard Worker return m_statements;
808*35238bceSAndroid Build Coastguard Worker }
809*35238bceSAndroid Build Coastguard Worker
810*35238bceSAndroid Build Coastguard Worker private:
811*35238bceSAndroid Build Coastguard Worker Counter &m_symCounter;
812*35238bceSAndroid Build Coastguard Worker vector<StatementP> m_statements;
813*35238bceSAndroid Build Coastguard Worker };
814*35238bceSAndroid Build Coastguard Worker
815*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
816*35238bceSAndroid Build Coastguard Worker * \brief
817*35238bceSAndroid Build Coastguard Worker *
818*35238bceSAndroid Build Coastguard Worker * A statement that modifies a variable or a declaration that binds a variable.
819*35238bceSAndroid Build Coastguard Worker *
820*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
821*35238bceSAndroid Build Coastguard Worker template <typename T>
822*35238bceSAndroid Build Coastguard Worker class VariableStatement : public Statement
823*35238bceSAndroid Build Coastguard Worker {
824*35238bceSAndroid Build Coastguard Worker public:
VariableStatement(const VariableP<T> & variable,const ExprP<T> & value,bool isDeclaration)825*35238bceSAndroid Build Coastguard Worker VariableStatement(const VariableP<T> &variable, const ExprP<T> &value, bool isDeclaration)
826*35238bceSAndroid Build Coastguard Worker : m_variable(variable)
827*35238bceSAndroid Build Coastguard Worker , m_value(value)
828*35238bceSAndroid Build Coastguard Worker , m_isDeclaration(isDeclaration)
829*35238bceSAndroid Build Coastguard Worker {
830*35238bceSAndroid Build Coastguard Worker }
831*35238bceSAndroid Build Coastguard Worker
832*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os) const833*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os) const
834*35238bceSAndroid Build Coastguard Worker {
835*35238bceSAndroid Build Coastguard Worker if (m_isDeclaration)
836*35238bceSAndroid Build Coastguard Worker os << glu::declare(getVarTypeOf<T>(), m_variable->getName());
837*35238bceSAndroid Build Coastguard Worker else
838*35238bceSAndroid Build Coastguard Worker os << m_variable->getName();
839*35238bceSAndroid Build Coastguard Worker
840*35238bceSAndroid Build Coastguard Worker os << " = " << *m_value << ";\n";
841*35238bceSAndroid Build Coastguard Worker }
842*35238bceSAndroid Build Coastguard Worker
doExecute(EvalContext & ctx) const843*35238bceSAndroid Build Coastguard Worker void doExecute(EvalContext &ctx) const
844*35238bceSAndroid Build Coastguard Worker {
845*35238bceSAndroid Build Coastguard Worker if (m_isDeclaration)
846*35238bceSAndroid Build Coastguard Worker ctx.env.bind(*m_variable, m_value->evaluate(ctx));
847*35238bceSAndroid Build Coastguard Worker else
848*35238bceSAndroid Build Coastguard Worker ctx.env.lookup(*m_variable) = m_value->evaluate(ctx);
849*35238bceSAndroid Build Coastguard Worker }
850*35238bceSAndroid Build Coastguard Worker
doGetUsedFuncs(FuncSet & dst) const851*35238bceSAndroid Build Coastguard Worker void doGetUsedFuncs(FuncSet &dst) const
852*35238bceSAndroid Build Coastguard Worker {
853*35238bceSAndroid Build Coastguard Worker m_value->getUsedFuncs(dst);
854*35238bceSAndroid Build Coastguard Worker }
855*35238bceSAndroid Build Coastguard Worker
856*35238bceSAndroid Build Coastguard Worker VariableP<T> m_variable;
857*35238bceSAndroid Build Coastguard Worker ExprP<T> m_value;
858*35238bceSAndroid Build Coastguard Worker bool m_isDeclaration;
859*35238bceSAndroid Build Coastguard Worker };
860*35238bceSAndroid Build Coastguard Worker
861*35238bceSAndroid Build Coastguard Worker template <typename T>
variableStatement(const VariableP<T> & variable,const ExprP<T> & value,bool isDeclaration)862*35238bceSAndroid Build Coastguard Worker StatementP variableStatement(const VariableP<T> &variable, const ExprP<T> &value, bool isDeclaration)
863*35238bceSAndroid Build Coastguard Worker {
864*35238bceSAndroid Build Coastguard Worker return StatementP(new VariableStatement<T>(variable, value, isDeclaration));
865*35238bceSAndroid Build Coastguard Worker }
866*35238bceSAndroid Build Coastguard Worker
867*35238bceSAndroid Build Coastguard Worker template <typename T>
variableDeclaration(const VariableP<T> & variable,const ExprP<T> & definiens)868*35238bceSAndroid Build Coastguard Worker StatementP variableDeclaration(const VariableP<T> &variable, const ExprP<T> &definiens)
869*35238bceSAndroid Build Coastguard Worker {
870*35238bceSAndroid Build Coastguard Worker return variableStatement(variable, definiens, true);
871*35238bceSAndroid Build Coastguard Worker }
872*35238bceSAndroid Build Coastguard Worker
873*35238bceSAndroid Build Coastguard Worker template <typename T>
variableAssignment(const VariableP<T> & variable,const ExprP<T> & value)874*35238bceSAndroid Build Coastguard Worker StatementP variableAssignment(const VariableP<T> &variable, const ExprP<T> &value)
875*35238bceSAndroid Build Coastguard Worker {
876*35238bceSAndroid Build Coastguard Worker return variableStatement(variable, value, false);
877*35238bceSAndroid Build Coastguard Worker }
878*35238bceSAndroid Build Coastguard Worker
879*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
880*35238bceSAndroid Build Coastguard Worker * \brief A compound statement, i.e. a block.
881*35238bceSAndroid Build Coastguard Worker *
882*35238bceSAndroid Build Coastguard Worker * A compound statement is executed by executing its constituent statements in
883*35238bceSAndroid Build Coastguard Worker * sequence.
884*35238bceSAndroid Build Coastguard Worker *
885*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
886*35238bceSAndroid Build Coastguard Worker class CompoundStatement : public Statement
887*35238bceSAndroid Build Coastguard Worker {
888*35238bceSAndroid Build Coastguard Worker public:
CompoundStatement(const vector<StatementP> & statements)889*35238bceSAndroid Build Coastguard Worker CompoundStatement(const vector<StatementP> &statements) : m_statements(statements)
890*35238bceSAndroid Build Coastguard Worker {
891*35238bceSAndroid Build Coastguard Worker }
892*35238bceSAndroid Build Coastguard Worker
893*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os) const894*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os) const
895*35238bceSAndroid Build Coastguard Worker {
896*35238bceSAndroid Build Coastguard Worker os << "{\n";
897*35238bceSAndroid Build Coastguard Worker
898*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < m_statements.size(); ++ndx)
899*35238bceSAndroid Build Coastguard Worker os << *m_statements[ndx];
900*35238bceSAndroid Build Coastguard Worker
901*35238bceSAndroid Build Coastguard Worker os << "}\n";
902*35238bceSAndroid Build Coastguard Worker }
903*35238bceSAndroid Build Coastguard Worker
doExecute(EvalContext & ctx) const904*35238bceSAndroid Build Coastguard Worker void doExecute(EvalContext &ctx) const
905*35238bceSAndroid Build Coastguard Worker {
906*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < m_statements.size(); ++ndx)
907*35238bceSAndroid Build Coastguard Worker m_statements[ndx]->execute(ctx);
908*35238bceSAndroid Build Coastguard Worker }
909*35238bceSAndroid Build Coastguard Worker
doGetUsedFuncs(FuncSet & dst) const910*35238bceSAndroid Build Coastguard Worker void doGetUsedFuncs(FuncSet &dst) const
911*35238bceSAndroid Build Coastguard Worker {
912*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < m_statements.size(); ++ndx)
913*35238bceSAndroid Build Coastguard Worker m_statements[ndx]->getUsedFuncs(dst);
914*35238bceSAndroid Build Coastguard Worker }
915*35238bceSAndroid Build Coastguard Worker
916*35238bceSAndroid Build Coastguard Worker vector<StatementP> m_statements;
917*35238bceSAndroid Build Coastguard Worker };
918*35238bceSAndroid Build Coastguard Worker
compoundStatement(const vector<StatementP> & statements)919*35238bceSAndroid Build Coastguard Worker StatementP compoundStatement(const vector<StatementP> &statements)
920*35238bceSAndroid Build Coastguard Worker {
921*35238bceSAndroid Build Coastguard Worker return StatementP(new CompoundStatement(statements));
922*35238bceSAndroid Build Coastguard Worker }
923*35238bceSAndroid Build Coastguard Worker
924*35238bceSAndroid Build Coastguard Worker //! Common base class for all expressions regardless of their type.
925*35238bceSAndroid Build Coastguard Worker class ExprBase
926*35238bceSAndroid Build Coastguard Worker {
927*35238bceSAndroid Build Coastguard Worker public:
~ExprBase(void)928*35238bceSAndroid Build Coastguard Worker virtual ~ExprBase(void)
929*35238bceSAndroid Build Coastguard Worker {
930*35238bceSAndroid Build Coastguard Worker }
printExpr(ostream & os) const931*35238bceSAndroid Build Coastguard Worker void printExpr(ostream &os) const
932*35238bceSAndroid Build Coastguard Worker {
933*35238bceSAndroid Build Coastguard Worker this->doPrintExpr(os);
934*35238bceSAndroid Build Coastguard Worker }
935*35238bceSAndroid Build Coastguard Worker
936*35238bceSAndroid Build Coastguard Worker //! Output the functions that this expression refers to
getUsedFuncs(FuncSet & dst) const937*35238bceSAndroid Build Coastguard Worker void getUsedFuncs(FuncSet &dst) const
938*35238bceSAndroid Build Coastguard Worker {
939*35238bceSAndroid Build Coastguard Worker this->doGetUsedFuncs(dst);
940*35238bceSAndroid Build Coastguard Worker }
941*35238bceSAndroid Build Coastguard Worker
942*35238bceSAndroid Build Coastguard Worker protected:
doPrintExpr(ostream &) const943*35238bceSAndroid Build Coastguard Worker virtual void doPrintExpr(ostream &) const
944*35238bceSAndroid Build Coastguard Worker {
945*35238bceSAndroid Build Coastguard Worker }
doGetUsedFuncs(FuncSet &) const946*35238bceSAndroid Build Coastguard Worker virtual void doGetUsedFuncs(FuncSet &) const
947*35238bceSAndroid Build Coastguard Worker {
948*35238bceSAndroid Build Coastguard Worker }
949*35238bceSAndroid Build Coastguard Worker };
950*35238bceSAndroid Build Coastguard Worker
951*35238bceSAndroid Build Coastguard Worker //! Type-specific operations for an expression representing type T.
952*35238bceSAndroid Build Coastguard Worker template <typename T>
953*35238bceSAndroid Build Coastguard Worker class Expr : public ExprBase
954*35238bceSAndroid Build Coastguard Worker {
955*35238bceSAndroid Build Coastguard Worker public:
956*35238bceSAndroid Build Coastguard Worker typedef T Val;
957*35238bceSAndroid Build Coastguard Worker typedef typename Traits<T>::IVal IVal;
958*35238bceSAndroid Build Coastguard Worker
959*35238bceSAndroid Build Coastguard Worker IVal evaluate(const EvalContext &ctx) const;
960*35238bceSAndroid Build Coastguard Worker
961*35238bceSAndroid Build Coastguard Worker protected:
962*35238bceSAndroid Build Coastguard Worker virtual IVal doEvaluate(const EvalContext &ctx) const = 0;
963*35238bceSAndroid Build Coastguard Worker };
964*35238bceSAndroid Build Coastguard Worker
965*35238bceSAndroid Build Coastguard Worker //! Evaluate an expression with the given context, optionally tracing the calls to stderr.
966*35238bceSAndroid Build Coastguard Worker template <typename T>
evaluate(const EvalContext & ctx) const967*35238bceSAndroid Build Coastguard Worker typename Traits<T>::IVal Expr<T>::evaluate(const EvalContext &ctx) const
968*35238bceSAndroid Build Coastguard Worker {
969*35238bceSAndroid Build Coastguard Worker #ifdef GLS_ENABLE_TRACE
970*35238bceSAndroid Build Coastguard Worker static const FloatFormat highpFmt(-126, 127, 23, true, tcu::MAYBE, tcu::YES, tcu::MAYBE);
971*35238bceSAndroid Build Coastguard Worker EvalContext newCtx(ctx.format, ctx.floatPrecision, ctx.env, ctx.callDepth + 1);
972*35238bceSAndroid Build Coastguard Worker const IVal ret = this->doEvaluate(newCtx);
973*35238bceSAndroid Build Coastguard Worker
974*35238bceSAndroid Build Coastguard Worker if (isTypeValid<T>())
975*35238bceSAndroid Build Coastguard Worker {
976*35238bceSAndroid Build Coastguard Worker std::cerr << string(ctx.callDepth, ' ');
977*35238bceSAndroid Build Coastguard Worker this->printExpr(std::cerr);
978*35238bceSAndroid Build Coastguard Worker std::cerr << " -> " << intervalToString<T>(highpFmt, ret) << std::endl;
979*35238bceSAndroid Build Coastguard Worker }
980*35238bceSAndroid Build Coastguard Worker return ret;
981*35238bceSAndroid Build Coastguard Worker #else
982*35238bceSAndroid Build Coastguard Worker return this->doEvaluate(ctx);
983*35238bceSAndroid Build Coastguard Worker #endif
984*35238bceSAndroid Build Coastguard Worker }
985*35238bceSAndroid Build Coastguard Worker
986*35238bceSAndroid Build Coastguard Worker template <typename T>
987*35238bceSAndroid Build Coastguard Worker class ExprPBase : public SharedPtr<const Expr<T>>
988*35238bceSAndroid Build Coastguard Worker {
989*35238bceSAndroid Build Coastguard Worker public:
990*35238bceSAndroid Build Coastguard Worker };
991*35238bceSAndroid Build Coastguard Worker
operator <<(ostream & os,const ExprBase & expr)992*35238bceSAndroid Build Coastguard Worker ostream &operator<<(ostream &os, const ExprBase &expr)
993*35238bceSAndroid Build Coastguard Worker {
994*35238bceSAndroid Build Coastguard Worker expr.printExpr(os);
995*35238bceSAndroid Build Coastguard Worker return os;
996*35238bceSAndroid Build Coastguard Worker }
997*35238bceSAndroid Build Coastguard Worker
998*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
999*35238bceSAndroid Build Coastguard Worker * \brief Shared pointer to an expression of a container type.
1000*35238bceSAndroid Build Coastguard Worker *
1001*35238bceSAndroid Build Coastguard Worker * Container types (i.e. vectors and matrices) support the subscription
1002*35238bceSAndroid Build Coastguard Worker * operator. This class provides a bit of syntactic sugar to allow us to use
1003*35238bceSAndroid Build Coastguard Worker * the C++ subscription operator to create a subscription expression.
1004*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1005*35238bceSAndroid Build Coastguard Worker template <typename T>
1006*35238bceSAndroid Build Coastguard Worker class ContainerExprPBase : public ExprPBase<T>
1007*35238bceSAndroid Build Coastguard Worker {
1008*35238bceSAndroid Build Coastguard Worker public:
1009*35238bceSAndroid Build Coastguard Worker ExprP<typename T::Element> operator[](int i) const;
1010*35238bceSAndroid Build Coastguard Worker };
1011*35238bceSAndroid Build Coastguard Worker
1012*35238bceSAndroid Build Coastguard Worker template <typename T>
1013*35238bceSAndroid Build Coastguard Worker class ExprP : public ExprPBase<T>
1014*35238bceSAndroid Build Coastguard Worker {
1015*35238bceSAndroid Build Coastguard Worker };
1016*35238bceSAndroid Build Coastguard Worker
1017*35238bceSAndroid Build Coastguard Worker // We treat Voids as containers since the unused parameters in generalized
1018*35238bceSAndroid Build Coastguard Worker // vector functions are represented as Voids.
1019*35238bceSAndroid Build Coastguard Worker template <>
1020*35238bceSAndroid Build Coastguard Worker class ExprP<Void> : public ContainerExprPBase<Void>
1021*35238bceSAndroid Build Coastguard Worker {
1022*35238bceSAndroid Build Coastguard Worker };
1023*35238bceSAndroid Build Coastguard Worker
1024*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
1025*35238bceSAndroid Build Coastguard Worker class ExprP<Vector<T, Size>> : public ContainerExprPBase<Vector<T, Size>>
1026*35238bceSAndroid Build Coastguard Worker {
1027*35238bceSAndroid Build Coastguard Worker };
1028*35238bceSAndroid Build Coastguard Worker
1029*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
1030*35238bceSAndroid Build Coastguard Worker class ExprP<Matrix<T, Rows, Cols>> : public ContainerExprPBase<Matrix<T, Rows, Cols>>
1031*35238bceSAndroid Build Coastguard Worker {
1032*35238bceSAndroid Build Coastguard Worker };
1033*35238bceSAndroid Build Coastguard Worker
1034*35238bceSAndroid Build Coastguard Worker template <typename T>
exprP(void)1035*35238bceSAndroid Build Coastguard Worker ExprP<T> exprP(void)
1036*35238bceSAndroid Build Coastguard Worker {
1037*35238bceSAndroid Build Coastguard Worker return ExprP<T>();
1038*35238bceSAndroid Build Coastguard Worker }
1039*35238bceSAndroid Build Coastguard Worker
1040*35238bceSAndroid Build Coastguard Worker template <typename T>
exprP(const SharedPtr<const Expr<T>> & ptr)1041*35238bceSAndroid Build Coastguard Worker ExprP<T> exprP(const SharedPtr<const Expr<T>> &ptr)
1042*35238bceSAndroid Build Coastguard Worker {
1043*35238bceSAndroid Build Coastguard Worker ExprP<T> ret;
1044*35238bceSAndroid Build Coastguard Worker static_cast<SharedPtr<const Expr<T>> &>(ret) = ptr;
1045*35238bceSAndroid Build Coastguard Worker return ret;
1046*35238bceSAndroid Build Coastguard Worker }
1047*35238bceSAndroid Build Coastguard Worker
1048*35238bceSAndroid Build Coastguard Worker template <typename T>
exprP(const Expr<T> * ptr)1049*35238bceSAndroid Build Coastguard Worker ExprP<T> exprP(const Expr<T> *ptr)
1050*35238bceSAndroid Build Coastguard Worker {
1051*35238bceSAndroid Build Coastguard Worker return exprP(SharedPtr<const Expr<T>>(ptr));
1052*35238bceSAndroid Build Coastguard Worker }
1053*35238bceSAndroid Build Coastguard Worker
1054*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1055*35238bceSAndroid Build Coastguard Worker * \brief A shared pointer to a variable expression.
1056*35238bceSAndroid Build Coastguard Worker *
1057*35238bceSAndroid Build Coastguard Worker * This is just a narrowing of ExprP for the operations that require a variable
1058*35238bceSAndroid Build Coastguard Worker * instead of an arbitrary expression.
1059*35238bceSAndroid Build Coastguard Worker *
1060*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1061*35238bceSAndroid Build Coastguard Worker template <typename T>
1062*35238bceSAndroid Build Coastguard Worker class VariableP : public SharedPtr<const Variable<T>>
1063*35238bceSAndroid Build Coastguard Worker {
1064*35238bceSAndroid Build Coastguard Worker public:
1065*35238bceSAndroid Build Coastguard Worker typedef SharedPtr<const Variable<T>> Super;
VariableP(const Variable<T> * ptr)1066*35238bceSAndroid Build Coastguard Worker explicit VariableP(const Variable<T> *ptr) : Super(ptr)
1067*35238bceSAndroid Build Coastguard Worker {
1068*35238bceSAndroid Build Coastguard Worker }
VariableP(void)1069*35238bceSAndroid Build Coastguard Worker VariableP(void)
1070*35238bceSAndroid Build Coastguard Worker {
1071*35238bceSAndroid Build Coastguard Worker }
VariableP(const Super & ptr)1072*35238bceSAndroid Build Coastguard Worker VariableP(const Super &ptr) : Super(ptr)
1073*35238bceSAndroid Build Coastguard Worker {
1074*35238bceSAndroid Build Coastguard Worker }
1075*35238bceSAndroid Build Coastguard Worker
operator ExprP<T>(void) const1076*35238bceSAndroid Build Coastguard Worker operator ExprP<T>(void) const
1077*35238bceSAndroid Build Coastguard Worker {
1078*35238bceSAndroid Build Coastguard Worker SharedPtr<const Expr<T>> ptr = *this;
1079*35238bceSAndroid Build Coastguard Worker return exprP(ptr);
1080*35238bceSAndroid Build Coastguard Worker }
1081*35238bceSAndroid Build Coastguard Worker };
1082*35238bceSAndroid Build Coastguard Worker
1083*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1084*35238bceSAndroid Build Coastguard Worker * \name Syntactic sugar operators for expressions.
1085*35238bceSAndroid Build Coastguard Worker *
1086*35238bceSAndroid Build Coastguard Worker * @{
1087*35238bceSAndroid Build Coastguard Worker *
1088*35238bceSAndroid Build Coastguard Worker * These operators allow the use of C++ syntax to construct GLSL expressions
1089*35238bceSAndroid Build Coastguard Worker * containing operators: e.g. "a+b" creates an addition expression with
1090*35238bceSAndroid Build Coastguard Worker * operands a and b, and so on.
1091*35238bceSAndroid Build Coastguard Worker *
1092*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1093*35238bceSAndroid Build Coastguard Worker ExprP<float> operator-(const ExprP<float> &arg0);
1094*35238bceSAndroid Build Coastguard Worker ExprP<float> operator+(const ExprP<float> &arg0, const ExprP<float> &arg1);
1095*35238bceSAndroid Build Coastguard Worker ExprP<float> operator-(const ExprP<float> &arg0, const ExprP<float> &arg1);
1096*35238bceSAndroid Build Coastguard Worker ExprP<float> operator*(const ExprP<float> &arg0, const ExprP<float> &arg1);
1097*35238bceSAndroid Build Coastguard Worker ExprP<float> operator/(const ExprP<float> &arg0, const ExprP<float> &arg1);
1098*35238bceSAndroid Build Coastguard Worker template <int Size>
1099*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator-(const ExprP<Vector<float, Size>> &arg0);
1100*35238bceSAndroid Build Coastguard Worker template <int Size>
1101*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator*(const ExprP<Vector<float, Size>> &arg0, const ExprP<float> &arg1);
1102*35238bceSAndroid Build Coastguard Worker template <int Size>
1103*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator*(const ExprP<Vector<float, Size>> &arg0, const ExprP<Vector<float, Size>> &arg1);
1104*35238bceSAndroid Build Coastguard Worker template <int Size>
1105*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator-(const ExprP<Vector<float, Size>> &arg0, const ExprP<Vector<float, Size>> &arg1);
1106*35238bceSAndroid Build Coastguard Worker template <int Left, int Mid, int Right>
1107*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Left, Right>> operator*(const ExprP<Matrix<float, Left, Mid>> &left,
1108*35238bceSAndroid Build Coastguard Worker const ExprP<Matrix<float, Mid, Right>> &right);
1109*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
1110*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Rows>> operator*(const ExprP<Vector<float, Cols>> &left,
1111*35238bceSAndroid Build Coastguard Worker const ExprP<Matrix<float, Rows, Cols>> &right);
1112*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
1113*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Cols>> operator*(const ExprP<Matrix<float, Rows, Cols>> &left,
1114*35238bceSAndroid Build Coastguard Worker const ExprP<Vector<float, Rows>> &right);
1115*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
1116*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Rows, Cols>> operator*(const ExprP<Matrix<float, Rows, Cols>> &left, const ExprP<float> &right);
1117*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
1118*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Rows, Cols>> operator+(const ExprP<Matrix<float, Rows, Cols>> &left,
1119*35238bceSAndroid Build Coastguard Worker const ExprP<Matrix<float, Rows, Cols>> &right);
1120*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
1121*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Rows, Cols>> operator-(const ExprP<Matrix<float, Rows, Cols>> &mat);
1122*35238bceSAndroid Build Coastguard Worker
1123*35238bceSAndroid Build Coastguard Worker //! @}
1124*35238bceSAndroid Build Coastguard Worker
1125*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1126*35238bceSAndroid Build Coastguard Worker * \brief Variable expression.
1127*35238bceSAndroid Build Coastguard Worker *
1128*35238bceSAndroid Build Coastguard Worker * A variable is evaluated by looking up its range of possible values from an
1129*35238bceSAndroid Build Coastguard Worker * environment.
1130*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1131*35238bceSAndroid Build Coastguard Worker template <typename T>
1132*35238bceSAndroid Build Coastguard Worker class Variable : public Expr<T>
1133*35238bceSAndroid Build Coastguard Worker {
1134*35238bceSAndroid Build Coastguard Worker public:
1135*35238bceSAndroid Build Coastguard Worker typedef typename Expr<T>::IVal IVal;
1136*35238bceSAndroid Build Coastguard Worker
Variable(const string & name)1137*35238bceSAndroid Build Coastguard Worker Variable(const string &name) : m_name(name)
1138*35238bceSAndroid Build Coastguard Worker {
1139*35238bceSAndroid Build Coastguard Worker }
getName(void) const1140*35238bceSAndroid Build Coastguard Worker string getName(void) const
1141*35238bceSAndroid Build Coastguard Worker {
1142*35238bceSAndroid Build Coastguard Worker return m_name;
1143*35238bceSAndroid Build Coastguard Worker }
1144*35238bceSAndroid Build Coastguard Worker
1145*35238bceSAndroid Build Coastguard Worker protected:
doPrintExpr(ostream & os) const1146*35238bceSAndroid Build Coastguard Worker void doPrintExpr(ostream &os) const
1147*35238bceSAndroid Build Coastguard Worker {
1148*35238bceSAndroid Build Coastguard Worker os << m_name;
1149*35238bceSAndroid Build Coastguard Worker }
doEvaluate(const EvalContext & ctx) const1150*35238bceSAndroid Build Coastguard Worker IVal doEvaluate(const EvalContext &ctx) const
1151*35238bceSAndroid Build Coastguard Worker {
1152*35238bceSAndroid Build Coastguard Worker return ctx.env.lookup<T>(*this);
1153*35238bceSAndroid Build Coastguard Worker }
1154*35238bceSAndroid Build Coastguard Worker
1155*35238bceSAndroid Build Coastguard Worker private:
1156*35238bceSAndroid Build Coastguard Worker string m_name;
1157*35238bceSAndroid Build Coastguard Worker };
1158*35238bceSAndroid Build Coastguard Worker
1159*35238bceSAndroid Build Coastguard Worker template <typename T>
variable(const string & name)1160*35238bceSAndroid Build Coastguard Worker VariableP<T> variable(const string &name)
1161*35238bceSAndroid Build Coastguard Worker {
1162*35238bceSAndroid Build Coastguard Worker return VariableP<T>(new Variable<T>(name));
1163*35238bceSAndroid Build Coastguard Worker }
1164*35238bceSAndroid Build Coastguard Worker
1165*35238bceSAndroid Build Coastguard Worker template <typename T>
bindExpression(const string & name,ExpandContext & ctx,const ExprP<T> & expr)1166*35238bceSAndroid Build Coastguard Worker VariableP<T> bindExpression(const string &name, ExpandContext &ctx, const ExprP<T> &expr)
1167*35238bceSAndroid Build Coastguard Worker {
1168*35238bceSAndroid Build Coastguard Worker VariableP<T> var = ctx.genSym<T>(name);
1169*35238bceSAndroid Build Coastguard Worker ctx.addStatement(variableDeclaration(var, expr));
1170*35238bceSAndroid Build Coastguard Worker return var;
1171*35238bceSAndroid Build Coastguard Worker }
1172*35238bceSAndroid Build Coastguard Worker
1173*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1174*35238bceSAndroid Build Coastguard Worker * \brief Constant expression.
1175*35238bceSAndroid Build Coastguard Worker *
1176*35238bceSAndroid Build Coastguard Worker * A constant is evaluated by rounding it to a set of possible values allowed
1177*35238bceSAndroid Build Coastguard Worker * by the current floating point precision.
1178*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1179*35238bceSAndroid Build Coastguard Worker template <typename T>
1180*35238bceSAndroid Build Coastguard Worker class Constant : public Expr<T>
1181*35238bceSAndroid Build Coastguard Worker {
1182*35238bceSAndroid Build Coastguard Worker public:
1183*35238bceSAndroid Build Coastguard Worker typedef typename Expr<T>::IVal IVal;
1184*35238bceSAndroid Build Coastguard Worker
Constant(const T & value)1185*35238bceSAndroid Build Coastguard Worker Constant(const T &value) : m_value(value)
1186*35238bceSAndroid Build Coastguard Worker {
1187*35238bceSAndroid Build Coastguard Worker }
1188*35238bceSAndroid Build Coastguard Worker
1189*35238bceSAndroid Build Coastguard Worker protected:
doPrintExpr(ostream & os) const1190*35238bceSAndroid Build Coastguard Worker void doPrintExpr(ostream &os) const
1191*35238bceSAndroid Build Coastguard Worker {
1192*35238bceSAndroid Build Coastguard Worker os << m_value;
1193*35238bceSAndroid Build Coastguard Worker }
doEvaluate(const EvalContext &) const1194*35238bceSAndroid Build Coastguard Worker IVal doEvaluate(const EvalContext &) const
1195*35238bceSAndroid Build Coastguard Worker {
1196*35238bceSAndroid Build Coastguard Worker return makeIVal(m_value);
1197*35238bceSAndroid Build Coastguard Worker }
1198*35238bceSAndroid Build Coastguard Worker
1199*35238bceSAndroid Build Coastguard Worker private:
1200*35238bceSAndroid Build Coastguard Worker T m_value;
1201*35238bceSAndroid Build Coastguard Worker };
1202*35238bceSAndroid Build Coastguard Worker
1203*35238bceSAndroid Build Coastguard Worker template <typename T>
constant(const T & value)1204*35238bceSAndroid Build Coastguard Worker ExprP<T> constant(const T &value)
1205*35238bceSAndroid Build Coastguard Worker {
1206*35238bceSAndroid Build Coastguard Worker return exprP(new Constant<T>(value));
1207*35238bceSAndroid Build Coastguard Worker }
1208*35238bceSAndroid Build Coastguard Worker
1209*35238bceSAndroid Build Coastguard Worker //! Return a reference to a singleton void constant.
voidP(void)1210*35238bceSAndroid Build Coastguard Worker const ExprP<Void> &voidP(void)
1211*35238bceSAndroid Build Coastguard Worker {
1212*35238bceSAndroid Build Coastguard Worker static const ExprP<Void> singleton = constant(Void());
1213*35238bceSAndroid Build Coastguard Worker
1214*35238bceSAndroid Build Coastguard Worker return singleton;
1215*35238bceSAndroid Build Coastguard Worker }
1216*35238bceSAndroid Build Coastguard Worker
1217*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1218*35238bceSAndroid Build Coastguard Worker * \brief Four-element tuple.
1219*35238bceSAndroid Build Coastguard Worker *
1220*35238bceSAndroid Build Coastguard Worker * This is used for various things where we need one thing for each possible
1221*35238bceSAndroid Build Coastguard Worker * function parameter. Currently the maximum supported number of parameters is
1222*35238bceSAndroid Build Coastguard Worker * four.
1223*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1224*35238bceSAndroid Build Coastguard Worker template <typename T0 = Void, typename T1 = Void, typename T2 = Void, typename T3 = Void>
1225*35238bceSAndroid Build Coastguard Worker struct Tuple4
1226*35238bceSAndroid Build Coastguard Worker {
Tuple4deqp::gls::BuiltinPrecisionTests::Tuple41227*35238bceSAndroid Build Coastguard Worker explicit Tuple4(const T0 e0 = T0(), const T1 e1 = T1(), const T2 e2 = T2(), const T3 e3 = T3())
1228*35238bceSAndroid Build Coastguard Worker : a(e0)
1229*35238bceSAndroid Build Coastguard Worker , b(e1)
1230*35238bceSAndroid Build Coastguard Worker , c(e2)
1231*35238bceSAndroid Build Coastguard Worker , d(e3)
1232*35238bceSAndroid Build Coastguard Worker {
1233*35238bceSAndroid Build Coastguard Worker }
1234*35238bceSAndroid Build Coastguard Worker
1235*35238bceSAndroid Build Coastguard Worker T0 a;
1236*35238bceSAndroid Build Coastguard Worker T1 b;
1237*35238bceSAndroid Build Coastguard Worker T2 c;
1238*35238bceSAndroid Build Coastguard Worker T3 d;
1239*35238bceSAndroid Build Coastguard Worker };
1240*35238bceSAndroid Build Coastguard Worker
1241*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1242*35238bceSAndroid Build Coastguard Worker * \brief Function signature.
1243*35238bceSAndroid Build Coastguard Worker *
1244*35238bceSAndroid Build Coastguard Worker * This is a purely compile-time structure used to bundle all types in a
1245*35238bceSAndroid Build Coastguard Worker * function signature together. This makes passing the signature around in
1246*35238bceSAndroid Build Coastguard Worker * templates easier, since we only need to take and pass a single Sig instead
1247*35238bceSAndroid Build Coastguard Worker * of a bunch of parameter types and a return type.
1248*35238bceSAndroid Build Coastguard Worker *
1249*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1250*35238bceSAndroid Build Coastguard Worker template <typename R, typename P0 = Void, typename P1 = Void, typename P2 = Void, typename P3 = Void>
1251*35238bceSAndroid Build Coastguard Worker struct Signature
1252*35238bceSAndroid Build Coastguard Worker {
1253*35238bceSAndroid Build Coastguard Worker typedef R Ret;
1254*35238bceSAndroid Build Coastguard Worker typedef P0 Arg0;
1255*35238bceSAndroid Build Coastguard Worker typedef P1 Arg1;
1256*35238bceSAndroid Build Coastguard Worker typedef P2 Arg2;
1257*35238bceSAndroid Build Coastguard Worker typedef P3 Arg3;
1258*35238bceSAndroid Build Coastguard Worker typedef typename Traits<Ret>::IVal IRet;
1259*35238bceSAndroid Build Coastguard Worker typedef typename Traits<Arg0>::IVal IArg0;
1260*35238bceSAndroid Build Coastguard Worker typedef typename Traits<Arg1>::IVal IArg1;
1261*35238bceSAndroid Build Coastguard Worker typedef typename Traits<Arg2>::IVal IArg2;
1262*35238bceSAndroid Build Coastguard Worker typedef typename Traits<Arg3>::IVal IArg3;
1263*35238bceSAndroid Build Coastguard Worker
1264*35238bceSAndroid Build Coastguard Worker typedef Tuple4<const Arg0 &, const Arg1 &, const Arg2 &, const Arg3 &> Args;
1265*35238bceSAndroid Build Coastguard Worker typedef Tuple4<const IArg0 &, const IArg1 &, const IArg2 &, const IArg3 &> IArgs;
1266*35238bceSAndroid Build Coastguard Worker typedef Tuple4<ExprP<Arg0>, ExprP<Arg1>, ExprP<Arg2>, ExprP<Arg3>> ArgExprs;
1267*35238bceSAndroid Build Coastguard Worker };
1268*35238bceSAndroid Build Coastguard Worker
1269*35238bceSAndroid Build Coastguard Worker typedef vector<const ExprBase *> BaseArgExprs;
1270*35238bceSAndroid Build Coastguard Worker
1271*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1272*35238bceSAndroid Build Coastguard Worker * \brief Type-independent operations for function objects.
1273*35238bceSAndroid Build Coastguard Worker *
1274*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1275*35238bceSAndroid Build Coastguard Worker class FuncBase
1276*35238bceSAndroid Build Coastguard Worker {
1277*35238bceSAndroid Build Coastguard Worker public:
~FuncBase(void)1278*35238bceSAndroid Build Coastguard Worker virtual ~FuncBase(void)
1279*35238bceSAndroid Build Coastguard Worker {
1280*35238bceSAndroid Build Coastguard Worker }
1281*35238bceSAndroid Build Coastguard Worker virtual string getName(void) const = 0;
1282*35238bceSAndroid Build Coastguard Worker //! Name of extension that this function requires, or empty.
getRequiredExtension(const RenderContext &) const1283*35238bceSAndroid Build Coastguard Worker virtual string getRequiredExtension(const RenderContext &) const
1284*35238bceSAndroid Build Coastguard Worker {
1285*35238bceSAndroid Build Coastguard Worker return "";
1286*35238bceSAndroid Build Coastguard Worker }
1287*35238bceSAndroid Build Coastguard Worker virtual void print(ostream &, const BaseArgExprs &) const = 0;
1288*35238bceSAndroid Build Coastguard Worker //! Index of output parameter, or -1 if none of the parameters is output.
getOutParamIndex(void) const1289*35238bceSAndroid Build Coastguard Worker virtual int getOutParamIndex(void) const
1290*35238bceSAndroid Build Coastguard Worker {
1291*35238bceSAndroid Build Coastguard Worker return -1;
1292*35238bceSAndroid Build Coastguard Worker }
1293*35238bceSAndroid Build Coastguard Worker
printDefinition(ostream & os) const1294*35238bceSAndroid Build Coastguard Worker void printDefinition(ostream &os) const
1295*35238bceSAndroid Build Coastguard Worker {
1296*35238bceSAndroid Build Coastguard Worker doPrintDefinition(os);
1297*35238bceSAndroid Build Coastguard Worker }
1298*35238bceSAndroid Build Coastguard Worker
getUsedFuncs(FuncSet & dst) const1299*35238bceSAndroid Build Coastguard Worker void getUsedFuncs(FuncSet &dst) const
1300*35238bceSAndroid Build Coastguard Worker {
1301*35238bceSAndroid Build Coastguard Worker this->doGetUsedFuncs(dst);
1302*35238bceSAndroid Build Coastguard Worker }
1303*35238bceSAndroid Build Coastguard Worker
1304*35238bceSAndroid Build Coastguard Worker protected:
1305*35238bceSAndroid Build Coastguard Worker virtual void doPrintDefinition(ostream &os) const = 0;
1306*35238bceSAndroid Build Coastguard Worker virtual void doGetUsedFuncs(FuncSet &dst) const = 0;
1307*35238bceSAndroid Build Coastguard Worker };
1308*35238bceSAndroid Build Coastguard Worker
1309*35238bceSAndroid Build Coastguard Worker typedef Tuple4<string, string, string, string> ParamNames;
1310*35238bceSAndroid Build Coastguard Worker
1311*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1312*35238bceSAndroid Build Coastguard Worker * \brief Function objects.
1313*35238bceSAndroid Build Coastguard Worker *
1314*35238bceSAndroid Build Coastguard Worker * Each Func object represents a GLSL function. It can be applied to interval
1315*35238bceSAndroid Build Coastguard Worker * arguments, and it returns the an interval that is a conservative
1316*35238bceSAndroid Build Coastguard Worker * approximation of the image of the GLSL function over the argument
1317*35238bceSAndroid Build Coastguard Worker * intervals. That is, it is given a set of possible arguments and it returns
1318*35238bceSAndroid Build Coastguard Worker * the set of possible values.
1319*35238bceSAndroid Build Coastguard Worker *
1320*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1321*35238bceSAndroid Build Coastguard Worker template <typename Sig_>
1322*35238bceSAndroid Build Coastguard Worker class Func : public FuncBase
1323*35238bceSAndroid Build Coastguard Worker {
1324*35238bceSAndroid Build Coastguard Worker public:
1325*35238bceSAndroid Build Coastguard Worker typedef Sig_ Sig;
1326*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Ret Ret;
1327*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg0 Arg0;
1328*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg1 Arg1;
1329*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg2 Arg2;
1330*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg3 Arg3;
1331*35238bceSAndroid Build Coastguard Worker typedef typename Sig::IRet IRet;
1332*35238bceSAndroid Build Coastguard Worker typedef typename Sig::IArg0 IArg0;
1333*35238bceSAndroid Build Coastguard Worker typedef typename Sig::IArg1 IArg1;
1334*35238bceSAndroid Build Coastguard Worker typedef typename Sig::IArg2 IArg2;
1335*35238bceSAndroid Build Coastguard Worker typedef typename Sig::IArg3 IArg3;
1336*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Args Args;
1337*35238bceSAndroid Build Coastguard Worker typedef typename Sig::IArgs IArgs;
1338*35238bceSAndroid Build Coastguard Worker typedef typename Sig::ArgExprs ArgExprs;
1339*35238bceSAndroid Build Coastguard Worker
print(ostream & os,const BaseArgExprs & args) const1340*35238bceSAndroid Build Coastguard Worker void print(ostream &os, const BaseArgExprs &args) const
1341*35238bceSAndroid Build Coastguard Worker {
1342*35238bceSAndroid Build Coastguard Worker this->doPrint(os, args);
1343*35238bceSAndroid Build Coastguard Worker }
1344*35238bceSAndroid Build Coastguard Worker
apply(const EvalContext & ctx,const IArg0 & arg0=IArg0 (),const IArg1 & arg1=IArg1 (),const IArg2 & arg2=IArg2 (),const IArg3 & arg3=IArg3 ()) const1345*35238bceSAndroid Build Coastguard Worker IRet apply(const EvalContext &ctx, const IArg0 &arg0 = IArg0(), const IArg1 &arg1 = IArg1(),
1346*35238bceSAndroid Build Coastguard Worker const IArg2 &arg2 = IArg2(), const IArg3 &arg3 = IArg3()) const
1347*35238bceSAndroid Build Coastguard Worker {
1348*35238bceSAndroid Build Coastguard Worker return this->applyArgs(ctx, IArgs(arg0, arg1, arg2, arg3));
1349*35238bceSAndroid Build Coastguard Worker }
applyArgs(const EvalContext & ctx,const IArgs & args) const1350*35238bceSAndroid Build Coastguard Worker IRet applyArgs(const EvalContext &ctx, const IArgs &args) const
1351*35238bceSAndroid Build Coastguard Worker {
1352*35238bceSAndroid Build Coastguard Worker return this->doApply(ctx, args);
1353*35238bceSAndroid Build Coastguard Worker }
1354*35238bceSAndroid Build Coastguard Worker ExprP<Ret> operator()(const ExprP<Arg0> &arg0 = voidP(), const ExprP<Arg1> &arg1 = voidP(),
1355*35238bceSAndroid Build Coastguard Worker const ExprP<Arg2> &arg2 = voidP(), const ExprP<Arg3> &arg3 = voidP()) const;
1356*35238bceSAndroid Build Coastguard Worker
getParamNames(void) const1357*35238bceSAndroid Build Coastguard Worker const ParamNames &getParamNames(void) const
1358*35238bceSAndroid Build Coastguard Worker {
1359*35238bceSAndroid Build Coastguard Worker return this->doGetParamNames();
1360*35238bceSAndroid Build Coastguard Worker }
1361*35238bceSAndroid Build Coastguard Worker
1362*35238bceSAndroid Build Coastguard Worker protected:
1363*35238bceSAndroid Build Coastguard Worker virtual IRet doApply(const EvalContext &, const IArgs &) const = 0;
doPrint(ostream & os,const BaseArgExprs & args) const1364*35238bceSAndroid Build Coastguard Worker virtual void doPrint(ostream &os, const BaseArgExprs &args) const
1365*35238bceSAndroid Build Coastguard Worker {
1366*35238bceSAndroid Build Coastguard Worker os << getName() << "(";
1367*35238bceSAndroid Build Coastguard Worker
1368*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg0>())
1369*35238bceSAndroid Build Coastguard Worker os << *args[0];
1370*35238bceSAndroid Build Coastguard Worker
1371*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg1>())
1372*35238bceSAndroid Build Coastguard Worker os << ", " << *args[1];
1373*35238bceSAndroid Build Coastguard Worker
1374*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg2>())
1375*35238bceSAndroid Build Coastguard Worker os << ", " << *args[2];
1376*35238bceSAndroid Build Coastguard Worker
1377*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg3>())
1378*35238bceSAndroid Build Coastguard Worker os << ", " << *args[3];
1379*35238bceSAndroid Build Coastguard Worker
1380*35238bceSAndroid Build Coastguard Worker os << ")";
1381*35238bceSAndroid Build Coastguard Worker }
1382*35238bceSAndroid Build Coastguard Worker
doGetParamNames(void) const1383*35238bceSAndroid Build Coastguard Worker virtual const ParamNames &doGetParamNames(void) const
1384*35238bceSAndroid Build Coastguard Worker {
1385*35238bceSAndroid Build Coastguard Worker static ParamNames names("a", "b", "c", "d");
1386*35238bceSAndroid Build Coastguard Worker return names;
1387*35238bceSAndroid Build Coastguard Worker }
1388*35238bceSAndroid Build Coastguard Worker };
1389*35238bceSAndroid Build Coastguard Worker
1390*35238bceSAndroid Build Coastguard Worker template <typename Sig>
1391*35238bceSAndroid Build Coastguard Worker class Apply : public Expr<typename Sig::Ret>
1392*35238bceSAndroid Build Coastguard Worker {
1393*35238bceSAndroid Build Coastguard Worker public:
1394*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Ret Ret;
1395*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg0 Arg0;
1396*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg1 Arg1;
1397*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg2 Arg2;
1398*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg3 Arg3;
1399*35238bceSAndroid Build Coastguard Worker typedef typename Expr<Ret>::Val Val;
1400*35238bceSAndroid Build Coastguard Worker typedef typename Expr<Ret>::IVal IVal;
1401*35238bceSAndroid Build Coastguard Worker typedef Func<Sig> ApplyFunc;
1402*35238bceSAndroid Build Coastguard Worker typedef typename ApplyFunc::ArgExprs ArgExprs;
1403*35238bceSAndroid Build Coastguard Worker
Apply(const ApplyFunc & func,const ExprP<Arg0> & arg0=voidP (),const ExprP<Arg1> & arg1=voidP (),const ExprP<Arg2> & arg2=voidP (),const ExprP<Arg3> & arg3=voidP ())1404*35238bceSAndroid Build Coastguard Worker Apply(const ApplyFunc &func, const ExprP<Arg0> &arg0 = voidP(), const ExprP<Arg1> &arg1 = voidP(),
1405*35238bceSAndroid Build Coastguard Worker const ExprP<Arg2> &arg2 = voidP(), const ExprP<Arg3> &arg3 = voidP())
1406*35238bceSAndroid Build Coastguard Worker : m_func(func)
1407*35238bceSAndroid Build Coastguard Worker , m_args(arg0, arg1, arg2, arg3)
1408*35238bceSAndroid Build Coastguard Worker {
1409*35238bceSAndroid Build Coastguard Worker }
1410*35238bceSAndroid Build Coastguard Worker
Apply(const ApplyFunc & func,const ArgExprs & args)1411*35238bceSAndroid Build Coastguard Worker Apply(const ApplyFunc &func, const ArgExprs &args) : m_func(func), m_args(args)
1412*35238bceSAndroid Build Coastguard Worker {
1413*35238bceSAndroid Build Coastguard Worker }
1414*35238bceSAndroid Build Coastguard Worker
1415*35238bceSAndroid Build Coastguard Worker protected:
doPrintExpr(ostream & os) const1416*35238bceSAndroid Build Coastguard Worker void doPrintExpr(ostream &os) const
1417*35238bceSAndroid Build Coastguard Worker {
1418*35238bceSAndroid Build Coastguard Worker BaseArgExprs args;
1419*35238bceSAndroid Build Coastguard Worker args.push_back(m_args.a.get());
1420*35238bceSAndroid Build Coastguard Worker args.push_back(m_args.b.get());
1421*35238bceSAndroid Build Coastguard Worker args.push_back(m_args.c.get());
1422*35238bceSAndroid Build Coastguard Worker args.push_back(m_args.d.get());
1423*35238bceSAndroid Build Coastguard Worker m_func.print(os, args);
1424*35238bceSAndroid Build Coastguard Worker }
1425*35238bceSAndroid Build Coastguard Worker
doEvaluate(const EvalContext & ctx) const1426*35238bceSAndroid Build Coastguard Worker IVal doEvaluate(const EvalContext &ctx) const
1427*35238bceSAndroid Build Coastguard Worker {
1428*35238bceSAndroid Build Coastguard Worker return m_func.apply(ctx, m_args.a->evaluate(ctx), m_args.b->evaluate(ctx), m_args.c->evaluate(ctx),
1429*35238bceSAndroid Build Coastguard Worker m_args.d->evaluate(ctx));
1430*35238bceSAndroid Build Coastguard Worker }
1431*35238bceSAndroid Build Coastguard Worker
doGetUsedFuncs(FuncSet & dst) const1432*35238bceSAndroid Build Coastguard Worker void doGetUsedFuncs(FuncSet &dst) const
1433*35238bceSAndroid Build Coastguard Worker {
1434*35238bceSAndroid Build Coastguard Worker m_func.getUsedFuncs(dst);
1435*35238bceSAndroid Build Coastguard Worker m_args.a->getUsedFuncs(dst);
1436*35238bceSAndroid Build Coastguard Worker m_args.b->getUsedFuncs(dst);
1437*35238bceSAndroid Build Coastguard Worker m_args.c->getUsedFuncs(dst);
1438*35238bceSAndroid Build Coastguard Worker m_args.d->getUsedFuncs(dst);
1439*35238bceSAndroid Build Coastguard Worker }
1440*35238bceSAndroid Build Coastguard Worker
1441*35238bceSAndroid Build Coastguard Worker const ApplyFunc &m_func;
1442*35238bceSAndroid Build Coastguard Worker ArgExprs m_args;
1443*35238bceSAndroid Build Coastguard Worker };
1444*35238bceSAndroid Build Coastguard Worker
1445*35238bceSAndroid Build Coastguard Worker template <typename T>
1446*35238bceSAndroid Build Coastguard Worker class Alternatives : public Func<Signature<T, T, T>>
1447*35238bceSAndroid Build Coastguard Worker {
1448*35238bceSAndroid Build Coastguard Worker public:
1449*35238bceSAndroid Build Coastguard Worker typedef typename Alternatives::Sig Sig;
1450*35238bceSAndroid Build Coastguard Worker
1451*35238bceSAndroid Build Coastguard Worker protected:
1452*35238bceSAndroid Build Coastguard Worker typedef typename Alternatives::IRet IRet;
1453*35238bceSAndroid Build Coastguard Worker typedef typename Alternatives::IArgs IArgs;
1454*35238bceSAndroid Build Coastguard Worker
getName(void) const1455*35238bceSAndroid Build Coastguard Worker virtual string getName(void) const
1456*35238bceSAndroid Build Coastguard Worker {
1457*35238bceSAndroid Build Coastguard Worker return "alternatives";
1458*35238bceSAndroid Build Coastguard Worker }
doPrintDefinition(std::ostream &) const1459*35238bceSAndroid Build Coastguard Worker virtual void doPrintDefinition(std::ostream &) const
1460*35238bceSAndroid Build Coastguard Worker {
1461*35238bceSAndroid Build Coastguard Worker }
doGetUsedFuncs(FuncSet &) const1462*35238bceSAndroid Build Coastguard Worker void doGetUsedFuncs(FuncSet &) const
1463*35238bceSAndroid Build Coastguard Worker {
1464*35238bceSAndroid Build Coastguard Worker }
1465*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext &,const IArgs & args) const1466*35238bceSAndroid Build Coastguard Worker virtual IRet doApply(const EvalContext &, const IArgs &args) const
1467*35238bceSAndroid Build Coastguard Worker {
1468*35238bceSAndroid Build Coastguard Worker return unionIVal<T>(args.a, args.b);
1469*35238bceSAndroid Build Coastguard Worker }
1470*35238bceSAndroid Build Coastguard Worker
doPrint(ostream & os,const BaseArgExprs & args) const1471*35238bceSAndroid Build Coastguard Worker virtual void doPrint(ostream &os, const BaseArgExprs &args) const
1472*35238bceSAndroid Build Coastguard Worker {
1473*35238bceSAndroid Build Coastguard Worker os << "{" << *args[0] << " | " << *args[1] << "}";
1474*35238bceSAndroid Build Coastguard Worker }
1475*35238bceSAndroid Build Coastguard Worker };
1476*35238bceSAndroid Build Coastguard Worker
1477*35238bceSAndroid Build Coastguard Worker template <typename Sig>
createApply(const Func<Sig> & func,const typename Func<Sig>::ArgExprs & args)1478*35238bceSAndroid Build Coastguard Worker ExprP<typename Sig::Ret> createApply(const Func<Sig> &func, const typename Func<Sig>::ArgExprs &args)
1479*35238bceSAndroid Build Coastguard Worker {
1480*35238bceSAndroid Build Coastguard Worker return exprP(new Apply<Sig>(func, args));
1481*35238bceSAndroid Build Coastguard Worker }
1482*35238bceSAndroid Build Coastguard Worker
1483*35238bceSAndroid Build Coastguard Worker template <typename Sig>
createApply(const Func<Sig> & func,const ExprP<typename Sig::Arg0> & arg0=voidP (),const ExprP<typename Sig::Arg1> & arg1=voidP (),const ExprP<typename Sig::Arg2> & arg2=voidP (),const ExprP<typename Sig::Arg3> & arg3=voidP ())1484*35238bceSAndroid Build Coastguard Worker ExprP<typename Sig::Ret> createApply(const Func<Sig> &func, const ExprP<typename Sig::Arg0> &arg0 = voidP(),
1485*35238bceSAndroid Build Coastguard Worker const ExprP<typename Sig::Arg1> &arg1 = voidP(),
1486*35238bceSAndroid Build Coastguard Worker const ExprP<typename Sig::Arg2> &arg2 = voidP(),
1487*35238bceSAndroid Build Coastguard Worker const ExprP<typename Sig::Arg3> &arg3 = voidP())
1488*35238bceSAndroid Build Coastguard Worker {
1489*35238bceSAndroid Build Coastguard Worker return exprP(new Apply<Sig>(func, arg0, arg1, arg2, arg3));
1490*35238bceSAndroid Build Coastguard Worker }
1491*35238bceSAndroid Build Coastguard Worker
1492*35238bceSAndroid Build Coastguard Worker template <typename Sig>
operator ()(const ExprP<typename Sig::Arg0> & arg0,const ExprP<typename Sig::Arg1> & arg1,const ExprP<typename Sig::Arg2> & arg2,const ExprP<typename Sig::Arg3> & arg3) const1493*35238bceSAndroid Build Coastguard Worker ExprP<typename Sig::Ret> Func<Sig>::operator()(const ExprP<typename Sig::Arg0> &arg0,
1494*35238bceSAndroid Build Coastguard Worker const ExprP<typename Sig::Arg1> &arg1,
1495*35238bceSAndroid Build Coastguard Worker const ExprP<typename Sig::Arg2> &arg2,
1496*35238bceSAndroid Build Coastguard Worker const ExprP<typename Sig::Arg3> &arg3) const
1497*35238bceSAndroid Build Coastguard Worker {
1498*35238bceSAndroid Build Coastguard Worker return createApply(*this, arg0, arg1, arg2, arg3);
1499*35238bceSAndroid Build Coastguard Worker }
1500*35238bceSAndroid Build Coastguard Worker
1501*35238bceSAndroid Build Coastguard Worker template <typename F>
app(const ExprP<typename F::Arg0> & arg0=voidP (),const ExprP<typename F::Arg1> & arg1=voidP (),const ExprP<typename F::Arg2> & arg2=voidP (),const ExprP<typename F::Arg3> & arg3=voidP ())1502*35238bceSAndroid Build Coastguard Worker ExprP<typename F::Ret> app(const ExprP<typename F::Arg0> &arg0 = voidP(), const ExprP<typename F::Arg1> &arg1 = voidP(),
1503*35238bceSAndroid Build Coastguard Worker const ExprP<typename F::Arg2> &arg2 = voidP(), const ExprP<typename F::Arg3> &arg3 = voidP())
1504*35238bceSAndroid Build Coastguard Worker {
1505*35238bceSAndroid Build Coastguard Worker return createApply(instance<F>(), arg0, arg1, arg2, arg3);
1506*35238bceSAndroid Build Coastguard Worker }
1507*35238bceSAndroid Build Coastguard Worker
1508*35238bceSAndroid Build Coastguard Worker template <typename F>
call(const EvalContext & ctx,const typename F::IArg0 & arg0=Void (),const typename F::IArg1 & arg1=Void (),const typename F::IArg2 & arg2=Void (),const typename F::IArg3 & arg3=Void ())1509*35238bceSAndroid Build Coastguard Worker typename F::IRet call(const EvalContext &ctx, const typename F::IArg0 &arg0 = Void(),
1510*35238bceSAndroid Build Coastguard Worker const typename F::IArg1 &arg1 = Void(), const typename F::IArg2 &arg2 = Void(),
1511*35238bceSAndroid Build Coastguard Worker const typename F::IArg3 &arg3 = Void())
1512*35238bceSAndroid Build Coastguard Worker {
1513*35238bceSAndroid Build Coastguard Worker return instance<F>().apply(ctx, arg0, arg1, arg2, arg3);
1514*35238bceSAndroid Build Coastguard Worker }
1515*35238bceSAndroid Build Coastguard Worker
1516*35238bceSAndroid Build Coastguard Worker template <typename T>
alternatives(const ExprP<T> & arg0,const ExprP<T> & arg1)1517*35238bceSAndroid Build Coastguard Worker ExprP<T> alternatives(const ExprP<T> &arg0, const ExprP<T> &arg1)
1518*35238bceSAndroid Build Coastguard Worker {
1519*35238bceSAndroid Build Coastguard Worker return createApply<typename Alternatives<T>::Sig>(instance<Alternatives<T>>(), arg0, arg1);
1520*35238bceSAndroid Build Coastguard Worker }
1521*35238bceSAndroid Build Coastguard Worker
1522*35238bceSAndroid Build Coastguard Worker template <typename Sig>
1523*35238bceSAndroid Build Coastguard Worker class ApplyVar : public Apply<Sig>
1524*35238bceSAndroid Build Coastguard Worker {
1525*35238bceSAndroid Build Coastguard Worker public:
1526*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Ret Ret;
1527*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg0 Arg0;
1528*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg1 Arg1;
1529*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg2 Arg2;
1530*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg3 Arg3;
1531*35238bceSAndroid Build Coastguard Worker typedef typename Expr<Ret>::Val Val;
1532*35238bceSAndroid Build Coastguard Worker typedef typename Expr<Ret>::IVal IVal;
1533*35238bceSAndroid Build Coastguard Worker typedef Func<Sig> ApplyFunc;
1534*35238bceSAndroid Build Coastguard Worker typedef typename ApplyFunc::ArgExprs ArgExprs;
1535*35238bceSAndroid Build Coastguard Worker
ApplyVar(const ApplyFunc & func,const VariableP<Arg0> & arg0,const VariableP<Arg1> & arg1,const VariableP<Arg2> & arg2,const VariableP<Arg3> & arg3)1536*35238bceSAndroid Build Coastguard Worker ApplyVar(const ApplyFunc &func, const VariableP<Arg0> &arg0, const VariableP<Arg1> &arg1,
1537*35238bceSAndroid Build Coastguard Worker const VariableP<Arg2> &arg2, const VariableP<Arg3> &arg3)
1538*35238bceSAndroid Build Coastguard Worker : Apply<Sig>(func, arg0, arg1, arg2, arg3)
1539*35238bceSAndroid Build Coastguard Worker {
1540*35238bceSAndroid Build Coastguard Worker }
1541*35238bceSAndroid Build Coastguard Worker
1542*35238bceSAndroid Build Coastguard Worker protected:
doEvaluate(const EvalContext & ctx) const1543*35238bceSAndroid Build Coastguard Worker IVal doEvaluate(const EvalContext &ctx) const
1544*35238bceSAndroid Build Coastguard Worker {
1545*35238bceSAndroid Build Coastguard Worker const Variable<Arg0> &var0 = static_cast<const Variable<Arg0> &>(*this->m_args.a);
1546*35238bceSAndroid Build Coastguard Worker const Variable<Arg1> &var1 = static_cast<const Variable<Arg1> &>(*this->m_args.b);
1547*35238bceSAndroid Build Coastguard Worker const Variable<Arg2> &var2 = static_cast<const Variable<Arg2> &>(*this->m_args.c);
1548*35238bceSAndroid Build Coastguard Worker const Variable<Arg3> &var3 = static_cast<const Variable<Arg3> &>(*this->m_args.d);
1549*35238bceSAndroid Build Coastguard Worker return this->m_func.apply(ctx, ctx.env.lookup(var0), ctx.env.lookup(var1), ctx.env.lookup(var2),
1550*35238bceSAndroid Build Coastguard Worker ctx.env.lookup(var3));
1551*35238bceSAndroid Build Coastguard Worker }
1552*35238bceSAndroid Build Coastguard Worker };
1553*35238bceSAndroid Build Coastguard Worker
1554*35238bceSAndroid Build Coastguard Worker template <typename Sig>
applyVar(const Func<Sig> & func,const VariableP<typename Sig::Arg0> & arg0,const VariableP<typename Sig::Arg1> & arg1,const VariableP<typename Sig::Arg2> & arg2,const VariableP<typename Sig::Arg3> & arg3)1555*35238bceSAndroid Build Coastguard Worker ExprP<typename Sig::Ret> applyVar(const Func<Sig> &func, const VariableP<typename Sig::Arg0> &arg0,
1556*35238bceSAndroid Build Coastguard Worker const VariableP<typename Sig::Arg1> &arg1, const VariableP<typename Sig::Arg2> &arg2,
1557*35238bceSAndroid Build Coastguard Worker const VariableP<typename Sig::Arg3> &arg3)
1558*35238bceSAndroid Build Coastguard Worker {
1559*35238bceSAndroid Build Coastguard Worker return exprP(new ApplyVar<Sig>(func, arg0, arg1, arg2, arg3));
1560*35238bceSAndroid Build Coastguard Worker }
1561*35238bceSAndroid Build Coastguard Worker
1562*35238bceSAndroid Build Coastguard Worker template <typename Sig_>
1563*35238bceSAndroid Build Coastguard Worker class DerivedFunc : public Func<Sig_>
1564*35238bceSAndroid Build Coastguard Worker {
1565*35238bceSAndroid Build Coastguard Worker public:
1566*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::ArgExprs ArgExprs;
1567*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::IRet IRet;
1568*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::IArgs IArgs;
1569*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::Ret Ret;
1570*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::Arg0 Arg0;
1571*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::Arg1 Arg1;
1572*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::Arg2 Arg2;
1573*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::Arg3 Arg3;
1574*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::IArg0 IArg0;
1575*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::IArg1 IArg1;
1576*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::IArg2 IArg2;
1577*35238bceSAndroid Build Coastguard Worker typedef typename DerivedFunc::IArg3 IArg3;
1578*35238bceSAndroid Build Coastguard Worker
1579*35238bceSAndroid Build Coastguard Worker protected:
doPrintDefinition(ostream & os) const1580*35238bceSAndroid Build Coastguard Worker void doPrintDefinition(ostream &os) const
1581*35238bceSAndroid Build Coastguard Worker {
1582*35238bceSAndroid Build Coastguard Worker const ParamNames ¶mNames = this->getParamNames();
1583*35238bceSAndroid Build Coastguard Worker
1584*35238bceSAndroid Build Coastguard Worker initialize();
1585*35238bceSAndroid Build Coastguard Worker
1586*35238bceSAndroid Build Coastguard Worker os << dataTypeNameOf<Ret>() << " " << this->getName() << "(";
1587*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg0>())
1588*35238bceSAndroid Build Coastguard Worker os << dataTypeNameOf<Arg0>() << " " << paramNames.a;
1589*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg1>())
1590*35238bceSAndroid Build Coastguard Worker os << ", " << dataTypeNameOf<Arg1>() << " " << paramNames.b;
1591*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg2>())
1592*35238bceSAndroid Build Coastguard Worker os << ", " << dataTypeNameOf<Arg2>() << " " << paramNames.c;
1593*35238bceSAndroid Build Coastguard Worker if (isTypeValid<Arg3>())
1594*35238bceSAndroid Build Coastguard Worker os << ", " << dataTypeNameOf<Arg3>() << " " << paramNames.d;
1595*35238bceSAndroid Build Coastguard Worker os << ")\n{\n";
1596*35238bceSAndroid Build Coastguard Worker
1597*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < m_body.size(); ++ndx)
1598*35238bceSAndroid Build Coastguard Worker os << *m_body[ndx];
1599*35238bceSAndroid Build Coastguard Worker os << "return " << *m_ret << ";\n";
1600*35238bceSAndroid Build Coastguard Worker os << "}\n";
1601*35238bceSAndroid Build Coastguard Worker }
1602*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext & ctx,const IArgs & args) const1603*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &args) const
1604*35238bceSAndroid Build Coastguard Worker {
1605*35238bceSAndroid Build Coastguard Worker Environment funEnv;
1606*35238bceSAndroid Build Coastguard Worker IArgs &mutArgs = const_cast<IArgs &>(args);
1607*35238bceSAndroid Build Coastguard Worker IRet ret;
1608*35238bceSAndroid Build Coastguard Worker
1609*35238bceSAndroid Build Coastguard Worker initialize();
1610*35238bceSAndroid Build Coastguard Worker
1611*35238bceSAndroid Build Coastguard Worker funEnv.bind(*m_var0, args.a);
1612*35238bceSAndroid Build Coastguard Worker funEnv.bind(*m_var1, args.b);
1613*35238bceSAndroid Build Coastguard Worker funEnv.bind(*m_var2, args.c);
1614*35238bceSAndroid Build Coastguard Worker funEnv.bind(*m_var3, args.d);
1615*35238bceSAndroid Build Coastguard Worker
1616*35238bceSAndroid Build Coastguard Worker {
1617*35238bceSAndroid Build Coastguard Worker EvalContext funCtx(ctx.format, ctx.floatPrecision, funEnv, ctx.callDepth);
1618*35238bceSAndroid Build Coastguard Worker
1619*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < m_body.size(); ++ndx)
1620*35238bceSAndroid Build Coastguard Worker m_body[ndx]->execute(funCtx);
1621*35238bceSAndroid Build Coastguard Worker
1622*35238bceSAndroid Build Coastguard Worker ret = m_ret->evaluate(funCtx);
1623*35238bceSAndroid Build Coastguard Worker }
1624*35238bceSAndroid Build Coastguard Worker
1625*35238bceSAndroid Build Coastguard Worker // \todo [lauri] Store references instead of values in environment
1626*35238bceSAndroid Build Coastguard Worker const_cast<IArg0 &>(mutArgs.a) = funEnv.lookup(*m_var0);
1627*35238bceSAndroid Build Coastguard Worker const_cast<IArg1 &>(mutArgs.b) = funEnv.lookup(*m_var1);
1628*35238bceSAndroid Build Coastguard Worker const_cast<IArg2 &>(mutArgs.c) = funEnv.lookup(*m_var2);
1629*35238bceSAndroid Build Coastguard Worker const_cast<IArg3 &>(mutArgs.d) = funEnv.lookup(*m_var3);
1630*35238bceSAndroid Build Coastguard Worker
1631*35238bceSAndroid Build Coastguard Worker return ret;
1632*35238bceSAndroid Build Coastguard Worker }
1633*35238bceSAndroid Build Coastguard Worker
doGetUsedFuncs(FuncSet & dst) const1634*35238bceSAndroid Build Coastguard Worker void doGetUsedFuncs(FuncSet &dst) const
1635*35238bceSAndroid Build Coastguard Worker {
1636*35238bceSAndroid Build Coastguard Worker initialize();
1637*35238bceSAndroid Build Coastguard Worker if (dst.insert(this).second)
1638*35238bceSAndroid Build Coastguard Worker {
1639*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < m_body.size(); ++ndx)
1640*35238bceSAndroid Build Coastguard Worker m_body[ndx]->getUsedFuncs(dst);
1641*35238bceSAndroid Build Coastguard Worker m_ret->getUsedFuncs(dst);
1642*35238bceSAndroid Build Coastguard Worker }
1643*35238bceSAndroid Build Coastguard Worker }
1644*35238bceSAndroid Build Coastguard Worker
1645*35238bceSAndroid Build Coastguard Worker virtual ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args_) const = 0;
1646*35238bceSAndroid Build Coastguard Worker
1647*35238bceSAndroid Build Coastguard Worker // These are transparently initialized when first needed. They cannot be
1648*35238bceSAndroid Build Coastguard Worker // initialized in the constructor because they depend on the doExpand
1649*35238bceSAndroid Build Coastguard Worker // method of the subclass.
1650*35238bceSAndroid Build Coastguard Worker
1651*35238bceSAndroid Build Coastguard Worker mutable VariableP<Arg0> m_var0;
1652*35238bceSAndroid Build Coastguard Worker mutable VariableP<Arg1> m_var1;
1653*35238bceSAndroid Build Coastguard Worker mutable VariableP<Arg2> m_var2;
1654*35238bceSAndroid Build Coastguard Worker mutable VariableP<Arg3> m_var3;
1655*35238bceSAndroid Build Coastguard Worker mutable vector<StatementP> m_body;
1656*35238bceSAndroid Build Coastguard Worker mutable ExprP<Ret> m_ret;
1657*35238bceSAndroid Build Coastguard Worker
1658*35238bceSAndroid Build Coastguard Worker private:
initialize(void) const1659*35238bceSAndroid Build Coastguard Worker void initialize(void) const
1660*35238bceSAndroid Build Coastguard Worker {
1661*35238bceSAndroid Build Coastguard Worker if (!m_ret)
1662*35238bceSAndroid Build Coastguard Worker {
1663*35238bceSAndroid Build Coastguard Worker const ParamNames ¶mNames = this->getParamNames();
1664*35238bceSAndroid Build Coastguard Worker Counter symCounter;
1665*35238bceSAndroid Build Coastguard Worker ExpandContext ctx(symCounter);
1666*35238bceSAndroid Build Coastguard Worker ArgExprs args;
1667*35238bceSAndroid Build Coastguard Worker
1668*35238bceSAndroid Build Coastguard Worker args.a = m_var0 = variable<Arg0>(paramNames.a);
1669*35238bceSAndroid Build Coastguard Worker args.b = m_var1 = variable<Arg1>(paramNames.b);
1670*35238bceSAndroid Build Coastguard Worker args.c = m_var2 = variable<Arg2>(paramNames.c);
1671*35238bceSAndroid Build Coastguard Worker args.d = m_var3 = variable<Arg3>(paramNames.d);
1672*35238bceSAndroid Build Coastguard Worker
1673*35238bceSAndroid Build Coastguard Worker m_ret = this->doExpand(ctx, args);
1674*35238bceSAndroid Build Coastguard Worker m_body = ctx.getStatements();
1675*35238bceSAndroid Build Coastguard Worker }
1676*35238bceSAndroid Build Coastguard Worker }
1677*35238bceSAndroid Build Coastguard Worker };
1678*35238bceSAndroid Build Coastguard Worker
1679*35238bceSAndroid Build Coastguard Worker template <typename Sig>
1680*35238bceSAndroid Build Coastguard Worker class PrimitiveFunc : public Func<Sig>
1681*35238bceSAndroid Build Coastguard Worker {
1682*35238bceSAndroid Build Coastguard Worker public:
1683*35238bceSAndroid Build Coastguard Worker typedef typename PrimitiveFunc::Ret Ret;
1684*35238bceSAndroid Build Coastguard Worker typedef typename PrimitiveFunc::ArgExprs ArgExprs;
1685*35238bceSAndroid Build Coastguard Worker
1686*35238bceSAndroid Build Coastguard Worker protected:
doPrintDefinition(ostream &) const1687*35238bceSAndroid Build Coastguard Worker void doPrintDefinition(ostream &) const
1688*35238bceSAndroid Build Coastguard Worker {
1689*35238bceSAndroid Build Coastguard Worker }
doGetUsedFuncs(FuncSet &) const1690*35238bceSAndroid Build Coastguard Worker void doGetUsedFuncs(FuncSet &) const
1691*35238bceSAndroid Build Coastguard Worker {
1692*35238bceSAndroid Build Coastguard Worker }
1693*35238bceSAndroid Build Coastguard Worker };
1694*35238bceSAndroid Build Coastguard Worker
1695*35238bceSAndroid Build Coastguard Worker template <typename T>
1696*35238bceSAndroid Build Coastguard Worker class Cond : public PrimitiveFunc<Signature<T, bool, T, T>>
1697*35238bceSAndroid Build Coastguard Worker {
1698*35238bceSAndroid Build Coastguard Worker public:
1699*35238bceSAndroid Build Coastguard Worker typedef typename Cond::IArgs IArgs;
1700*35238bceSAndroid Build Coastguard Worker typedef typename Cond::IRet IRet;
1701*35238bceSAndroid Build Coastguard Worker
getName(void) const1702*35238bceSAndroid Build Coastguard Worker string getName(void) const
1703*35238bceSAndroid Build Coastguard Worker {
1704*35238bceSAndroid Build Coastguard Worker return "_cond";
1705*35238bceSAndroid Build Coastguard Worker }
1706*35238bceSAndroid Build Coastguard Worker
1707*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os,const BaseArgExprs & args) const1708*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
1709*35238bceSAndroid Build Coastguard Worker {
1710*35238bceSAndroid Build Coastguard Worker os << "(" << *args[0] << " ? " << *args[1] << " : " << *args[2] << ")";
1711*35238bceSAndroid Build Coastguard Worker }
1712*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext &,const IArgs & iargs) const1713*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
1714*35238bceSAndroid Build Coastguard Worker {
1715*35238bceSAndroid Build Coastguard Worker IRet ret;
1716*35238bceSAndroid Build Coastguard Worker
1717*35238bceSAndroid Build Coastguard Worker if (iargs.a.contains(true))
1718*35238bceSAndroid Build Coastguard Worker ret = unionIVal<T>(ret, iargs.b);
1719*35238bceSAndroid Build Coastguard Worker
1720*35238bceSAndroid Build Coastguard Worker if (iargs.a.contains(false))
1721*35238bceSAndroid Build Coastguard Worker ret = unionIVal<T>(ret, iargs.c);
1722*35238bceSAndroid Build Coastguard Worker
1723*35238bceSAndroid Build Coastguard Worker return ret;
1724*35238bceSAndroid Build Coastguard Worker }
1725*35238bceSAndroid Build Coastguard Worker };
1726*35238bceSAndroid Build Coastguard Worker
1727*35238bceSAndroid Build Coastguard Worker template <typename T>
1728*35238bceSAndroid Build Coastguard Worker class CompareOperator : public PrimitiveFunc<Signature<bool, T, T>>
1729*35238bceSAndroid Build Coastguard Worker {
1730*35238bceSAndroid Build Coastguard Worker public:
1731*35238bceSAndroid Build Coastguard Worker typedef typename CompareOperator::IArgs IArgs;
1732*35238bceSAndroid Build Coastguard Worker typedef typename CompareOperator::IArg0 IArg0;
1733*35238bceSAndroid Build Coastguard Worker typedef typename CompareOperator::IArg1 IArg1;
1734*35238bceSAndroid Build Coastguard Worker typedef typename CompareOperator::IRet IRet;
1735*35238bceSAndroid Build Coastguard Worker
1736*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os,const BaseArgExprs & args) const1737*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
1738*35238bceSAndroid Build Coastguard Worker {
1739*35238bceSAndroid Build Coastguard Worker os << "(" << *args[0] << getSymbol() << *args[1] << ")";
1740*35238bceSAndroid Build Coastguard Worker }
1741*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext &,const IArgs & iargs) const1742*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &, const IArgs &iargs) const
1743*35238bceSAndroid Build Coastguard Worker {
1744*35238bceSAndroid Build Coastguard Worker const IArg0 &arg0 = iargs.a;
1745*35238bceSAndroid Build Coastguard Worker const IArg1 &arg1 = iargs.b;
1746*35238bceSAndroid Build Coastguard Worker IRet ret;
1747*35238bceSAndroid Build Coastguard Worker
1748*35238bceSAndroid Build Coastguard Worker if (canSucceed(arg0, arg1))
1749*35238bceSAndroid Build Coastguard Worker ret |= true;
1750*35238bceSAndroid Build Coastguard Worker if (canFail(arg0, arg1))
1751*35238bceSAndroid Build Coastguard Worker ret |= false;
1752*35238bceSAndroid Build Coastguard Worker
1753*35238bceSAndroid Build Coastguard Worker return ret;
1754*35238bceSAndroid Build Coastguard Worker }
1755*35238bceSAndroid Build Coastguard Worker
1756*35238bceSAndroid Build Coastguard Worker virtual string getSymbol(void) const = 0;
1757*35238bceSAndroid Build Coastguard Worker virtual bool canSucceed(const IArg0 &, const IArg1 &) const = 0;
1758*35238bceSAndroid Build Coastguard Worker virtual bool canFail(const IArg0 &, const IArg1 &) const = 0;
1759*35238bceSAndroid Build Coastguard Worker };
1760*35238bceSAndroid Build Coastguard Worker
1761*35238bceSAndroid Build Coastguard Worker template <typename T>
1762*35238bceSAndroid Build Coastguard Worker class LessThan : public CompareOperator<T>
1763*35238bceSAndroid Build Coastguard Worker {
1764*35238bceSAndroid Build Coastguard Worker public:
getName(void) const1765*35238bceSAndroid Build Coastguard Worker string getName(void) const
1766*35238bceSAndroid Build Coastguard Worker {
1767*35238bceSAndroid Build Coastguard Worker return "lessThan";
1768*35238bceSAndroid Build Coastguard Worker }
1769*35238bceSAndroid Build Coastguard Worker
1770*35238bceSAndroid Build Coastguard Worker protected:
getSymbol(void) const1771*35238bceSAndroid Build Coastguard Worker string getSymbol(void) const
1772*35238bceSAndroid Build Coastguard Worker {
1773*35238bceSAndroid Build Coastguard Worker return "<";
1774*35238bceSAndroid Build Coastguard Worker }
1775*35238bceSAndroid Build Coastguard Worker
canSucceed(const Interval & a,const Interval & b) const1776*35238bceSAndroid Build Coastguard Worker bool canSucceed(const Interval &a, const Interval &b) const
1777*35238bceSAndroid Build Coastguard Worker {
1778*35238bceSAndroid Build Coastguard Worker return (a.lo() < b.hi());
1779*35238bceSAndroid Build Coastguard Worker }
1780*35238bceSAndroid Build Coastguard Worker
canFail(const Interval & a,const Interval & b) const1781*35238bceSAndroid Build Coastguard Worker bool canFail(const Interval &a, const Interval &b) const
1782*35238bceSAndroid Build Coastguard Worker {
1783*35238bceSAndroid Build Coastguard Worker return !(a.hi() < b.lo());
1784*35238bceSAndroid Build Coastguard Worker }
1785*35238bceSAndroid Build Coastguard Worker };
1786*35238bceSAndroid Build Coastguard Worker
1787*35238bceSAndroid Build Coastguard Worker template <typename T>
operator <(const ExprP<T> & a,const ExprP<T> & b)1788*35238bceSAndroid Build Coastguard Worker ExprP<bool> operator<(const ExprP<T> &a, const ExprP<T> &b)
1789*35238bceSAndroid Build Coastguard Worker {
1790*35238bceSAndroid Build Coastguard Worker return app<LessThan<T>>(a, b);
1791*35238bceSAndroid Build Coastguard Worker }
1792*35238bceSAndroid Build Coastguard Worker
1793*35238bceSAndroid Build Coastguard Worker template <typename T>
cond(const ExprP<bool> & test,const ExprP<T> & consequent,const ExprP<T> & alternative)1794*35238bceSAndroid Build Coastguard Worker ExprP<T> cond(const ExprP<bool> &test, const ExprP<T> &consequent, const ExprP<T> &alternative)
1795*35238bceSAndroid Build Coastguard Worker {
1796*35238bceSAndroid Build Coastguard Worker return app<Cond<T>>(test, consequent, alternative);
1797*35238bceSAndroid Build Coastguard Worker }
1798*35238bceSAndroid Build Coastguard Worker
1799*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1800*35238bceSAndroid Build Coastguard Worker *
1801*35238bceSAndroid Build Coastguard Worker * @}
1802*35238bceSAndroid Build Coastguard Worker *
1803*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
1804*35238bceSAndroid Build Coastguard Worker
1805*35238bceSAndroid Build Coastguard Worker class FloatFunc1 : public PrimitiveFunc<Signature<float, float>>
1806*35238bceSAndroid Build Coastguard Worker {
1807*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const1808*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &ctx, const IArgs &iargs) const
1809*35238bceSAndroid Build Coastguard Worker {
1810*35238bceSAndroid Build Coastguard Worker return this->applyMonotone(ctx, iargs.a);
1811*35238bceSAndroid Build Coastguard Worker }
1812*35238bceSAndroid Build Coastguard Worker
applyMonotone(const EvalContext & ctx,const Interval & iarg0) const1813*35238bceSAndroid Build Coastguard Worker Interval applyMonotone(const EvalContext &ctx, const Interval &iarg0) const
1814*35238bceSAndroid Build Coastguard Worker {
1815*35238bceSAndroid Build Coastguard Worker Interval ret;
1816*35238bceSAndroid Build Coastguard Worker
1817*35238bceSAndroid Build Coastguard Worker TCU_INTERVAL_APPLY_MONOTONE1(ret, arg0, iarg0, val,
1818*35238bceSAndroid Build Coastguard Worker TCU_SET_INTERVAL(val, point, point = this->applyPoint(ctx, arg0)));
1819*35238bceSAndroid Build Coastguard Worker
1820*35238bceSAndroid Build Coastguard Worker ret |= innerExtrema(ctx, iarg0);
1821*35238bceSAndroid Build Coastguard Worker ret &= (this->getCodomain() | TCU_NAN);
1822*35238bceSAndroid Build Coastguard Worker
1823*35238bceSAndroid Build Coastguard Worker return ctx.format.convert(ret);
1824*35238bceSAndroid Build Coastguard Worker }
1825*35238bceSAndroid Build Coastguard Worker
innerExtrema(const EvalContext &,const Interval &) const1826*35238bceSAndroid Build Coastguard Worker virtual Interval innerExtrema(const EvalContext &, const Interval &) const
1827*35238bceSAndroid Build Coastguard Worker {
1828*35238bceSAndroid Build Coastguard Worker return Interval(); // empty interval, i.e. no extrema
1829*35238bceSAndroid Build Coastguard Worker }
1830*35238bceSAndroid Build Coastguard Worker
applyPoint(const EvalContext & ctx,double arg0) const1831*35238bceSAndroid Build Coastguard Worker virtual Interval applyPoint(const EvalContext &ctx, double arg0) const
1832*35238bceSAndroid Build Coastguard Worker {
1833*35238bceSAndroid Build Coastguard Worker const double exact = this->applyExact(arg0);
1834*35238bceSAndroid Build Coastguard Worker const double prec = this->precision(ctx, exact, arg0);
1835*35238bceSAndroid Build Coastguard Worker const double wprec = this->warningPrecision(ctx, exact, arg0);
1836*35238bceSAndroid Build Coastguard Worker Interval ioutput = exact + Interval(-prec, prec);
1837*35238bceSAndroid Build Coastguard Worker ioutput.warning(exact - wprec, exact + wprec);
1838*35238bceSAndroid Build Coastguard Worker return ioutput;
1839*35238bceSAndroid Build Coastguard Worker }
1840*35238bceSAndroid Build Coastguard Worker
applyExact(double) const1841*35238bceSAndroid Build Coastguard Worker virtual double applyExact(double) const
1842*35238bceSAndroid Build Coastguard Worker {
1843*35238bceSAndroid Build Coastguard Worker TCU_THROW(InternalError, "Cannot apply");
1844*35238bceSAndroid Build Coastguard Worker }
1845*35238bceSAndroid Build Coastguard Worker
getCodomain(void) const1846*35238bceSAndroid Build Coastguard Worker virtual Interval getCodomain(void) const
1847*35238bceSAndroid Build Coastguard Worker {
1848*35238bceSAndroid Build Coastguard Worker return Interval::unbounded(true);
1849*35238bceSAndroid Build Coastguard Worker }
1850*35238bceSAndroid Build Coastguard Worker
1851*35238bceSAndroid Build Coastguard Worker virtual double precision(const EvalContext &ctx, double, double) const = 0;
1852*35238bceSAndroid Build Coastguard Worker
warningPrecision(const EvalContext & ctx,double exact,double arg0) const1853*35238bceSAndroid Build Coastguard Worker virtual double warningPrecision(const EvalContext &ctx, double exact, double arg0) const
1854*35238bceSAndroid Build Coastguard Worker {
1855*35238bceSAndroid Build Coastguard Worker return precision(ctx, exact, arg0);
1856*35238bceSAndroid Build Coastguard Worker }
1857*35238bceSAndroid Build Coastguard Worker };
1858*35238bceSAndroid Build Coastguard Worker
1859*35238bceSAndroid Build Coastguard Worker class CFloatFunc1 : public FloatFunc1
1860*35238bceSAndroid Build Coastguard Worker {
1861*35238bceSAndroid Build Coastguard Worker public:
CFloatFunc1(const string & name,DoubleFunc1 & func)1862*35238bceSAndroid Build Coastguard Worker CFloatFunc1(const string &name, DoubleFunc1 &func) : m_name(name), m_func(func)
1863*35238bceSAndroid Build Coastguard Worker {
1864*35238bceSAndroid Build Coastguard Worker }
1865*35238bceSAndroid Build Coastguard Worker
getName(void) const1866*35238bceSAndroid Build Coastguard Worker string getName(void) const
1867*35238bceSAndroid Build Coastguard Worker {
1868*35238bceSAndroid Build Coastguard Worker return m_name;
1869*35238bceSAndroid Build Coastguard Worker }
1870*35238bceSAndroid Build Coastguard Worker
1871*35238bceSAndroid Build Coastguard Worker protected:
applyExact(double x) const1872*35238bceSAndroid Build Coastguard Worker double applyExact(double x) const
1873*35238bceSAndroid Build Coastguard Worker {
1874*35238bceSAndroid Build Coastguard Worker return m_func(x);
1875*35238bceSAndroid Build Coastguard Worker }
1876*35238bceSAndroid Build Coastguard Worker
1877*35238bceSAndroid Build Coastguard Worker const string m_name;
1878*35238bceSAndroid Build Coastguard Worker DoubleFunc1 &m_func;
1879*35238bceSAndroid Build Coastguard Worker };
1880*35238bceSAndroid Build Coastguard Worker
1881*35238bceSAndroid Build Coastguard Worker class FloatFunc2 : public PrimitiveFunc<Signature<float, float, float>>
1882*35238bceSAndroid Build Coastguard Worker {
1883*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const1884*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &ctx, const IArgs &iargs) const
1885*35238bceSAndroid Build Coastguard Worker {
1886*35238bceSAndroid Build Coastguard Worker return this->applyMonotone(ctx, iargs.a, iargs.b);
1887*35238bceSAndroid Build Coastguard Worker }
1888*35238bceSAndroid Build Coastguard Worker
applyMonotone(const EvalContext & ctx,const Interval & xi,const Interval & yi) const1889*35238bceSAndroid Build Coastguard Worker Interval applyMonotone(const EvalContext &ctx, const Interval &xi, const Interval &yi) const
1890*35238bceSAndroid Build Coastguard Worker {
1891*35238bceSAndroid Build Coastguard Worker Interval reti;
1892*35238bceSAndroid Build Coastguard Worker
1893*35238bceSAndroid Build Coastguard Worker TCU_INTERVAL_APPLY_MONOTONE2(reti, x, xi, y, yi, ret,
1894*35238bceSAndroid Build Coastguard Worker TCU_SET_INTERVAL(ret, point, point = this->applyPoint(ctx, x, y)));
1895*35238bceSAndroid Build Coastguard Worker reti |= innerExtrema(ctx, xi, yi);
1896*35238bceSAndroid Build Coastguard Worker reti &= (this->getCodomain() | TCU_NAN);
1897*35238bceSAndroid Build Coastguard Worker
1898*35238bceSAndroid Build Coastguard Worker return ctx.format.convert(reti);
1899*35238bceSAndroid Build Coastguard Worker }
1900*35238bceSAndroid Build Coastguard Worker
innerExtrema(const EvalContext &,const Interval &,const Interval &) const1901*35238bceSAndroid Build Coastguard Worker virtual Interval innerExtrema(const EvalContext &, const Interval &, const Interval &) const
1902*35238bceSAndroid Build Coastguard Worker {
1903*35238bceSAndroid Build Coastguard Worker return Interval(); // empty interval, i.e. no extrema
1904*35238bceSAndroid Build Coastguard Worker }
1905*35238bceSAndroid Build Coastguard Worker
applyPoint(const EvalContext & ctx,double x,double y) const1906*35238bceSAndroid Build Coastguard Worker virtual Interval applyPoint(const EvalContext &ctx, double x, double y) const
1907*35238bceSAndroid Build Coastguard Worker {
1908*35238bceSAndroid Build Coastguard Worker const double exact = this->applyExact(x, y);
1909*35238bceSAndroid Build Coastguard Worker const double prec = this->precision(ctx, exact, x, y);
1910*35238bceSAndroid Build Coastguard Worker
1911*35238bceSAndroid Build Coastguard Worker return exact + Interval(-prec, prec);
1912*35238bceSAndroid Build Coastguard Worker }
1913*35238bceSAndroid Build Coastguard Worker
applyExact(double,double) const1914*35238bceSAndroid Build Coastguard Worker virtual double applyExact(double, double) const
1915*35238bceSAndroid Build Coastguard Worker {
1916*35238bceSAndroid Build Coastguard Worker TCU_THROW(InternalError, "Cannot apply");
1917*35238bceSAndroid Build Coastguard Worker }
1918*35238bceSAndroid Build Coastguard Worker
getCodomain(void) const1919*35238bceSAndroid Build Coastguard Worker virtual Interval getCodomain(void) const
1920*35238bceSAndroid Build Coastguard Worker {
1921*35238bceSAndroid Build Coastguard Worker return Interval::unbounded(true);
1922*35238bceSAndroid Build Coastguard Worker }
1923*35238bceSAndroid Build Coastguard Worker
1924*35238bceSAndroid Build Coastguard Worker virtual double precision(const EvalContext &ctx, double ret, double x, double y) const = 0;
1925*35238bceSAndroid Build Coastguard Worker };
1926*35238bceSAndroid Build Coastguard Worker
1927*35238bceSAndroid Build Coastguard Worker class CFloatFunc2 : public FloatFunc2
1928*35238bceSAndroid Build Coastguard Worker {
1929*35238bceSAndroid Build Coastguard Worker public:
CFloatFunc2(const string & name,DoubleFunc2 & func)1930*35238bceSAndroid Build Coastguard Worker CFloatFunc2(const string &name, DoubleFunc2 &func) : m_name(name), m_func(func)
1931*35238bceSAndroid Build Coastguard Worker {
1932*35238bceSAndroid Build Coastguard Worker }
1933*35238bceSAndroid Build Coastguard Worker
getName(void) const1934*35238bceSAndroid Build Coastguard Worker string getName(void) const
1935*35238bceSAndroid Build Coastguard Worker {
1936*35238bceSAndroid Build Coastguard Worker return m_name;
1937*35238bceSAndroid Build Coastguard Worker }
1938*35238bceSAndroid Build Coastguard Worker
1939*35238bceSAndroid Build Coastguard Worker protected:
applyExact(double x,double y) const1940*35238bceSAndroid Build Coastguard Worker double applyExact(double x, double y) const
1941*35238bceSAndroid Build Coastguard Worker {
1942*35238bceSAndroid Build Coastguard Worker return m_func(x, y);
1943*35238bceSAndroid Build Coastguard Worker }
1944*35238bceSAndroid Build Coastguard Worker
1945*35238bceSAndroid Build Coastguard Worker const string m_name;
1946*35238bceSAndroid Build Coastguard Worker DoubleFunc2 &m_func;
1947*35238bceSAndroid Build Coastguard Worker };
1948*35238bceSAndroid Build Coastguard Worker
1949*35238bceSAndroid Build Coastguard Worker class InfixOperator : public FloatFunc2
1950*35238bceSAndroid Build Coastguard Worker {
1951*35238bceSAndroid Build Coastguard Worker protected:
1952*35238bceSAndroid Build Coastguard Worker virtual string getSymbol(void) const = 0;
1953*35238bceSAndroid Build Coastguard Worker
doPrint(ostream & os,const BaseArgExprs & args) const1954*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
1955*35238bceSAndroid Build Coastguard Worker {
1956*35238bceSAndroid Build Coastguard Worker os << "(" << *args[0] << " " << getSymbol() << " " << *args[1] << ")";
1957*35238bceSAndroid Build Coastguard Worker }
1958*35238bceSAndroid Build Coastguard Worker
applyPoint(const EvalContext & ctx,double x,double y) const1959*35238bceSAndroid Build Coastguard Worker Interval applyPoint(const EvalContext &ctx, double x, double y) const
1960*35238bceSAndroid Build Coastguard Worker {
1961*35238bceSAndroid Build Coastguard Worker const double exact = this->applyExact(x, y);
1962*35238bceSAndroid Build Coastguard Worker
1963*35238bceSAndroid Build Coastguard Worker // Allow either representable number on both sides of the exact value,
1964*35238bceSAndroid Build Coastguard Worker // but require exactly representable values to be preserved.
1965*35238bceSAndroid Build Coastguard Worker return ctx.format.roundOut(exact, !deIsInf(x) && !deIsInf(y));
1966*35238bceSAndroid Build Coastguard Worker }
1967*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext &,double,double,double) const1968*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &, double, double, double) const
1969*35238bceSAndroid Build Coastguard Worker {
1970*35238bceSAndroid Build Coastguard Worker return 0.0;
1971*35238bceSAndroid Build Coastguard Worker }
1972*35238bceSAndroid Build Coastguard Worker };
1973*35238bceSAndroid Build Coastguard Worker
1974*35238bceSAndroid Build Coastguard Worker class FloatFunc3 : public PrimitiveFunc<Signature<float, float, float, float>>
1975*35238bceSAndroid Build Coastguard Worker {
1976*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const1977*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &ctx, const IArgs &iargs) const
1978*35238bceSAndroid Build Coastguard Worker {
1979*35238bceSAndroid Build Coastguard Worker return this->applyMonotone(ctx, iargs.a, iargs.b, iargs.c);
1980*35238bceSAndroid Build Coastguard Worker }
1981*35238bceSAndroid Build Coastguard Worker
applyMonotone(const EvalContext & ctx,const Interval & xi,const Interval & yi,const Interval & zi) const1982*35238bceSAndroid Build Coastguard Worker Interval applyMonotone(const EvalContext &ctx, const Interval &xi, const Interval &yi, const Interval &zi) const
1983*35238bceSAndroid Build Coastguard Worker {
1984*35238bceSAndroid Build Coastguard Worker Interval reti;
1985*35238bceSAndroid Build Coastguard Worker TCU_INTERVAL_APPLY_MONOTONE3(reti, x, xi, y, yi, z, zi, ret,
1986*35238bceSAndroid Build Coastguard Worker TCU_SET_INTERVAL(ret, point, point = this->applyPoint(ctx, x, y, z)));
1987*35238bceSAndroid Build Coastguard Worker return ctx.format.convert(reti);
1988*35238bceSAndroid Build Coastguard Worker }
1989*35238bceSAndroid Build Coastguard Worker
applyPoint(const EvalContext & ctx,double x,double y,double z) const1990*35238bceSAndroid Build Coastguard Worker virtual Interval applyPoint(const EvalContext &ctx, double x, double y, double z) const
1991*35238bceSAndroid Build Coastguard Worker {
1992*35238bceSAndroid Build Coastguard Worker const double exact = this->applyExact(x, y, z);
1993*35238bceSAndroid Build Coastguard Worker const double prec = this->precision(ctx, exact, x, y, z);
1994*35238bceSAndroid Build Coastguard Worker return exact + Interval(-prec, prec);
1995*35238bceSAndroid Build Coastguard Worker }
1996*35238bceSAndroid Build Coastguard Worker
applyExact(double,double,double) const1997*35238bceSAndroid Build Coastguard Worker virtual double applyExact(double, double, double) const
1998*35238bceSAndroid Build Coastguard Worker {
1999*35238bceSAndroid Build Coastguard Worker TCU_THROW(InternalError, "Cannot apply");
2000*35238bceSAndroid Build Coastguard Worker }
2001*35238bceSAndroid Build Coastguard Worker
2002*35238bceSAndroid Build Coastguard Worker virtual double precision(const EvalContext &ctx, double result, double x, double y, double z) const = 0;
2003*35238bceSAndroid Build Coastguard Worker };
2004*35238bceSAndroid Build Coastguard Worker
2005*35238bceSAndroid Build Coastguard Worker // We define syntactic sugar functions for expression constructors. Since
2006*35238bceSAndroid Build Coastguard Worker // these have the same names as ordinary mathematical operations (sin, log
2007*35238bceSAndroid Build Coastguard Worker // etc.), it's better to give them a dedicated namespace.
2008*35238bceSAndroid Build Coastguard Worker namespace Functions
2009*35238bceSAndroid Build Coastguard Worker {
2010*35238bceSAndroid Build Coastguard Worker
2011*35238bceSAndroid Build Coastguard Worker using namespace tcu;
2012*35238bceSAndroid Build Coastguard Worker
2013*35238bceSAndroid Build Coastguard Worker class Add : public InfixOperator
2014*35238bceSAndroid Build Coastguard Worker {
2015*35238bceSAndroid Build Coastguard Worker public:
getName(void) const2016*35238bceSAndroid Build Coastguard Worker string getName(void) const
2017*35238bceSAndroid Build Coastguard Worker {
2018*35238bceSAndroid Build Coastguard Worker return "add";
2019*35238bceSAndroid Build Coastguard Worker }
getSymbol(void) const2020*35238bceSAndroid Build Coastguard Worker string getSymbol(void) const
2021*35238bceSAndroid Build Coastguard Worker {
2022*35238bceSAndroid Build Coastguard Worker return "+";
2023*35238bceSAndroid Build Coastguard Worker }
2024*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext & ctx,const IArgs & iargs) const2025*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &ctx, const IArgs &iargs) const
2026*35238bceSAndroid Build Coastguard Worker {
2027*35238bceSAndroid Build Coastguard Worker // Fast-path for common case
2028*35238bceSAndroid Build Coastguard Worker if (iargs.a.isOrdinary(ctx.format.getMaxValue()) && iargs.b.isOrdinary(ctx.format.getMaxValue()))
2029*35238bceSAndroid Build Coastguard Worker {
2030*35238bceSAndroid Build Coastguard Worker Interval ret;
2031*35238bceSAndroid Build Coastguard Worker TCU_SET_INTERVAL_BOUNDS(ret, sum, sum = iargs.a.lo() + iargs.b.lo(), sum = iargs.a.hi() + iargs.b.hi());
2032*35238bceSAndroid Build Coastguard Worker return ctx.format.convert(ctx.format.roundOut(ret, true));
2033*35238bceSAndroid Build Coastguard Worker }
2034*35238bceSAndroid Build Coastguard Worker return this->applyMonotone(ctx, iargs.a, iargs.b);
2035*35238bceSAndroid Build Coastguard Worker }
2036*35238bceSAndroid Build Coastguard Worker
2037*35238bceSAndroid Build Coastguard Worker protected:
applyExact(double x,double y) const2038*35238bceSAndroid Build Coastguard Worker double applyExact(double x, double y) const
2039*35238bceSAndroid Build Coastguard Worker {
2040*35238bceSAndroid Build Coastguard Worker return x + y;
2041*35238bceSAndroid Build Coastguard Worker }
2042*35238bceSAndroid Build Coastguard Worker };
2043*35238bceSAndroid Build Coastguard Worker
2044*35238bceSAndroid Build Coastguard Worker class Mul : public InfixOperator
2045*35238bceSAndroid Build Coastguard Worker {
2046*35238bceSAndroid Build Coastguard Worker public:
getName(void) const2047*35238bceSAndroid Build Coastguard Worker string getName(void) const
2048*35238bceSAndroid Build Coastguard Worker {
2049*35238bceSAndroid Build Coastguard Worker return "mul";
2050*35238bceSAndroid Build Coastguard Worker }
getSymbol(void) const2051*35238bceSAndroid Build Coastguard Worker string getSymbol(void) const
2052*35238bceSAndroid Build Coastguard Worker {
2053*35238bceSAndroid Build Coastguard Worker return "*";
2054*35238bceSAndroid Build Coastguard Worker }
2055*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext & ctx,const IArgs & iargs) const2056*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &ctx, const IArgs &iargs) const
2057*35238bceSAndroid Build Coastguard Worker {
2058*35238bceSAndroid Build Coastguard Worker Interval a = iargs.a;
2059*35238bceSAndroid Build Coastguard Worker Interval b = iargs.b;
2060*35238bceSAndroid Build Coastguard Worker
2061*35238bceSAndroid Build Coastguard Worker // Fast-path for common case
2062*35238bceSAndroid Build Coastguard Worker if (a.isOrdinary(ctx.format.getMaxValue()) && b.isOrdinary(ctx.format.getMaxValue()))
2063*35238bceSAndroid Build Coastguard Worker {
2064*35238bceSAndroid Build Coastguard Worker Interval ret;
2065*35238bceSAndroid Build Coastguard Worker if (a.hi() < 0)
2066*35238bceSAndroid Build Coastguard Worker {
2067*35238bceSAndroid Build Coastguard Worker a = -a;
2068*35238bceSAndroid Build Coastguard Worker b = -b;
2069*35238bceSAndroid Build Coastguard Worker }
2070*35238bceSAndroid Build Coastguard Worker if (a.lo() >= 0 && b.lo() >= 0)
2071*35238bceSAndroid Build Coastguard Worker {
2072*35238bceSAndroid Build Coastguard Worker TCU_SET_INTERVAL_BOUNDS(ret, prod, prod = iargs.a.lo() * iargs.b.lo(),
2073*35238bceSAndroid Build Coastguard Worker prod = iargs.a.hi() * iargs.b.hi());
2074*35238bceSAndroid Build Coastguard Worker return ctx.format.convert(ctx.format.roundOut(ret, true));
2075*35238bceSAndroid Build Coastguard Worker }
2076*35238bceSAndroid Build Coastguard Worker if (a.lo() >= 0 && b.hi() <= 0)
2077*35238bceSAndroid Build Coastguard Worker {
2078*35238bceSAndroid Build Coastguard Worker TCU_SET_INTERVAL_BOUNDS(ret, prod, prod = iargs.a.hi() * iargs.b.lo(),
2079*35238bceSAndroid Build Coastguard Worker prod = iargs.a.lo() * iargs.b.hi());
2080*35238bceSAndroid Build Coastguard Worker return ctx.format.convert(ctx.format.roundOut(ret, true));
2081*35238bceSAndroid Build Coastguard Worker }
2082*35238bceSAndroid Build Coastguard Worker }
2083*35238bceSAndroid Build Coastguard Worker return this->applyMonotone(ctx, iargs.a, iargs.b);
2084*35238bceSAndroid Build Coastguard Worker }
2085*35238bceSAndroid Build Coastguard Worker
2086*35238bceSAndroid Build Coastguard Worker protected:
applyExact(double x,double y) const2087*35238bceSAndroid Build Coastguard Worker double applyExact(double x, double y) const
2088*35238bceSAndroid Build Coastguard Worker {
2089*35238bceSAndroid Build Coastguard Worker return x * y;
2090*35238bceSAndroid Build Coastguard Worker }
2091*35238bceSAndroid Build Coastguard Worker
innerExtrema(const EvalContext &,const Interval & xi,const Interval & yi) const2092*35238bceSAndroid Build Coastguard Worker Interval innerExtrema(const EvalContext &, const Interval &xi, const Interval &yi) const
2093*35238bceSAndroid Build Coastguard Worker {
2094*35238bceSAndroid Build Coastguard Worker if (((xi.contains(-TCU_INFINITY) || xi.contains(TCU_INFINITY)) && yi.contains(0.0)) ||
2095*35238bceSAndroid Build Coastguard Worker ((yi.contains(-TCU_INFINITY) || yi.contains(TCU_INFINITY)) && xi.contains(0.0)))
2096*35238bceSAndroid Build Coastguard Worker return Interval(TCU_NAN);
2097*35238bceSAndroid Build Coastguard Worker
2098*35238bceSAndroid Build Coastguard Worker return Interval();
2099*35238bceSAndroid Build Coastguard Worker }
2100*35238bceSAndroid Build Coastguard Worker };
2101*35238bceSAndroid Build Coastguard Worker
2102*35238bceSAndroid Build Coastguard Worker class Sub : public InfixOperator
2103*35238bceSAndroid Build Coastguard Worker {
2104*35238bceSAndroid Build Coastguard Worker public:
getName(void) const2105*35238bceSAndroid Build Coastguard Worker string getName(void) const
2106*35238bceSAndroid Build Coastguard Worker {
2107*35238bceSAndroid Build Coastguard Worker return "sub";
2108*35238bceSAndroid Build Coastguard Worker }
getSymbol(void) const2109*35238bceSAndroid Build Coastguard Worker string getSymbol(void) const
2110*35238bceSAndroid Build Coastguard Worker {
2111*35238bceSAndroid Build Coastguard Worker return "-";
2112*35238bceSAndroid Build Coastguard Worker }
2113*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext & ctx,const IArgs & iargs) const2114*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &ctx, const IArgs &iargs) const
2115*35238bceSAndroid Build Coastguard Worker {
2116*35238bceSAndroid Build Coastguard Worker // Fast-path for common case
2117*35238bceSAndroid Build Coastguard Worker if (iargs.a.isOrdinary(ctx.format.getMaxValue()) && iargs.b.isOrdinary(ctx.format.getMaxValue()))
2118*35238bceSAndroid Build Coastguard Worker {
2119*35238bceSAndroid Build Coastguard Worker Interval ret;
2120*35238bceSAndroid Build Coastguard Worker
2121*35238bceSAndroid Build Coastguard Worker TCU_SET_INTERVAL_BOUNDS(ret, diff, diff = iargs.a.lo() - iargs.b.hi(), diff = iargs.a.hi() - iargs.b.lo());
2122*35238bceSAndroid Build Coastguard Worker return ctx.format.convert(ctx.format.roundOut(ret, true));
2123*35238bceSAndroid Build Coastguard Worker }
2124*35238bceSAndroid Build Coastguard Worker else
2125*35238bceSAndroid Build Coastguard Worker {
2126*35238bceSAndroid Build Coastguard Worker return this->applyMonotone(ctx, iargs.a, iargs.b);
2127*35238bceSAndroid Build Coastguard Worker }
2128*35238bceSAndroid Build Coastguard Worker }
2129*35238bceSAndroid Build Coastguard Worker
2130*35238bceSAndroid Build Coastguard Worker protected:
applyExact(double x,double y) const2131*35238bceSAndroid Build Coastguard Worker double applyExact(double x, double y) const
2132*35238bceSAndroid Build Coastguard Worker {
2133*35238bceSAndroid Build Coastguard Worker return x - y;
2134*35238bceSAndroid Build Coastguard Worker }
2135*35238bceSAndroid Build Coastguard Worker };
2136*35238bceSAndroid Build Coastguard Worker
2137*35238bceSAndroid Build Coastguard Worker class Negate : public FloatFunc1
2138*35238bceSAndroid Build Coastguard Worker {
2139*35238bceSAndroid Build Coastguard Worker public:
getName(void) const2140*35238bceSAndroid Build Coastguard Worker string getName(void) const
2141*35238bceSAndroid Build Coastguard Worker {
2142*35238bceSAndroid Build Coastguard Worker return "_negate";
2143*35238bceSAndroid Build Coastguard Worker }
doPrint(ostream & os,const BaseArgExprs & args) const2144*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
2145*35238bceSAndroid Build Coastguard Worker {
2146*35238bceSAndroid Build Coastguard Worker os << "-" << *args[0];
2147*35238bceSAndroid Build Coastguard Worker }
2148*35238bceSAndroid Build Coastguard Worker
2149*35238bceSAndroid Build Coastguard Worker protected:
precision(const EvalContext &,double,double) const2150*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &, double, double) const
2151*35238bceSAndroid Build Coastguard Worker {
2152*35238bceSAndroid Build Coastguard Worker return 0.0;
2153*35238bceSAndroid Build Coastguard Worker }
applyExact(double x) const2154*35238bceSAndroid Build Coastguard Worker double applyExact(double x) const
2155*35238bceSAndroid Build Coastguard Worker {
2156*35238bceSAndroid Build Coastguard Worker return -x;
2157*35238bceSAndroid Build Coastguard Worker }
2158*35238bceSAndroid Build Coastguard Worker };
2159*35238bceSAndroid Build Coastguard Worker
2160*35238bceSAndroid Build Coastguard Worker class Div : public InfixOperator
2161*35238bceSAndroid Build Coastguard Worker {
2162*35238bceSAndroid Build Coastguard Worker public:
getName(void) const2163*35238bceSAndroid Build Coastguard Worker string getName(void) const
2164*35238bceSAndroid Build Coastguard Worker {
2165*35238bceSAndroid Build Coastguard Worker return "div";
2166*35238bceSAndroid Build Coastguard Worker }
2167*35238bceSAndroid Build Coastguard Worker
2168*35238bceSAndroid Build Coastguard Worker protected:
getSymbol(void) const2169*35238bceSAndroid Build Coastguard Worker string getSymbol(void) const
2170*35238bceSAndroid Build Coastguard Worker {
2171*35238bceSAndroid Build Coastguard Worker return "/";
2172*35238bceSAndroid Build Coastguard Worker }
2173*35238bceSAndroid Build Coastguard Worker
innerExtrema(const EvalContext &,const Interval & nom,const Interval & den) const2174*35238bceSAndroid Build Coastguard Worker Interval innerExtrema(const EvalContext &, const Interval &nom, const Interval &den) const
2175*35238bceSAndroid Build Coastguard Worker {
2176*35238bceSAndroid Build Coastguard Worker Interval ret;
2177*35238bceSAndroid Build Coastguard Worker
2178*35238bceSAndroid Build Coastguard Worker if (den.contains(0.0))
2179*35238bceSAndroid Build Coastguard Worker {
2180*35238bceSAndroid Build Coastguard Worker if (nom.contains(0.0))
2181*35238bceSAndroid Build Coastguard Worker ret |= TCU_NAN;
2182*35238bceSAndroid Build Coastguard Worker
2183*35238bceSAndroid Build Coastguard Worker if (nom.lo() < 0.0 || nom.hi() > 0.0)
2184*35238bceSAndroid Build Coastguard Worker ret |= Interval::unbounded();
2185*35238bceSAndroid Build Coastguard Worker }
2186*35238bceSAndroid Build Coastguard Worker
2187*35238bceSAndroid Build Coastguard Worker return ret;
2188*35238bceSAndroid Build Coastguard Worker }
2189*35238bceSAndroid Build Coastguard Worker
applyExact(double x,double y) const2190*35238bceSAndroid Build Coastguard Worker double applyExact(double x, double y) const
2191*35238bceSAndroid Build Coastguard Worker {
2192*35238bceSAndroid Build Coastguard Worker return x / y;
2193*35238bceSAndroid Build Coastguard Worker }
2194*35238bceSAndroid Build Coastguard Worker
applyPoint(const EvalContext & ctx,double x,double y) const2195*35238bceSAndroid Build Coastguard Worker Interval applyPoint(const EvalContext &ctx, double x, double y) const
2196*35238bceSAndroid Build Coastguard Worker {
2197*35238bceSAndroid Build Coastguard Worker Interval ret = FloatFunc2::applyPoint(ctx, x, y);
2198*35238bceSAndroid Build Coastguard Worker
2199*35238bceSAndroid Build Coastguard Worker if (!deIsInf(x) && !deIsInf(y) && y != 0.0)
2200*35238bceSAndroid Build Coastguard Worker {
2201*35238bceSAndroid Build Coastguard Worker const Interval dst = ctx.format.convert(ret);
2202*35238bceSAndroid Build Coastguard Worker if (dst.contains(-TCU_INFINITY))
2203*35238bceSAndroid Build Coastguard Worker ret |= -ctx.format.getMaxValue();
2204*35238bceSAndroid Build Coastguard Worker if (dst.contains(+TCU_INFINITY))
2205*35238bceSAndroid Build Coastguard Worker ret |= +ctx.format.getMaxValue();
2206*35238bceSAndroid Build Coastguard Worker }
2207*35238bceSAndroid Build Coastguard Worker
2208*35238bceSAndroid Build Coastguard Worker return ret;
2209*35238bceSAndroid Build Coastguard Worker }
2210*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext & ctx,double ret,double,double den) const2211*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double ret, double, double den) const
2212*35238bceSAndroid Build Coastguard Worker {
2213*35238bceSAndroid Build Coastguard Worker const FloatFormat &fmt = ctx.format;
2214*35238bceSAndroid Build Coastguard Worker
2215*35238bceSAndroid Build Coastguard Worker // \todo [2014-03-05 lauri] Check that the limits in GLSL 3.10 are actually correct.
2216*35238bceSAndroid Build Coastguard Worker // For now, we assume that division's precision is 2.5 ULP when the value is within
2217*35238bceSAndroid Build Coastguard Worker // [2^MINEXP, 2^MAXEXP-1]
2218*35238bceSAndroid Build Coastguard Worker
2219*35238bceSAndroid Build Coastguard Worker if (den == 0.0)
2220*35238bceSAndroid Build Coastguard Worker return 0.0; // Result must be exactly inf
2221*35238bceSAndroid Build Coastguard Worker else if (de::inBounds(deAbs(den), deLdExp(1.0, fmt.getMinExp()), deLdExp(1.0, fmt.getMaxExp() - 1)))
2222*35238bceSAndroid Build Coastguard Worker return fmt.ulp(ret, 2.5);
2223*35238bceSAndroid Build Coastguard Worker else
2224*35238bceSAndroid Build Coastguard Worker return TCU_INFINITY; // Can be any number, but must be a number.
2225*35238bceSAndroid Build Coastguard Worker }
2226*35238bceSAndroid Build Coastguard Worker };
2227*35238bceSAndroid Build Coastguard Worker
2228*35238bceSAndroid Build Coastguard Worker class InverseSqrt : public FloatFunc1
2229*35238bceSAndroid Build Coastguard Worker {
2230*35238bceSAndroid Build Coastguard Worker public:
getName(void) const2231*35238bceSAndroid Build Coastguard Worker string getName(void) const
2232*35238bceSAndroid Build Coastguard Worker {
2233*35238bceSAndroid Build Coastguard Worker return "inversesqrt";
2234*35238bceSAndroid Build Coastguard Worker }
2235*35238bceSAndroid Build Coastguard Worker
2236*35238bceSAndroid Build Coastguard Worker protected:
applyExact(double x) const2237*35238bceSAndroid Build Coastguard Worker double applyExact(double x) const
2238*35238bceSAndroid Build Coastguard Worker {
2239*35238bceSAndroid Build Coastguard Worker return 1.0 / deSqrt(x);
2240*35238bceSAndroid Build Coastguard Worker }
2241*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext & ctx,double ret,double x) const2242*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double ret, double x) const
2243*35238bceSAndroid Build Coastguard Worker {
2244*35238bceSAndroid Build Coastguard Worker return x <= 0 ? TCU_NAN : ctx.format.ulp(ret, 2.0);
2245*35238bceSAndroid Build Coastguard Worker }
2246*35238bceSAndroid Build Coastguard Worker
getCodomain(void) const2247*35238bceSAndroid Build Coastguard Worker Interval getCodomain(void) const
2248*35238bceSAndroid Build Coastguard Worker {
2249*35238bceSAndroid Build Coastguard Worker return Interval(0.0, TCU_INFINITY);
2250*35238bceSAndroid Build Coastguard Worker }
2251*35238bceSAndroid Build Coastguard Worker };
2252*35238bceSAndroid Build Coastguard Worker
2253*35238bceSAndroid Build Coastguard Worker class ExpFunc : public CFloatFunc1
2254*35238bceSAndroid Build Coastguard Worker {
2255*35238bceSAndroid Build Coastguard Worker public:
ExpFunc(const string & name,DoubleFunc1 & func)2256*35238bceSAndroid Build Coastguard Worker ExpFunc(const string &name, DoubleFunc1 &func) : CFloatFunc1(name, func)
2257*35238bceSAndroid Build Coastguard Worker {
2258*35238bceSAndroid Build Coastguard Worker }
2259*35238bceSAndroid Build Coastguard Worker
2260*35238bceSAndroid Build Coastguard Worker protected:
precision(const EvalContext & ctx,double ret,double x) const2261*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double ret, double x) const
2262*35238bceSAndroid Build Coastguard Worker {
2263*35238bceSAndroid Build Coastguard Worker switch (ctx.floatPrecision)
2264*35238bceSAndroid Build Coastguard Worker {
2265*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
2266*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 3.0 + 2.0 * deAbs(x));
2267*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
2268*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 2.0 + 2.0 * deAbs(x));
2269*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
2270*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 2.0);
2271*35238bceSAndroid Build Coastguard Worker default:
2272*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
2273*35238bceSAndroid Build Coastguard Worker }
2274*35238bceSAndroid Build Coastguard Worker return 0;
2275*35238bceSAndroid Build Coastguard Worker }
2276*35238bceSAndroid Build Coastguard Worker
getCodomain(void) const2277*35238bceSAndroid Build Coastguard Worker Interval getCodomain(void) const
2278*35238bceSAndroid Build Coastguard Worker {
2279*35238bceSAndroid Build Coastguard Worker return Interval(0.0, TCU_INFINITY);
2280*35238bceSAndroid Build Coastguard Worker }
2281*35238bceSAndroid Build Coastguard Worker };
2282*35238bceSAndroid Build Coastguard Worker
2283*35238bceSAndroid Build Coastguard Worker class Exp2 : public ExpFunc
2284*35238bceSAndroid Build Coastguard Worker {
2285*35238bceSAndroid Build Coastguard Worker public:
Exp2(void)2286*35238bceSAndroid Build Coastguard Worker Exp2(void) : ExpFunc("exp2", deExp2)
2287*35238bceSAndroid Build Coastguard Worker {
2288*35238bceSAndroid Build Coastguard Worker }
2289*35238bceSAndroid Build Coastguard Worker };
2290*35238bceSAndroid Build Coastguard Worker class Exp : public ExpFunc
2291*35238bceSAndroid Build Coastguard Worker {
2292*35238bceSAndroid Build Coastguard Worker public:
Exp(void)2293*35238bceSAndroid Build Coastguard Worker Exp(void) : ExpFunc("exp", deExp)
2294*35238bceSAndroid Build Coastguard Worker {
2295*35238bceSAndroid Build Coastguard Worker }
2296*35238bceSAndroid Build Coastguard Worker };
2297*35238bceSAndroid Build Coastguard Worker
exp2(const ExprP<float> & x)2298*35238bceSAndroid Build Coastguard Worker ExprP<float> exp2(const ExprP<float> &x)
2299*35238bceSAndroid Build Coastguard Worker {
2300*35238bceSAndroid Build Coastguard Worker return app<Exp2>(x);
2301*35238bceSAndroid Build Coastguard Worker }
exp(const ExprP<float> & x)2302*35238bceSAndroid Build Coastguard Worker ExprP<float> exp(const ExprP<float> &x)
2303*35238bceSAndroid Build Coastguard Worker {
2304*35238bceSAndroid Build Coastguard Worker return app<Exp>(x);
2305*35238bceSAndroid Build Coastguard Worker }
2306*35238bceSAndroid Build Coastguard Worker
2307*35238bceSAndroid Build Coastguard Worker class LogFunc : public CFloatFunc1
2308*35238bceSAndroid Build Coastguard Worker {
2309*35238bceSAndroid Build Coastguard Worker public:
LogFunc(const string & name,DoubleFunc1 & func)2310*35238bceSAndroid Build Coastguard Worker LogFunc(const string &name, DoubleFunc1 &func) : CFloatFunc1(name, func)
2311*35238bceSAndroid Build Coastguard Worker {
2312*35238bceSAndroid Build Coastguard Worker }
2313*35238bceSAndroid Build Coastguard Worker
2314*35238bceSAndroid Build Coastguard Worker protected:
precision(const EvalContext & ctx,double ret,double x) const2315*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double ret, double x) const
2316*35238bceSAndroid Build Coastguard Worker {
2317*35238bceSAndroid Build Coastguard Worker if (x <= 0)
2318*35238bceSAndroid Build Coastguard Worker return TCU_NAN;
2319*35238bceSAndroid Build Coastguard Worker
2320*35238bceSAndroid Build Coastguard Worker switch (ctx.floatPrecision)
2321*35238bceSAndroid Build Coastguard Worker {
2322*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
2323*35238bceSAndroid Build Coastguard Worker return (0.5 <= x && x <= 2.0) ? deLdExp(1.0, -21) : ctx.format.ulp(ret, 3.0);
2324*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
2325*35238bceSAndroid Build Coastguard Worker return (0.5 <= x && x <= 2.0) ? deLdExp(1.0, -7) : ctx.format.ulp(ret, 2.0);
2326*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
2327*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 2.0);
2328*35238bceSAndroid Build Coastguard Worker default:
2329*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
2330*35238bceSAndroid Build Coastguard Worker }
2331*35238bceSAndroid Build Coastguard Worker
2332*35238bceSAndroid Build Coastguard Worker return 0;
2333*35238bceSAndroid Build Coastguard Worker }
2334*35238bceSAndroid Build Coastguard Worker
2335*35238bceSAndroid Build Coastguard Worker // OpenGL API Issue #57 "Clarifying the required ULP precision for GLSL built-in log()". Agreed that
2336*35238bceSAndroid Build Coastguard Worker // implementations will be allowed 4 ULPs for HIGHP Log/Log2, but CTS should generate a quality warning.
warningPrecision(const EvalContext & ctx,double ret,double x) const2337*35238bceSAndroid Build Coastguard Worker double warningPrecision(const EvalContext &ctx, double ret, double x) const
2338*35238bceSAndroid Build Coastguard Worker {
2339*35238bceSAndroid Build Coastguard Worker if (ctx.floatPrecision == glu::PRECISION_HIGHP && x > 0)
2340*35238bceSAndroid Build Coastguard Worker {
2341*35238bceSAndroid Build Coastguard Worker return (0.5 <= x && x <= 2.0) ? deLdExp(1.0, -21) : ctx.format.ulp(ret, 4.0);
2342*35238bceSAndroid Build Coastguard Worker }
2343*35238bceSAndroid Build Coastguard Worker else
2344*35238bceSAndroid Build Coastguard Worker {
2345*35238bceSAndroid Build Coastguard Worker return precision(ctx, ret, x);
2346*35238bceSAndroid Build Coastguard Worker }
2347*35238bceSAndroid Build Coastguard Worker }
2348*35238bceSAndroid Build Coastguard Worker };
2349*35238bceSAndroid Build Coastguard Worker
2350*35238bceSAndroid Build Coastguard Worker class Log2 : public LogFunc
2351*35238bceSAndroid Build Coastguard Worker {
2352*35238bceSAndroid Build Coastguard Worker public:
Log2(void)2353*35238bceSAndroid Build Coastguard Worker Log2(void) : LogFunc("log2", deLog2)
2354*35238bceSAndroid Build Coastguard Worker {
2355*35238bceSAndroid Build Coastguard Worker }
2356*35238bceSAndroid Build Coastguard Worker };
2357*35238bceSAndroid Build Coastguard Worker class Log : public LogFunc
2358*35238bceSAndroid Build Coastguard Worker {
2359*35238bceSAndroid Build Coastguard Worker public:
Log(void)2360*35238bceSAndroid Build Coastguard Worker Log(void) : LogFunc("log", deLog)
2361*35238bceSAndroid Build Coastguard Worker {
2362*35238bceSAndroid Build Coastguard Worker }
2363*35238bceSAndroid Build Coastguard Worker };
2364*35238bceSAndroid Build Coastguard Worker
log2(const ExprP<float> & x)2365*35238bceSAndroid Build Coastguard Worker ExprP<float> log2(const ExprP<float> &x)
2366*35238bceSAndroid Build Coastguard Worker {
2367*35238bceSAndroid Build Coastguard Worker return app<Log2>(x);
2368*35238bceSAndroid Build Coastguard Worker }
log(const ExprP<float> & x)2369*35238bceSAndroid Build Coastguard Worker ExprP<float> log(const ExprP<float> &x)
2370*35238bceSAndroid Build Coastguard Worker {
2371*35238bceSAndroid Build Coastguard Worker return app<Log>(x);
2372*35238bceSAndroid Build Coastguard Worker }
2373*35238bceSAndroid Build Coastguard Worker
2374*35238bceSAndroid Build Coastguard Worker #define DEFINE_CONSTRUCTOR1(CLASS, TRET, NAME, T0) \
2375*35238bceSAndroid Build Coastguard Worker ExprP<TRET> NAME(const ExprP<T0> &arg0) \
2376*35238bceSAndroid Build Coastguard Worker { \
2377*35238bceSAndroid Build Coastguard Worker return app<CLASS>(arg0); \
2378*35238bceSAndroid Build Coastguard Worker }
2379*35238bceSAndroid Build Coastguard Worker
2380*35238bceSAndroid Build Coastguard Worker #define DEFINE_DERIVED1(CLASS, TRET, NAME, T0, ARG0, EXPANSION) \
2381*35238bceSAndroid Build Coastguard Worker class CLASS : public DerivedFunc<Signature<TRET, T0>> /* NOLINT(CLASS) */ \
2382*35238bceSAndroid Build Coastguard Worker { \
2383*35238bceSAndroid Build Coastguard Worker public: \
2384*35238bceSAndroid Build Coastguard Worker string getName(void) const \
2385*35238bceSAndroid Build Coastguard Worker { \
2386*35238bceSAndroid Build Coastguard Worker return #NAME; \
2387*35238bceSAndroid Build Coastguard Worker } \
2388*35238bceSAndroid Build Coastguard Worker \
2389*35238bceSAndroid Build Coastguard Worker protected: \
2390*35238bceSAndroid Build Coastguard Worker ExprP<TRET> doExpand(ExpandContext &, const CLASS::ArgExprs &args_) const \
2391*35238bceSAndroid Build Coastguard Worker { \
2392*35238bceSAndroid Build Coastguard Worker const ExprP<float> &ARG0 = args_.a; \
2393*35238bceSAndroid Build Coastguard Worker return EXPANSION; \
2394*35238bceSAndroid Build Coastguard Worker } \
2395*35238bceSAndroid Build Coastguard Worker }; \
2396*35238bceSAndroid Build Coastguard Worker DEFINE_CONSTRUCTOR1(CLASS, TRET, NAME, T0)
2397*35238bceSAndroid Build Coastguard Worker
2398*35238bceSAndroid Build Coastguard Worker #define DEFINE_DERIVED_FLOAT1(CLASS, NAME, ARG0, EXPANSION) DEFINE_DERIVED1(CLASS, float, NAME, float, ARG0, EXPANSION)
2399*35238bceSAndroid Build Coastguard Worker
2400*35238bceSAndroid Build Coastguard Worker #define DEFINE_CONSTRUCTOR2(CLASS, TRET, NAME, T0, T1) \
2401*35238bceSAndroid Build Coastguard Worker ExprP<TRET> NAME(const ExprP<T0> &arg0, const ExprP<T1> &arg1) \
2402*35238bceSAndroid Build Coastguard Worker { \
2403*35238bceSAndroid Build Coastguard Worker return app<CLASS>(arg0, arg1); \
2404*35238bceSAndroid Build Coastguard Worker }
2405*35238bceSAndroid Build Coastguard Worker
2406*35238bceSAndroid Build Coastguard Worker #define DEFINE_DERIVED2(CLASS, TRET, NAME, T0, Arg0, T1, Arg1, EXPANSION) \
2407*35238bceSAndroid Build Coastguard Worker class CLASS : public DerivedFunc<Signature<TRET, T0, T1>> /* NOLINT(CLASS) */ \
2408*35238bceSAndroid Build Coastguard Worker { \
2409*35238bceSAndroid Build Coastguard Worker public: \
2410*35238bceSAndroid Build Coastguard Worker string getName(void) const \
2411*35238bceSAndroid Build Coastguard Worker { \
2412*35238bceSAndroid Build Coastguard Worker return #NAME; \
2413*35238bceSAndroid Build Coastguard Worker } \
2414*35238bceSAndroid Build Coastguard Worker \
2415*35238bceSAndroid Build Coastguard Worker protected: \
2416*35238bceSAndroid Build Coastguard Worker ExprP<TRET> doExpand(ExpandContext &, const ArgExprs &args_) const \
2417*35238bceSAndroid Build Coastguard Worker { \
2418*35238bceSAndroid Build Coastguard Worker const ExprP<T0> &Arg0 = args_.a; \
2419*35238bceSAndroid Build Coastguard Worker const ExprP<T1> &Arg1 = args_.b; \
2420*35238bceSAndroid Build Coastguard Worker return EXPANSION; \
2421*35238bceSAndroid Build Coastguard Worker } \
2422*35238bceSAndroid Build Coastguard Worker }; \
2423*35238bceSAndroid Build Coastguard Worker DEFINE_CONSTRUCTOR2(CLASS, TRET, NAME, T0, T1)
2424*35238bceSAndroid Build Coastguard Worker
2425*35238bceSAndroid Build Coastguard Worker #define DEFINE_DERIVED_FLOAT2(CLASS, NAME, Arg0, Arg1, EXPANSION) \
2426*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED2(CLASS, float, NAME, float, Arg0, float, Arg1, EXPANSION)
2427*35238bceSAndroid Build Coastguard Worker
2428*35238bceSAndroid Build Coastguard Worker #define DEFINE_CONSTRUCTOR3(CLASS, TRET, NAME, T0, T1, T2) \
2429*35238bceSAndroid Build Coastguard Worker ExprP<TRET> NAME(const ExprP<T0> &arg0, const ExprP<T1> &arg1, const ExprP<T2> &arg2) \
2430*35238bceSAndroid Build Coastguard Worker { \
2431*35238bceSAndroid Build Coastguard Worker return app<CLASS>(arg0, arg1, arg2); \
2432*35238bceSAndroid Build Coastguard Worker }
2433*35238bceSAndroid Build Coastguard Worker
2434*35238bceSAndroid Build Coastguard Worker #define DEFINE_DERIVED3(CLASS, TRET, NAME, T0, ARG0, T1, ARG1, T2, ARG2, EXPANSION) \
2435*35238bceSAndroid Build Coastguard Worker class CLASS : public DerivedFunc<Signature<TRET, T0, T1, T2>> /* NOLINT(CLASS) */ \
2436*35238bceSAndroid Build Coastguard Worker { \
2437*35238bceSAndroid Build Coastguard Worker public: \
2438*35238bceSAndroid Build Coastguard Worker string getName(void) const \
2439*35238bceSAndroid Build Coastguard Worker { \
2440*35238bceSAndroid Build Coastguard Worker return #NAME; \
2441*35238bceSAndroid Build Coastguard Worker } \
2442*35238bceSAndroid Build Coastguard Worker \
2443*35238bceSAndroid Build Coastguard Worker protected: \
2444*35238bceSAndroid Build Coastguard Worker ExprP<TRET> doExpand(ExpandContext &, const ArgExprs &args_) const \
2445*35238bceSAndroid Build Coastguard Worker { \
2446*35238bceSAndroid Build Coastguard Worker const ExprP<T0> &ARG0 = args_.a; \
2447*35238bceSAndroid Build Coastguard Worker const ExprP<T1> &ARG1 = args_.b; \
2448*35238bceSAndroid Build Coastguard Worker const ExprP<T2> &ARG2 = args_.c; \
2449*35238bceSAndroid Build Coastguard Worker return EXPANSION; \
2450*35238bceSAndroid Build Coastguard Worker } \
2451*35238bceSAndroid Build Coastguard Worker }; \
2452*35238bceSAndroid Build Coastguard Worker DEFINE_CONSTRUCTOR3(CLASS, TRET, NAME, T0, T1, T2)
2453*35238bceSAndroid Build Coastguard Worker
2454*35238bceSAndroid Build Coastguard Worker #define DEFINE_DERIVED_FLOAT3(CLASS, NAME, ARG0, ARG1, ARG2, EXPANSION) \
2455*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED3(CLASS, float, NAME, float, ARG0, float, ARG1, float, ARG2, EXPANSION)
2456*35238bceSAndroid Build Coastguard Worker
2457*35238bceSAndroid Build Coastguard Worker #define DEFINE_CONSTRUCTOR4(CLASS, TRET, NAME, T0, T1, T2, T3) \
2458*35238bceSAndroid Build Coastguard Worker ExprP<TRET> NAME(const ExprP<T0> &arg0, const ExprP<T1> &arg1, const ExprP<T2> &arg2, const ExprP<T3> &arg3) \
2459*35238bceSAndroid Build Coastguard Worker { \
2460*35238bceSAndroid Build Coastguard Worker return app<CLASS>(arg0, arg1, arg2, arg3); \
2461*35238bceSAndroid Build Coastguard Worker }
2462*35238bceSAndroid Build Coastguard Worker
2463*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Sqrt, sqrt, x, (x == 0.0f ? constant(1.0f) : (constant(1.0f) / app<InverseSqrt>(x))))
2464*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT2(Pow, pow, x, y, exp2(y *log2(x)))
2465*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Radians, radians, d, (constant(DE_PI) / constant(180.0f)) * d)
2466*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Degrees, degrees, r, (constant(180.0f) / constant(DE_PI)) * r)
2467*35238bceSAndroid Build Coastguard Worker
2468*35238bceSAndroid Build Coastguard Worker class TrigFunc : public CFloatFunc1
2469*35238bceSAndroid Build Coastguard Worker {
2470*35238bceSAndroid Build Coastguard Worker public:
TrigFunc(const string & name,DoubleFunc1 & func,const Interval & loEx,const Interval & hiEx)2471*35238bceSAndroid Build Coastguard Worker TrigFunc(const string &name, DoubleFunc1 &func, const Interval &loEx, const Interval &hiEx)
2472*35238bceSAndroid Build Coastguard Worker : CFloatFunc1(name, func)
2473*35238bceSAndroid Build Coastguard Worker , m_loExtremum(loEx)
2474*35238bceSAndroid Build Coastguard Worker , m_hiExtremum(hiEx)
2475*35238bceSAndroid Build Coastguard Worker {
2476*35238bceSAndroid Build Coastguard Worker }
2477*35238bceSAndroid Build Coastguard Worker
2478*35238bceSAndroid Build Coastguard Worker protected:
innerExtrema(const EvalContext &,const Interval & angle) const2479*35238bceSAndroid Build Coastguard Worker Interval innerExtrema(const EvalContext &, const Interval &angle) const
2480*35238bceSAndroid Build Coastguard Worker {
2481*35238bceSAndroid Build Coastguard Worker const double lo = angle.lo();
2482*35238bceSAndroid Build Coastguard Worker const double hi = angle.hi();
2483*35238bceSAndroid Build Coastguard Worker const int loSlope = doGetSlope(lo);
2484*35238bceSAndroid Build Coastguard Worker const int hiSlope = doGetSlope(hi);
2485*35238bceSAndroid Build Coastguard Worker
2486*35238bceSAndroid Build Coastguard Worker // Detect the high and low values the function can take between the
2487*35238bceSAndroid Build Coastguard Worker // interval endpoints.
2488*35238bceSAndroid Build Coastguard Worker if (angle.length() >= 2.0 * DE_PI_DOUBLE)
2489*35238bceSAndroid Build Coastguard Worker {
2490*35238bceSAndroid Build Coastguard Worker // The interval is longer than a full cycle, so it must get all possible values.
2491*35238bceSAndroid Build Coastguard Worker return m_hiExtremum | m_loExtremum;
2492*35238bceSAndroid Build Coastguard Worker }
2493*35238bceSAndroid Build Coastguard Worker else if (loSlope == 1 && hiSlope == -1)
2494*35238bceSAndroid Build Coastguard Worker {
2495*35238bceSAndroid Build Coastguard Worker // The slope can change from positive to negative only at the maximum value.
2496*35238bceSAndroid Build Coastguard Worker return m_hiExtremum;
2497*35238bceSAndroid Build Coastguard Worker }
2498*35238bceSAndroid Build Coastguard Worker else if (loSlope == -1 && hiSlope == 1)
2499*35238bceSAndroid Build Coastguard Worker {
2500*35238bceSAndroid Build Coastguard Worker // The slope can change from negative to positive only at the maximum value.
2501*35238bceSAndroid Build Coastguard Worker return m_loExtremum;
2502*35238bceSAndroid Build Coastguard Worker }
2503*35238bceSAndroid Build Coastguard Worker else if (loSlope == hiSlope && deIntSign(applyExact(hi) - applyExact(lo)) * loSlope == -1)
2504*35238bceSAndroid Build Coastguard Worker {
2505*35238bceSAndroid Build Coastguard Worker // The slope has changed twice between the endpoints, so both extrema are included.
2506*35238bceSAndroid Build Coastguard Worker return m_hiExtremum | m_loExtremum;
2507*35238bceSAndroid Build Coastguard Worker }
2508*35238bceSAndroid Build Coastguard Worker
2509*35238bceSAndroid Build Coastguard Worker return Interval();
2510*35238bceSAndroid Build Coastguard Worker }
2511*35238bceSAndroid Build Coastguard Worker
getCodomain(void) const2512*35238bceSAndroid Build Coastguard Worker Interval getCodomain(void) const
2513*35238bceSAndroid Build Coastguard Worker {
2514*35238bceSAndroid Build Coastguard Worker // Ensure that result is always within [-1, 1], or NaN (for +-inf)
2515*35238bceSAndroid Build Coastguard Worker return Interval(-1.0, 1.0) | TCU_NAN;
2516*35238bceSAndroid Build Coastguard Worker }
2517*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext & ctx,double ret,double arg) const2518*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double ret, double arg) const
2519*35238bceSAndroid Build Coastguard Worker {
2520*35238bceSAndroid Build Coastguard Worker if (ctx.floatPrecision == glu::PRECISION_HIGHP)
2521*35238bceSAndroid Build Coastguard Worker {
2522*35238bceSAndroid Build Coastguard Worker // Use precision from OpenCL fast relaxed math
2523*35238bceSAndroid Build Coastguard Worker if (-DE_PI_DOUBLE <= arg && arg <= DE_PI_DOUBLE)
2524*35238bceSAndroid Build Coastguard Worker {
2525*35238bceSAndroid Build Coastguard Worker return deLdExp(1.0, -11);
2526*35238bceSAndroid Build Coastguard Worker }
2527*35238bceSAndroid Build Coastguard Worker else
2528*35238bceSAndroid Build Coastguard Worker {
2529*35238bceSAndroid Build Coastguard Worker // "larger otherwise", let's pick |x| * 2^-12 , which is slightly over
2530*35238bceSAndroid Build Coastguard Worker // 2^-11 at x == pi.
2531*35238bceSAndroid Build Coastguard Worker return deLdExp(deAbs(arg), -12);
2532*35238bceSAndroid Build Coastguard Worker }
2533*35238bceSAndroid Build Coastguard Worker }
2534*35238bceSAndroid Build Coastguard Worker else if (ctx.floatPrecision == glu::PRECISION_MEDIUMP)
2535*35238bceSAndroid Build Coastguard Worker {
2536*35238bceSAndroid Build Coastguard Worker if (-DE_PI_DOUBLE <= arg && arg <= DE_PI_DOUBLE)
2537*35238bceSAndroid Build Coastguard Worker {
2538*35238bceSAndroid Build Coastguard Worker // from OpenCL half-float extension specification
2539*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 2.0);
2540*35238bceSAndroid Build Coastguard Worker }
2541*35238bceSAndroid Build Coastguard Worker else
2542*35238bceSAndroid Build Coastguard Worker {
2543*35238bceSAndroid Build Coastguard Worker // |x| * 2^-10, slightly larger than 2 ULP at x == pi
2544*35238bceSAndroid Build Coastguard Worker return deLdExp(deAbs(arg), -10);
2545*35238bceSAndroid Build Coastguard Worker }
2546*35238bceSAndroid Build Coastguard Worker }
2547*35238bceSAndroid Build Coastguard Worker else
2548*35238bceSAndroid Build Coastguard Worker {
2549*35238bceSAndroid Build Coastguard Worker DE_ASSERT(ctx.floatPrecision == glu::PRECISION_LOWP);
2550*35238bceSAndroid Build Coastguard Worker
2551*35238bceSAndroid Build Coastguard Worker // from OpenCL half-float extension specification
2552*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 2.0);
2553*35238bceSAndroid Build Coastguard Worker }
2554*35238bceSAndroid Build Coastguard Worker }
2555*35238bceSAndroid Build Coastguard Worker
2556*35238bceSAndroid Build Coastguard Worker virtual int doGetSlope(double angle) const = 0;
2557*35238bceSAndroid Build Coastguard Worker
2558*35238bceSAndroid Build Coastguard Worker Interval m_loExtremum;
2559*35238bceSAndroid Build Coastguard Worker Interval m_hiExtremum;
2560*35238bceSAndroid Build Coastguard Worker };
2561*35238bceSAndroid Build Coastguard Worker
2562*35238bceSAndroid Build Coastguard Worker class Sin : public TrigFunc
2563*35238bceSAndroid Build Coastguard Worker {
2564*35238bceSAndroid Build Coastguard Worker public:
Sin(void)2565*35238bceSAndroid Build Coastguard Worker Sin(void) : TrigFunc("sin", deSin, -1.0, 1.0)
2566*35238bceSAndroid Build Coastguard Worker {
2567*35238bceSAndroid Build Coastguard Worker }
2568*35238bceSAndroid Build Coastguard Worker
2569*35238bceSAndroid Build Coastguard Worker protected:
doGetSlope(double angle) const2570*35238bceSAndroid Build Coastguard Worker int doGetSlope(double angle) const
2571*35238bceSAndroid Build Coastguard Worker {
2572*35238bceSAndroid Build Coastguard Worker return deIntSign(deCos(angle));
2573*35238bceSAndroid Build Coastguard Worker }
2574*35238bceSAndroid Build Coastguard Worker };
2575*35238bceSAndroid Build Coastguard Worker
sin(const ExprP<float> & x)2576*35238bceSAndroid Build Coastguard Worker ExprP<float> sin(const ExprP<float> &x)
2577*35238bceSAndroid Build Coastguard Worker {
2578*35238bceSAndroid Build Coastguard Worker return app<Sin>(x);
2579*35238bceSAndroid Build Coastguard Worker }
2580*35238bceSAndroid Build Coastguard Worker
2581*35238bceSAndroid Build Coastguard Worker class Cos : public TrigFunc
2582*35238bceSAndroid Build Coastguard Worker {
2583*35238bceSAndroid Build Coastguard Worker public:
Cos(void)2584*35238bceSAndroid Build Coastguard Worker Cos(void) : TrigFunc("cos", deCos, -1.0, 1.0)
2585*35238bceSAndroid Build Coastguard Worker {
2586*35238bceSAndroid Build Coastguard Worker }
2587*35238bceSAndroid Build Coastguard Worker
2588*35238bceSAndroid Build Coastguard Worker protected:
doGetSlope(double angle) const2589*35238bceSAndroid Build Coastguard Worker int doGetSlope(double angle) const
2590*35238bceSAndroid Build Coastguard Worker {
2591*35238bceSAndroid Build Coastguard Worker return -deIntSign(deSin(angle));
2592*35238bceSAndroid Build Coastguard Worker }
2593*35238bceSAndroid Build Coastguard Worker };
2594*35238bceSAndroid Build Coastguard Worker
cos(const ExprP<float> & x)2595*35238bceSAndroid Build Coastguard Worker ExprP<float> cos(const ExprP<float> &x)
2596*35238bceSAndroid Build Coastguard Worker {
2597*35238bceSAndroid Build Coastguard Worker return app<Cos>(x);
2598*35238bceSAndroid Build Coastguard Worker }
2599*35238bceSAndroid Build Coastguard Worker
2600*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Tan, tan, x, sin(x) * (constant(1.0f) / cos(x)))
2601*35238bceSAndroid Build Coastguard Worker
2602*35238bceSAndroid Build Coastguard Worker class ASin : public CFloatFunc1
2603*35238bceSAndroid Build Coastguard Worker {
2604*35238bceSAndroid Build Coastguard Worker public:
ASin(void)2605*35238bceSAndroid Build Coastguard Worker ASin(void) : CFloatFunc1("asin", deAsin)
2606*35238bceSAndroid Build Coastguard Worker {
2607*35238bceSAndroid Build Coastguard Worker }
2608*35238bceSAndroid Build Coastguard Worker
2609*35238bceSAndroid Build Coastguard Worker protected:
precision(const EvalContext & ctx,double,double x) const2610*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double, double x) const
2611*35238bceSAndroid Build Coastguard Worker {
2612*35238bceSAndroid Build Coastguard Worker if (!de::inBounds(x, -1.0, 1.0))
2613*35238bceSAndroid Build Coastguard Worker return TCU_NAN;
2614*35238bceSAndroid Build Coastguard Worker
2615*35238bceSAndroid Build Coastguard Worker if (ctx.floatPrecision == glu::PRECISION_HIGHP)
2616*35238bceSAndroid Build Coastguard Worker {
2617*35238bceSAndroid Build Coastguard Worker // Absolute error of 2^-11
2618*35238bceSAndroid Build Coastguard Worker return deLdExp(1.0, -11);
2619*35238bceSAndroid Build Coastguard Worker }
2620*35238bceSAndroid Build Coastguard Worker else
2621*35238bceSAndroid Build Coastguard Worker {
2622*35238bceSAndroid Build Coastguard Worker // Absolute error of 2^-8
2623*35238bceSAndroid Build Coastguard Worker return deLdExp(1.0, -8);
2624*35238bceSAndroid Build Coastguard Worker }
2625*35238bceSAndroid Build Coastguard Worker }
2626*35238bceSAndroid Build Coastguard Worker };
2627*35238bceSAndroid Build Coastguard Worker
2628*35238bceSAndroid Build Coastguard Worker class ArcTrigFunc : public CFloatFunc1
2629*35238bceSAndroid Build Coastguard Worker {
2630*35238bceSAndroid Build Coastguard Worker public:
ArcTrigFunc(const string & name,DoubleFunc1 & func,double precisionULPs,const Interval & domain,const Interval & codomain)2631*35238bceSAndroid Build Coastguard Worker ArcTrigFunc(const string &name, DoubleFunc1 &func, double precisionULPs, const Interval &domain,
2632*35238bceSAndroid Build Coastguard Worker const Interval &codomain)
2633*35238bceSAndroid Build Coastguard Worker : CFloatFunc1(name, func)
2634*35238bceSAndroid Build Coastguard Worker , m_precision(precisionULPs)
2635*35238bceSAndroid Build Coastguard Worker , m_domain(domain)
2636*35238bceSAndroid Build Coastguard Worker , m_codomain(codomain)
2637*35238bceSAndroid Build Coastguard Worker {
2638*35238bceSAndroid Build Coastguard Worker }
2639*35238bceSAndroid Build Coastguard Worker
2640*35238bceSAndroid Build Coastguard Worker protected:
precision(const EvalContext & ctx,double ret,double x) const2641*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double ret, double x) const
2642*35238bceSAndroid Build Coastguard Worker {
2643*35238bceSAndroid Build Coastguard Worker if (!m_domain.contains(x))
2644*35238bceSAndroid Build Coastguard Worker return TCU_NAN;
2645*35238bceSAndroid Build Coastguard Worker
2646*35238bceSAndroid Build Coastguard Worker if (ctx.floatPrecision == glu::PRECISION_HIGHP)
2647*35238bceSAndroid Build Coastguard Worker {
2648*35238bceSAndroid Build Coastguard Worker // Use OpenCL's fast relaxed math precision
2649*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, m_precision);
2650*35238bceSAndroid Build Coastguard Worker }
2651*35238bceSAndroid Build Coastguard Worker else
2652*35238bceSAndroid Build Coastguard Worker {
2653*35238bceSAndroid Build Coastguard Worker // Use OpenCL half-float spec
2654*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 2.0);
2655*35238bceSAndroid Build Coastguard Worker }
2656*35238bceSAndroid Build Coastguard Worker }
2657*35238bceSAndroid Build Coastguard Worker
2658*35238bceSAndroid Build Coastguard Worker // We could implement getCodomain with m_codomain, but choose not to,
2659*35238bceSAndroid Build Coastguard Worker // because it seems too strict with trascendental constants like pi.
2660*35238bceSAndroid Build Coastguard Worker
2661*35238bceSAndroid Build Coastguard Worker const double m_precision;
2662*35238bceSAndroid Build Coastguard Worker const Interval m_domain;
2663*35238bceSAndroid Build Coastguard Worker const Interval m_codomain;
2664*35238bceSAndroid Build Coastguard Worker };
2665*35238bceSAndroid Build Coastguard Worker
2666*35238bceSAndroid Build Coastguard Worker class ACos : public ArcTrigFunc
2667*35238bceSAndroid Build Coastguard Worker {
2668*35238bceSAndroid Build Coastguard Worker public:
ACos(void)2669*35238bceSAndroid Build Coastguard Worker ACos(void) : ArcTrigFunc("acos", deAcos, 4096.0, Interval(-1.0, 1.0), Interval(0.0, DE_PI_DOUBLE))
2670*35238bceSAndroid Build Coastguard Worker {
2671*35238bceSAndroid Build Coastguard Worker }
2672*35238bceSAndroid Build Coastguard Worker };
2673*35238bceSAndroid Build Coastguard Worker
2674*35238bceSAndroid Build Coastguard Worker class ATan : public ArcTrigFunc
2675*35238bceSAndroid Build Coastguard Worker {
2676*35238bceSAndroid Build Coastguard Worker public:
ATan(void)2677*35238bceSAndroid Build Coastguard Worker ATan(void)
2678*35238bceSAndroid Build Coastguard Worker : ArcTrigFunc("atan", deAtanOver, 4096.0, Interval::unbounded(),
2679*35238bceSAndroid Build Coastguard Worker Interval(-DE_PI_DOUBLE * 0.5, DE_PI_DOUBLE * 0.5))
2680*35238bceSAndroid Build Coastguard Worker {
2681*35238bceSAndroid Build Coastguard Worker }
2682*35238bceSAndroid Build Coastguard Worker };
2683*35238bceSAndroid Build Coastguard Worker
2684*35238bceSAndroid Build Coastguard Worker class ATan2 : public CFloatFunc2
2685*35238bceSAndroid Build Coastguard Worker {
2686*35238bceSAndroid Build Coastguard Worker public:
ATan2(void)2687*35238bceSAndroid Build Coastguard Worker ATan2(void) : CFloatFunc2("atan", deAtan2)
2688*35238bceSAndroid Build Coastguard Worker {
2689*35238bceSAndroid Build Coastguard Worker }
2690*35238bceSAndroid Build Coastguard Worker
2691*35238bceSAndroid Build Coastguard Worker protected:
innerExtrema(const EvalContext & ctx,const Interval & yi,const Interval & xi) const2692*35238bceSAndroid Build Coastguard Worker Interval innerExtrema(const EvalContext &ctx, const Interval &yi, const Interval &xi) const
2693*35238bceSAndroid Build Coastguard Worker {
2694*35238bceSAndroid Build Coastguard Worker Interval ret;
2695*35238bceSAndroid Build Coastguard Worker
2696*35238bceSAndroid Build Coastguard Worker if (yi.contains(0.0))
2697*35238bceSAndroid Build Coastguard Worker {
2698*35238bceSAndroid Build Coastguard Worker if (xi.contains(0.0))
2699*35238bceSAndroid Build Coastguard Worker ret |= TCU_NAN;
2700*35238bceSAndroid Build Coastguard Worker if (xi.intersects(Interval(-TCU_INFINITY, 0.0)))
2701*35238bceSAndroid Build Coastguard Worker ret |= Interval(-DE_PI_DOUBLE, DE_PI_DOUBLE);
2702*35238bceSAndroid Build Coastguard Worker }
2703*35238bceSAndroid Build Coastguard Worker
2704*35238bceSAndroid Build Coastguard Worker if (!yi.isFinite(ctx.format.getMaxValue()) || !xi.isFinite(ctx.format.getMaxValue()))
2705*35238bceSAndroid Build Coastguard Worker {
2706*35238bceSAndroid Build Coastguard Worker // Infinities may not be supported, allow anything, including NaN
2707*35238bceSAndroid Build Coastguard Worker ret |= TCU_NAN;
2708*35238bceSAndroid Build Coastguard Worker }
2709*35238bceSAndroid Build Coastguard Worker
2710*35238bceSAndroid Build Coastguard Worker return ret;
2711*35238bceSAndroid Build Coastguard Worker }
2712*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext & ctx,double ret,double,double) const2713*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &ctx, double ret, double, double) const
2714*35238bceSAndroid Build Coastguard Worker {
2715*35238bceSAndroid Build Coastguard Worker if (ctx.floatPrecision == glu::PRECISION_HIGHP)
2716*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 4096.0);
2717*35238bceSAndroid Build Coastguard Worker else
2718*35238bceSAndroid Build Coastguard Worker return ctx.format.ulp(ret, 2.0);
2719*35238bceSAndroid Build Coastguard Worker }
2720*35238bceSAndroid Build Coastguard Worker
2721*35238bceSAndroid Build Coastguard Worker // Codomain could be [-pi, pi], but that would probably be too strict.
2722*35238bceSAndroid Build Coastguard Worker };
2723*35238bceSAndroid Build Coastguard Worker
2724*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Sinh, sinh, x, (exp(x) - exp(-x)) / constant(2.0f))
2725*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Cosh, cosh, x, (exp(x) + exp(-x)) / constant(2.0f))
2726*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Tanh, tanh, x, sinh(x) / cosh(x))
2727*35238bceSAndroid Build Coastguard Worker
2728*35238bceSAndroid Build Coastguard Worker // These are not defined as derived forms in the GLSL ES spec, but
2729*35238bceSAndroid Build Coastguard Worker // that gives us a reasonable precision.
2730*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(ASinh, asinh, x, log(x + sqrt(x * x + constant(1.0f))))
2731*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(ACosh, acosh, x,
2732*35238bceSAndroid Build Coastguard Worker log(x +
2733*35238bceSAndroid Build Coastguard Worker sqrt(alternatives((x + constant(1.0f)) * (x - constant(1.0f)), (x * x - constant(1.0f))))))
2734*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(ATanh, atanh, x, constant(0.5f) * log((constant(1.0f) + x) / (constant(1.0f) - x)))
2735*35238bceSAndroid Build Coastguard Worker
2736*35238bceSAndroid Build Coastguard Worker template <typename T>
2737*35238bceSAndroid Build Coastguard Worker class GetComponent : public PrimitiveFunc<Signature<typename T::Element, T, int>>
2738*35238bceSAndroid Build Coastguard Worker {
2739*35238bceSAndroid Build Coastguard Worker public:
2740*35238bceSAndroid Build Coastguard Worker typedef typename GetComponent::IRet IRet;
2741*35238bceSAndroid Build Coastguard Worker
getName(void) const2742*35238bceSAndroid Build Coastguard Worker string getName(void) const
2743*35238bceSAndroid Build Coastguard Worker {
2744*35238bceSAndroid Build Coastguard Worker return "_getComponent";
2745*35238bceSAndroid Build Coastguard Worker }
2746*35238bceSAndroid Build Coastguard Worker
print(ostream & os,const BaseArgExprs & args) const2747*35238bceSAndroid Build Coastguard Worker void print(ostream &os, const BaseArgExprs &args) const
2748*35238bceSAndroid Build Coastguard Worker {
2749*35238bceSAndroid Build Coastguard Worker os << *args[0] << "[" << *args[1] << "]";
2750*35238bceSAndroid Build Coastguard Worker }
2751*35238bceSAndroid Build Coastguard Worker
2752*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const typename GetComponent::IArgs & iargs) const2753*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const typename GetComponent::IArgs &iargs) const
2754*35238bceSAndroid Build Coastguard Worker {
2755*35238bceSAndroid Build Coastguard Worker IRet ret;
2756*35238bceSAndroid Build Coastguard Worker
2757*35238bceSAndroid Build Coastguard Worker for (int compNdx = 0; compNdx < T::SIZE; ++compNdx)
2758*35238bceSAndroid Build Coastguard Worker {
2759*35238bceSAndroid Build Coastguard Worker if (iargs.b.contains(compNdx))
2760*35238bceSAndroid Build Coastguard Worker ret = unionIVal<typename T::Element>(ret, iargs.a[compNdx]);
2761*35238bceSAndroid Build Coastguard Worker }
2762*35238bceSAndroid Build Coastguard Worker
2763*35238bceSAndroid Build Coastguard Worker return ret;
2764*35238bceSAndroid Build Coastguard Worker }
2765*35238bceSAndroid Build Coastguard Worker };
2766*35238bceSAndroid Build Coastguard Worker
2767*35238bceSAndroid Build Coastguard Worker template <typename T>
getComponent(const ExprP<T> & container,int ndx)2768*35238bceSAndroid Build Coastguard Worker ExprP<typename T::Element> getComponent(const ExprP<T> &container, int ndx)
2769*35238bceSAndroid Build Coastguard Worker {
2770*35238bceSAndroid Build Coastguard Worker DE_ASSERT(0 <= ndx && ndx < T::SIZE);
2771*35238bceSAndroid Build Coastguard Worker return app<GetComponent<T>>(container, constant(ndx));
2772*35238bceSAndroid Build Coastguard Worker }
2773*35238bceSAndroid Build Coastguard Worker
2774*35238bceSAndroid Build Coastguard Worker template <typename T>
2775*35238bceSAndroid Build Coastguard Worker string vecNamePrefix(void);
2776*35238bceSAndroid Build Coastguard Worker template <>
vecNamePrefix(void)2777*35238bceSAndroid Build Coastguard Worker string vecNamePrefix<float>(void)
2778*35238bceSAndroid Build Coastguard Worker {
2779*35238bceSAndroid Build Coastguard Worker return "";
2780*35238bceSAndroid Build Coastguard Worker }
2781*35238bceSAndroid Build Coastguard Worker template <>
vecNamePrefix(void)2782*35238bceSAndroid Build Coastguard Worker string vecNamePrefix<int>(void)
2783*35238bceSAndroid Build Coastguard Worker {
2784*35238bceSAndroid Build Coastguard Worker return "i";
2785*35238bceSAndroid Build Coastguard Worker }
2786*35238bceSAndroid Build Coastguard Worker template <>
vecNamePrefix(void)2787*35238bceSAndroid Build Coastguard Worker string vecNamePrefix<bool>(void)
2788*35238bceSAndroid Build Coastguard Worker {
2789*35238bceSAndroid Build Coastguard Worker return "b";
2790*35238bceSAndroid Build Coastguard Worker }
2791*35238bceSAndroid Build Coastguard Worker
2792*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
vecName(void)2793*35238bceSAndroid Build Coastguard Worker string vecName(void)
2794*35238bceSAndroid Build Coastguard Worker {
2795*35238bceSAndroid Build Coastguard Worker return vecNamePrefix<T>() + "vec" + de::toString(Size);
2796*35238bceSAndroid Build Coastguard Worker }
2797*35238bceSAndroid Build Coastguard Worker
2798*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
2799*35238bceSAndroid Build Coastguard Worker class GenVec;
2800*35238bceSAndroid Build Coastguard Worker
2801*35238bceSAndroid Build Coastguard Worker template <typename T>
2802*35238bceSAndroid Build Coastguard Worker class GenVec<T, 1> : public DerivedFunc<Signature<T, T>>
2803*35238bceSAndroid Build Coastguard Worker {
2804*35238bceSAndroid Build Coastguard Worker public:
2805*35238bceSAndroid Build Coastguard Worker typedef typename GenVec<T, 1>::ArgExprs ArgExprs;
2806*35238bceSAndroid Build Coastguard Worker
getName(void) const2807*35238bceSAndroid Build Coastguard Worker string getName(void) const
2808*35238bceSAndroid Build Coastguard Worker {
2809*35238bceSAndroid Build Coastguard Worker return "_" + vecName<T, 1>();
2810*35238bceSAndroid Build Coastguard Worker }
2811*35238bceSAndroid Build Coastguard Worker
2812*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const2813*35238bceSAndroid Build Coastguard Worker ExprP<T> doExpand(ExpandContext &, const ArgExprs &args) const
2814*35238bceSAndroid Build Coastguard Worker {
2815*35238bceSAndroid Build Coastguard Worker return args.a;
2816*35238bceSAndroid Build Coastguard Worker }
2817*35238bceSAndroid Build Coastguard Worker };
2818*35238bceSAndroid Build Coastguard Worker
2819*35238bceSAndroid Build Coastguard Worker template <typename T>
2820*35238bceSAndroid Build Coastguard Worker class GenVec<T, 2> : public PrimitiveFunc<Signature<Vector<T, 2>, T, T>>
2821*35238bceSAndroid Build Coastguard Worker {
2822*35238bceSAndroid Build Coastguard Worker public:
2823*35238bceSAndroid Build Coastguard Worker typedef typename GenVec::IRet IRet;
2824*35238bceSAndroid Build Coastguard Worker typedef typename GenVec::IArgs IArgs;
2825*35238bceSAndroid Build Coastguard Worker
getName(void) const2826*35238bceSAndroid Build Coastguard Worker string getName(void) const
2827*35238bceSAndroid Build Coastguard Worker {
2828*35238bceSAndroid Build Coastguard Worker return vecName<T, 2>();
2829*35238bceSAndroid Build Coastguard Worker }
2830*35238bceSAndroid Build Coastguard Worker
2831*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const2832*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
2833*35238bceSAndroid Build Coastguard Worker {
2834*35238bceSAndroid Build Coastguard Worker return IRet(iargs.a, iargs.b);
2835*35238bceSAndroid Build Coastguard Worker }
2836*35238bceSAndroid Build Coastguard Worker };
2837*35238bceSAndroid Build Coastguard Worker
2838*35238bceSAndroid Build Coastguard Worker template <typename T>
2839*35238bceSAndroid Build Coastguard Worker class GenVec<T, 3> : public PrimitiveFunc<Signature<Vector<T, 3>, T, T, T>>
2840*35238bceSAndroid Build Coastguard Worker {
2841*35238bceSAndroid Build Coastguard Worker public:
2842*35238bceSAndroid Build Coastguard Worker typedef typename GenVec::IRet IRet;
2843*35238bceSAndroid Build Coastguard Worker typedef typename GenVec::IArgs IArgs;
2844*35238bceSAndroid Build Coastguard Worker
getName(void) const2845*35238bceSAndroid Build Coastguard Worker string getName(void) const
2846*35238bceSAndroid Build Coastguard Worker {
2847*35238bceSAndroid Build Coastguard Worker return vecName<T, 3>();
2848*35238bceSAndroid Build Coastguard Worker }
2849*35238bceSAndroid Build Coastguard Worker
2850*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const2851*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
2852*35238bceSAndroid Build Coastguard Worker {
2853*35238bceSAndroid Build Coastguard Worker return IRet(iargs.a, iargs.b, iargs.c);
2854*35238bceSAndroid Build Coastguard Worker }
2855*35238bceSAndroid Build Coastguard Worker };
2856*35238bceSAndroid Build Coastguard Worker
2857*35238bceSAndroid Build Coastguard Worker template <typename T>
2858*35238bceSAndroid Build Coastguard Worker class GenVec<T, 4> : public PrimitiveFunc<Signature<Vector<T, 4>, T, T, T, T>>
2859*35238bceSAndroid Build Coastguard Worker {
2860*35238bceSAndroid Build Coastguard Worker public:
2861*35238bceSAndroid Build Coastguard Worker typedef typename GenVec::IRet IRet;
2862*35238bceSAndroid Build Coastguard Worker typedef typename GenVec::IArgs IArgs;
2863*35238bceSAndroid Build Coastguard Worker
getName(void) const2864*35238bceSAndroid Build Coastguard Worker string getName(void) const
2865*35238bceSAndroid Build Coastguard Worker {
2866*35238bceSAndroid Build Coastguard Worker return vecName<T, 4>();
2867*35238bceSAndroid Build Coastguard Worker }
2868*35238bceSAndroid Build Coastguard Worker
2869*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const2870*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
2871*35238bceSAndroid Build Coastguard Worker {
2872*35238bceSAndroid Build Coastguard Worker return IRet(iargs.a, iargs.b, iargs.c, iargs.d);
2873*35238bceSAndroid Build Coastguard Worker }
2874*35238bceSAndroid Build Coastguard Worker };
2875*35238bceSAndroid Build Coastguard Worker
2876*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Columns>
2877*35238bceSAndroid Build Coastguard Worker class GenMat;
2878*35238bceSAndroid Build Coastguard Worker
2879*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows>
2880*35238bceSAndroid Build Coastguard Worker class GenMat<T, Rows, 2> : public PrimitiveFunc<Signature<Matrix<T, Rows, 2>, Vector<T, Rows>, Vector<T, Rows>>>
2881*35238bceSAndroid Build Coastguard Worker {
2882*35238bceSAndroid Build Coastguard Worker public:
2883*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::Ret Ret;
2884*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::IRet IRet;
2885*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::IArgs IArgs;
2886*35238bceSAndroid Build Coastguard Worker
getName(void) const2887*35238bceSAndroid Build Coastguard Worker string getName(void) const
2888*35238bceSAndroid Build Coastguard Worker {
2889*35238bceSAndroid Build Coastguard Worker return dataTypeNameOf<Ret>();
2890*35238bceSAndroid Build Coastguard Worker }
2891*35238bceSAndroid Build Coastguard Worker
2892*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const2893*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
2894*35238bceSAndroid Build Coastguard Worker {
2895*35238bceSAndroid Build Coastguard Worker IRet ret;
2896*35238bceSAndroid Build Coastguard Worker ret[0] = iargs.a;
2897*35238bceSAndroid Build Coastguard Worker ret[1] = iargs.b;
2898*35238bceSAndroid Build Coastguard Worker return ret;
2899*35238bceSAndroid Build Coastguard Worker }
2900*35238bceSAndroid Build Coastguard Worker };
2901*35238bceSAndroid Build Coastguard Worker
2902*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows>
2903*35238bceSAndroid Build Coastguard Worker class GenMat<T, Rows, 3>
2904*35238bceSAndroid Build Coastguard Worker : public PrimitiveFunc<Signature<Matrix<T, Rows, 3>, Vector<T, Rows>, Vector<T, Rows>, Vector<T, Rows>>>
2905*35238bceSAndroid Build Coastguard Worker {
2906*35238bceSAndroid Build Coastguard Worker public:
2907*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::Ret Ret;
2908*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::IRet IRet;
2909*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::IArgs IArgs;
2910*35238bceSAndroid Build Coastguard Worker
getName(void) const2911*35238bceSAndroid Build Coastguard Worker string getName(void) const
2912*35238bceSAndroid Build Coastguard Worker {
2913*35238bceSAndroid Build Coastguard Worker return dataTypeNameOf<Ret>();
2914*35238bceSAndroid Build Coastguard Worker }
2915*35238bceSAndroid Build Coastguard Worker
2916*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const2917*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
2918*35238bceSAndroid Build Coastguard Worker {
2919*35238bceSAndroid Build Coastguard Worker IRet ret;
2920*35238bceSAndroid Build Coastguard Worker ret[0] = iargs.a;
2921*35238bceSAndroid Build Coastguard Worker ret[1] = iargs.b;
2922*35238bceSAndroid Build Coastguard Worker ret[2] = iargs.c;
2923*35238bceSAndroid Build Coastguard Worker return ret;
2924*35238bceSAndroid Build Coastguard Worker }
2925*35238bceSAndroid Build Coastguard Worker };
2926*35238bceSAndroid Build Coastguard Worker
2927*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows>
2928*35238bceSAndroid Build Coastguard Worker class GenMat<T, Rows, 4>
2929*35238bceSAndroid Build Coastguard Worker : public PrimitiveFunc<
2930*35238bceSAndroid Build Coastguard Worker Signature<Matrix<T, Rows, 4>, Vector<T, Rows>, Vector<T, Rows>, Vector<T, Rows>, Vector<T, Rows>>>
2931*35238bceSAndroid Build Coastguard Worker {
2932*35238bceSAndroid Build Coastguard Worker public:
2933*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::Ret Ret;
2934*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::IRet IRet;
2935*35238bceSAndroid Build Coastguard Worker typedef typename GenMat::IArgs IArgs;
2936*35238bceSAndroid Build Coastguard Worker
getName(void) const2937*35238bceSAndroid Build Coastguard Worker string getName(void) const
2938*35238bceSAndroid Build Coastguard Worker {
2939*35238bceSAndroid Build Coastguard Worker return dataTypeNameOf<Ret>();
2940*35238bceSAndroid Build Coastguard Worker }
2941*35238bceSAndroid Build Coastguard Worker
2942*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const2943*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
2944*35238bceSAndroid Build Coastguard Worker {
2945*35238bceSAndroid Build Coastguard Worker IRet ret;
2946*35238bceSAndroid Build Coastguard Worker ret[0] = iargs.a;
2947*35238bceSAndroid Build Coastguard Worker ret[1] = iargs.b;
2948*35238bceSAndroid Build Coastguard Worker ret[2] = iargs.c;
2949*35238bceSAndroid Build Coastguard Worker ret[3] = iargs.d;
2950*35238bceSAndroid Build Coastguard Worker return ret;
2951*35238bceSAndroid Build Coastguard Worker }
2952*35238bceSAndroid Build Coastguard Worker };
2953*35238bceSAndroid Build Coastguard Worker
2954*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows>
mat2(const ExprP<Vector<T,Rows>> & arg0,const ExprP<Vector<T,Rows>> & arg1)2955*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<T, Rows, 2>> mat2(const ExprP<Vector<T, Rows>> &arg0, const ExprP<Vector<T, Rows>> &arg1)
2956*35238bceSAndroid Build Coastguard Worker {
2957*35238bceSAndroid Build Coastguard Worker return app<GenMat<T, Rows, 2>>(arg0, arg1);
2958*35238bceSAndroid Build Coastguard Worker }
2959*35238bceSAndroid Build Coastguard Worker
2960*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows>
mat3(const ExprP<Vector<T,Rows>> & arg0,const ExprP<Vector<T,Rows>> & arg1,const ExprP<Vector<T,Rows>> & arg2)2961*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<T, Rows, 3>> mat3(const ExprP<Vector<T, Rows>> &arg0, const ExprP<Vector<T, Rows>> &arg1,
2962*35238bceSAndroid Build Coastguard Worker const ExprP<Vector<T, Rows>> &arg2)
2963*35238bceSAndroid Build Coastguard Worker {
2964*35238bceSAndroid Build Coastguard Worker return app<GenMat<T, Rows, 3>>(arg0, arg1, arg2);
2965*35238bceSAndroid Build Coastguard Worker }
2966*35238bceSAndroid Build Coastguard Worker
2967*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows>
mat4(const ExprP<Vector<T,Rows>> & arg0,const ExprP<Vector<T,Rows>> & arg1,const ExprP<Vector<T,Rows>> & arg2,const ExprP<Vector<T,Rows>> & arg3)2968*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<T, Rows, 4>> mat4(const ExprP<Vector<T, Rows>> &arg0, const ExprP<Vector<T, Rows>> &arg1,
2969*35238bceSAndroid Build Coastguard Worker const ExprP<Vector<T, Rows>> &arg2, const ExprP<Vector<T, Rows>> &arg3)
2970*35238bceSAndroid Build Coastguard Worker {
2971*35238bceSAndroid Build Coastguard Worker return app<GenMat<T, Rows, 4>>(arg0, arg1, arg2, arg3);
2972*35238bceSAndroid Build Coastguard Worker }
2973*35238bceSAndroid Build Coastguard Worker
2974*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
2975*35238bceSAndroid Build Coastguard Worker class MatNeg : public PrimitiveFunc<Signature<Matrix<float, Rows, Cols>, Matrix<float, Rows, Cols>>>
2976*35238bceSAndroid Build Coastguard Worker {
2977*35238bceSAndroid Build Coastguard Worker public:
2978*35238bceSAndroid Build Coastguard Worker typedef typename MatNeg::IRet IRet;
2979*35238bceSAndroid Build Coastguard Worker typedef typename MatNeg::IArgs IArgs;
2980*35238bceSAndroid Build Coastguard Worker
getName(void) const2981*35238bceSAndroid Build Coastguard Worker string getName(void) const
2982*35238bceSAndroid Build Coastguard Worker {
2983*35238bceSAndroid Build Coastguard Worker return "_matNeg";
2984*35238bceSAndroid Build Coastguard Worker }
2985*35238bceSAndroid Build Coastguard Worker
2986*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os,const BaseArgExprs & args) const2987*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
2988*35238bceSAndroid Build Coastguard Worker {
2989*35238bceSAndroid Build Coastguard Worker os << "-(" << *args[0] << ")";
2990*35238bceSAndroid Build Coastguard Worker }
2991*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext &,const IArgs & iargs) const2992*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
2993*35238bceSAndroid Build Coastguard Worker {
2994*35238bceSAndroid Build Coastguard Worker IRet ret;
2995*35238bceSAndroid Build Coastguard Worker
2996*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < Cols; ++col)
2997*35238bceSAndroid Build Coastguard Worker {
2998*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < Rows; ++row)
2999*35238bceSAndroid Build Coastguard Worker ret[col][row] = -iargs.a[col][row];
3000*35238bceSAndroid Build Coastguard Worker }
3001*35238bceSAndroid Build Coastguard Worker
3002*35238bceSAndroid Build Coastguard Worker return ret;
3003*35238bceSAndroid Build Coastguard Worker }
3004*35238bceSAndroid Build Coastguard Worker };
3005*35238bceSAndroid Build Coastguard Worker
3006*35238bceSAndroid Build Coastguard Worker template <typename T, typename Sig>
3007*35238bceSAndroid Build Coastguard Worker class CompWiseFunc : public PrimitiveFunc<Sig>
3008*35238bceSAndroid Build Coastguard Worker {
3009*35238bceSAndroid Build Coastguard Worker public:
3010*35238bceSAndroid Build Coastguard Worker typedef Func<Signature<T, T, T>> ScalarFunc;
3011*35238bceSAndroid Build Coastguard Worker
getName(void) const3012*35238bceSAndroid Build Coastguard Worker string getName(void) const
3013*35238bceSAndroid Build Coastguard Worker {
3014*35238bceSAndroid Build Coastguard Worker return doGetScalarFunc().getName();
3015*35238bceSAndroid Build Coastguard Worker }
3016*35238bceSAndroid Build Coastguard Worker
3017*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os,const BaseArgExprs & args) const3018*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
3019*35238bceSAndroid Build Coastguard Worker {
3020*35238bceSAndroid Build Coastguard Worker doGetScalarFunc().print(os, args);
3021*35238bceSAndroid Build Coastguard Worker }
3022*35238bceSAndroid Build Coastguard Worker
3023*35238bceSAndroid Build Coastguard Worker virtual const ScalarFunc &doGetScalarFunc(void) const = 0;
3024*35238bceSAndroid Build Coastguard Worker };
3025*35238bceSAndroid Build Coastguard Worker
3026*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
3027*35238bceSAndroid Build Coastguard Worker class CompMatFuncBase
3028*35238bceSAndroid Build Coastguard Worker : public CompWiseFunc<float,
3029*35238bceSAndroid Build Coastguard Worker Signature<Matrix<float, Rows, Cols>, Matrix<float, Rows, Cols>, Matrix<float, Rows, Cols>>>
3030*35238bceSAndroid Build Coastguard Worker {
3031*35238bceSAndroid Build Coastguard Worker public:
3032*35238bceSAndroid Build Coastguard Worker typedef typename CompMatFuncBase::IRet IRet;
3033*35238bceSAndroid Build Coastguard Worker typedef typename CompMatFuncBase::IArgs IArgs;
3034*35238bceSAndroid Build Coastguard Worker
3035*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const3036*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
3037*35238bceSAndroid Build Coastguard Worker {
3038*35238bceSAndroid Build Coastguard Worker IRet ret;
3039*35238bceSAndroid Build Coastguard Worker
3040*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < Cols; ++col)
3041*35238bceSAndroid Build Coastguard Worker {
3042*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < Rows; ++row)
3043*35238bceSAndroid Build Coastguard Worker ret[col][row] = this->doGetScalarFunc().apply(ctx, iargs.a[col][row], iargs.b[col][row]);
3044*35238bceSAndroid Build Coastguard Worker }
3045*35238bceSAndroid Build Coastguard Worker
3046*35238bceSAndroid Build Coastguard Worker return ret;
3047*35238bceSAndroid Build Coastguard Worker }
3048*35238bceSAndroid Build Coastguard Worker };
3049*35238bceSAndroid Build Coastguard Worker
3050*35238bceSAndroid Build Coastguard Worker template <typename F, int Rows, int Cols>
3051*35238bceSAndroid Build Coastguard Worker class CompMatFunc : public CompMatFuncBase<Rows, Cols>
3052*35238bceSAndroid Build Coastguard Worker {
3053*35238bceSAndroid Build Coastguard Worker protected:
doGetScalarFunc(void) const3054*35238bceSAndroid Build Coastguard Worker const typename CompMatFunc::ScalarFunc &doGetScalarFunc(void) const
3055*35238bceSAndroid Build Coastguard Worker {
3056*35238bceSAndroid Build Coastguard Worker return instance<F>();
3057*35238bceSAndroid Build Coastguard Worker }
3058*35238bceSAndroid Build Coastguard Worker };
3059*35238bceSAndroid Build Coastguard Worker
3060*35238bceSAndroid Build Coastguard Worker class ScalarMatrixCompMult : public Mul
3061*35238bceSAndroid Build Coastguard Worker {
3062*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3063*35238bceSAndroid Build Coastguard Worker string getName(void) const
3064*35238bceSAndroid Build Coastguard Worker {
3065*35238bceSAndroid Build Coastguard Worker return "matrixCompMult";
3066*35238bceSAndroid Build Coastguard Worker }
3067*35238bceSAndroid Build Coastguard Worker
doPrint(ostream & os,const BaseArgExprs & args) const3068*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
3069*35238bceSAndroid Build Coastguard Worker {
3070*35238bceSAndroid Build Coastguard Worker Func<Sig>::doPrint(os, args);
3071*35238bceSAndroid Build Coastguard Worker }
3072*35238bceSAndroid Build Coastguard Worker };
3073*35238bceSAndroid Build Coastguard Worker
3074*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
3075*35238bceSAndroid Build Coastguard Worker class MatrixCompMult : public CompMatFunc<ScalarMatrixCompMult, Rows, Cols>
3076*35238bceSAndroid Build Coastguard Worker {
3077*35238bceSAndroid Build Coastguard Worker };
3078*35238bceSAndroid Build Coastguard Worker
3079*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
3080*35238bceSAndroid Build Coastguard Worker class ScalarMatFuncBase
3081*35238bceSAndroid Build Coastguard Worker : public CompWiseFunc<float, Signature<Matrix<float, Rows, Cols>, Matrix<float, Rows, Cols>, float>>
3082*35238bceSAndroid Build Coastguard Worker {
3083*35238bceSAndroid Build Coastguard Worker public:
3084*35238bceSAndroid Build Coastguard Worker typedef typename ScalarMatFuncBase::IRet IRet;
3085*35238bceSAndroid Build Coastguard Worker typedef typename ScalarMatFuncBase::IArgs IArgs;
3086*35238bceSAndroid Build Coastguard Worker
3087*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const3088*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
3089*35238bceSAndroid Build Coastguard Worker {
3090*35238bceSAndroid Build Coastguard Worker IRet ret;
3091*35238bceSAndroid Build Coastguard Worker
3092*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < Cols; ++col)
3093*35238bceSAndroid Build Coastguard Worker {
3094*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < Rows; ++row)
3095*35238bceSAndroid Build Coastguard Worker ret[col][row] = this->doGetScalarFunc().apply(ctx, iargs.a[col][row], iargs.b);
3096*35238bceSAndroid Build Coastguard Worker }
3097*35238bceSAndroid Build Coastguard Worker
3098*35238bceSAndroid Build Coastguard Worker return ret;
3099*35238bceSAndroid Build Coastguard Worker }
3100*35238bceSAndroid Build Coastguard Worker };
3101*35238bceSAndroid Build Coastguard Worker
3102*35238bceSAndroid Build Coastguard Worker template <typename F, int Rows, int Cols>
3103*35238bceSAndroid Build Coastguard Worker class ScalarMatFunc : public ScalarMatFuncBase<Rows, Cols>
3104*35238bceSAndroid Build Coastguard Worker {
3105*35238bceSAndroid Build Coastguard Worker protected:
doGetScalarFunc(void) const3106*35238bceSAndroid Build Coastguard Worker const typename ScalarMatFunc::ScalarFunc &doGetScalarFunc(void) const
3107*35238bceSAndroid Build Coastguard Worker {
3108*35238bceSAndroid Build Coastguard Worker return instance<F>();
3109*35238bceSAndroid Build Coastguard Worker }
3110*35238bceSAndroid Build Coastguard Worker };
3111*35238bceSAndroid Build Coastguard Worker
3112*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
3113*35238bceSAndroid Build Coastguard Worker struct GenXType;
3114*35238bceSAndroid Build Coastguard Worker
3115*35238bceSAndroid Build Coastguard Worker template <typename T>
3116*35238bceSAndroid Build Coastguard Worker struct GenXType<T, 1>
3117*35238bceSAndroid Build Coastguard Worker {
genXTypedeqp::gls::BuiltinPrecisionTests::Functions::GenXType3118*35238bceSAndroid Build Coastguard Worker static ExprP<T> genXType(const ExprP<T> &x)
3119*35238bceSAndroid Build Coastguard Worker {
3120*35238bceSAndroid Build Coastguard Worker return x;
3121*35238bceSAndroid Build Coastguard Worker }
3122*35238bceSAndroid Build Coastguard Worker };
3123*35238bceSAndroid Build Coastguard Worker
3124*35238bceSAndroid Build Coastguard Worker template <typename T>
3125*35238bceSAndroid Build Coastguard Worker struct GenXType<T, 2>
3126*35238bceSAndroid Build Coastguard Worker {
genXTypedeqp::gls::BuiltinPrecisionTests::Functions::GenXType3127*35238bceSAndroid Build Coastguard Worker static ExprP<Vector<T, 2>> genXType(const ExprP<T> &x)
3128*35238bceSAndroid Build Coastguard Worker {
3129*35238bceSAndroid Build Coastguard Worker return app<GenVec<T, 2>>(x, x);
3130*35238bceSAndroid Build Coastguard Worker }
3131*35238bceSAndroid Build Coastguard Worker };
3132*35238bceSAndroid Build Coastguard Worker
3133*35238bceSAndroid Build Coastguard Worker template <typename T>
3134*35238bceSAndroid Build Coastguard Worker struct GenXType<T, 3>
3135*35238bceSAndroid Build Coastguard Worker {
genXTypedeqp::gls::BuiltinPrecisionTests::Functions::GenXType3136*35238bceSAndroid Build Coastguard Worker static ExprP<Vector<T, 3>> genXType(const ExprP<T> &x)
3137*35238bceSAndroid Build Coastguard Worker {
3138*35238bceSAndroid Build Coastguard Worker return app<GenVec<T, 3>>(x, x, x);
3139*35238bceSAndroid Build Coastguard Worker }
3140*35238bceSAndroid Build Coastguard Worker };
3141*35238bceSAndroid Build Coastguard Worker
3142*35238bceSAndroid Build Coastguard Worker template <typename T>
3143*35238bceSAndroid Build Coastguard Worker struct GenXType<T, 4>
3144*35238bceSAndroid Build Coastguard Worker {
genXTypedeqp::gls::BuiltinPrecisionTests::Functions::GenXType3145*35238bceSAndroid Build Coastguard Worker static ExprP<Vector<T, 4>> genXType(const ExprP<T> &x)
3146*35238bceSAndroid Build Coastguard Worker {
3147*35238bceSAndroid Build Coastguard Worker return app<GenVec<T, 4>>(x, x, x, x);
3148*35238bceSAndroid Build Coastguard Worker }
3149*35238bceSAndroid Build Coastguard Worker };
3150*35238bceSAndroid Build Coastguard Worker
3151*35238bceSAndroid Build Coastguard Worker //! Returns an expression of vector of size `Size` (or scalar if Size == 1),
3152*35238bceSAndroid Build Coastguard Worker //! with each element initialized with the expression `x`.
3153*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
genXType(const ExprP<T> & x)3154*35238bceSAndroid Build Coastguard Worker ExprP<typename ContainerOf<T, Size>::Container> genXType(const ExprP<T> &x)
3155*35238bceSAndroid Build Coastguard Worker {
3156*35238bceSAndroid Build Coastguard Worker return GenXType<T, Size>::genXType(x);
3157*35238bceSAndroid Build Coastguard Worker }
3158*35238bceSAndroid Build Coastguard Worker
3159*35238bceSAndroid Build Coastguard Worker typedef GenVec<float, 2> FloatVec2;
3160*35238bceSAndroid Build Coastguard Worker DEFINE_CONSTRUCTOR2(FloatVec2, Vec2, vec2, float, float)
3161*35238bceSAndroid Build Coastguard Worker
3162*35238bceSAndroid Build Coastguard Worker typedef GenVec<float, 3> FloatVec3;
3163*35238bceSAndroid Build Coastguard Worker DEFINE_CONSTRUCTOR3(FloatVec3, Vec3, vec3, float, float, float)
3164*35238bceSAndroid Build Coastguard Worker
3165*35238bceSAndroid Build Coastguard Worker typedef GenVec<float, 4> FloatVec4;
3166*35238bceSAndroid Build Coastguard Worker DEFINE_CONSTRUCTOR4(FloatVec4, Vec4, vec4, float, float, float, float)
3167*35238bceSAndroid Build Coastguard Worker
3168*35238bceSAndroid Build Coastguard Worker template <int Size>
3169*35238bceSAndroid Build Coastguard Worker class Dot : public DerivedFunc<Signature<float, Vector<float, Size>, Vector<float, Size>>>
3170*35238bceSAndroid Build Coastguard Worker {
3171*35238bceSAndroid Build Coastguard Worker public:
3172*35238bceSAndroid Build Coastguard Worker typedef typename Dot::ArgExprs ArgExprs;
3173*35238bceSAndroid Build Coastguard Worker
getName(void) const3174*35238bceSAndroid Build Coastguard Worker string getName(void) const
3175*35238bceSAndroid Build Coastguard Worker {
3176*35238bceSAndroid Build Coastguard Worker return "dot";
3177*35238bceSAndroid Build Coastguard Worker }
3178*35238bceSAndroid Build Coastguard Worker
3179*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const3180*35238bceSAndroid Build Coastguard Worker ExprP<float> doExpand(ExpandContext &, const ArgExprs &args) const
3181*35238bceSAndroid Build Coastguard Worker {
3182*35238bceSAndroid Build Coastguard Worker ExprP<float> op[Size];
3183*35238bceSAndroid Build Coastguard Worker // Precompute all products.
3184*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ++ndx)
3185*35238bceSAndroid Build Coastguard Worker op[ndx] = args.a[ndx] * args.b[ndx];
3186*35238bceSAndroid Build Coastguard Worker
3187*35238bceSAndroid Build Coastguard Worker int idx[Size];
3188*35238bceSAndroid Build Coastguard Worker //Prepare an array of indices.
3189*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ++ndx)
3190*35238bceSAndroid Build Coastguard Worker idx[ndx] = ndx;
3191*35238bceSAndroid Build Coastguard Worker
3192*35238bceSAndroid Build Coastguard Worker ExprP<float> res = op[0];
3193*35238bceSAndroid Build Coastguard Worker // Compute the first dot alternative: SUM(a[i]*b[i]), i = 0 .. Size-1
3194*35238bceSAndroid Build Coastguard Worker for (int ndx = 1; ndx < Size; ++ndx)
3195*35238bceSAndroid Build Coastguard Worker res = res + op[ndx];
3196*35238bceSAndroid Build Coastguard Worker
3197*35238bceSAndroid Build Coastguard Worker // Generate all permutations of indices and
3198*35238bceSAndroid Build Coastguard Worker // using a permutation compute a dot alternative.
3199*35238bceSAndroid Build Coastguard Worker // Generates all possible variants fo summation of products in the dot product expansion expression.
3200*35238bceSAndroid Build Coastguard Worker do
3201*35238bceSAndroid Build Coastguard Worker {
3202*35238bceSAndroid Build Coastguard Worker ExprP<float> alt = constant(0.0f);
3203*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ++ndx)
3204*35238bceSAndroid Build Coastguard Worker alt = alt + op[idx[ndx]];
3205*35238bceSAndroid Build Coastguard Worker res = alternatives(res, alt);
3206*35238bceSAndroid Build Coastguard Worker } while (std::next_permutation(idx, idx + Size));
3207*35238bceSAndroid Build Coastguard Worker
3208*35238bceSAndroid Build Coastguard Worker return res;
3209*35238bceSAndroid Build Coastguard Worker }
3210*35238bceSAndroid Build Coastguard Worker };
3211*35238bceSAndroid Build Coastguard Worker
3212*35238bceSAndroid Build Coastguard Worker template <>
3213*35238bceSAndroid Build Coastguard Worker class Dot<1> : public DerivedFunc<Signature<float, float, float>>
3214*35238bceSAndroid Build Coastguard Worker {
3215*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3216*35238bceSAndroid Build Coastguard Worker string getName(void) const
3217*35238bceSAndroid Build Coastguard Worker {
3218*35238bceSAndroid Build Coastguard Worker return "dot";
3219*35238bceSAndroid Build Coastguard Worker }
3220*35238bceSAndroid Build Coastguard Worker
doExpand(ExpandContext &,const ArgExprs & args) const3221*35238bceSAndroid Build Coastguard Worker ExprP<float> doExpand(ExpandContext &, const ArgExprs &args) const
3222*35238bceSAndroid Build Coastguard Worker {
3223*35238bceSAndroid Build Coastguard Worker return args.a * args.b;
3224*35238bceSAndroid Build Coastguard Worker }
3225*35238bceSAndroid Build Coastguard Worker };
3226*35238bceSAndroid Build Coastguard Worker
3227*35238bceSAndroid Build Coastguard Worker template <int Size>
dot(const ExprP<Vector<float,Size>> & x,const ExprP<Vector<float,Size>> & y)3228*35238bceSAndroid Build Coastguard Worker ExprP<float> dot(const ExprP<Vector<float, Size>> &x, const ExprP<Vector<float, Size>> &y)
3229*35238bceSAndroid Build Coastguard Worker {
3230*35238bceSAndroid Build Coastguard Worker return app<Dot<Size>>(x, y);
3231*35238bceSAndroid Build Coastguard Worker }
3232*35238bceSAndroid Build Coastguard Worker
dot(const ExprP<float> & x,const ExprP<float> & y)3233*35238bceSAndroid Build Coastguard Worker ExprP<float> dot(const ExprP<float> &x, const ExprP<float> &y)
3234*35238bceSAndroid Build Coastguard Worker {
3235*35238bceSAndroid Build Coastguard Worker return app<Dot<1>>(x, y);
3236*35238bceSAndroid Build Coastguard Worker }
3237*35238bceSAndroid Build Coastguard Worker
3238*35238bceSAndroid Build Coastguard Worker template <int Size>
3239*35238bceSAndroid Build Coastguard Worker class Length : public DerivedFunc<Signature<float, typename ContainerOf<float, Size>::Container>>
3240*35238bceSAndroid Build Coastguard Worker {
3241*35238bceSAndroid Build Coastguard Worker public:
3242*35238bceSAndroid Build Coastguard Worker typedef typename Length::ArgExprs ArgExprs;
3243*35238bceSAndroid Build Coastguard Worker
getName(void) const3244*35238bceSAndroid Build Coastguard Worker string getName(void) const
3245*35238bceSAndroid Build Coastguard Worker {
3246*35238bceSAndroid Build Coastguard Worker return "length";
3247*35238bceSAndroid Build Coastguard Worker }
3248*35238bceSAndroid Build Coastguard Worker
3249*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const3250*35238bceSAndroid Build Coastguard Worker ExprP<float> doExpand(ExpandContext &, const ArgExprs &args) const
3251*35238bceSAndroid Build Coastguard Worker {
3252*35238bceSAndroid Build Coastguard Worker return sqrt(dot(args.a, args.a));
3253*35238bceSAndroid Build Coastguard Worker }
3254*35238bceSAndroid Build Coastguard Worker };
3255*35238bceSAndroid Build Coastguard Worker
3256*35238bceSAndroid Build Coastguard Worker template <int Size>
length(const ExprP<typename ContainerOf<float,Size>::Container> & x)3257*35238bceSAndroid Build Coastguard Worker ExprP<float> length(const ExprP<typename ContainerOf<float, Size>::Container> &x)
3258*35238bceSAndroid Build Coastguard Worker {
3259*35238bceSAndroid Build Coastguard Worker return app<Length<Size>>(x);
3260*35238bceSAndroid Build Coastguard Worker }
3261*35238bceSAndroid Build Coastguard Worker
3262*35238bceSAndroid Build Coastguard Worker template <int Size>
3263*35238bceSAndroid Build Coastguard Worker class Distance
3264*35238bceSAndroid Build Coastguard Worker : public DerivedFunc<
3265*35238bceSAndroid Build Coastguard Worker Signature<float, typename ContainerOf<float, Size>::Container, typename ContainerOf<float, Size>::Container>>
3266*35238bceSAndroid Build Coastguard Worker {
3267*35238bceSAndroid Build Coastguard Worker public:
3268*35238bceSAndroid Build Coastguard Worker typedef typename Distance::Ret Ret;
3269*35238bceSAndroid Build Coastguard Worker typedef typename Distance::ArgExprs ArgExprs;
3270*35238bceSAndroid Build Coastguard Worker
getName(void) const3271*35238bceSAndroid Build Coastguard Worker string getName(void) const
3272*35238bceSAndroid Build Coastguard Worker {
3273*35238bceSAndroid Build Coastguard Worker return "distance";
3274*35238bceSAndroid Build Coastguard Worker }
3275*35238bceSAndroid Build Coastguard Worker
3276*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const3277*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &, const ArgExprs &args) const
3278*35238bceSAndroid Build Coastguard Worker {
3279*35238bceSAndroid Build Coastguard Worker return length<Size>(args.a - args.b);
3280*35238bceSAndroid Build Coastguard Worker }
3281*35238bceSAndroid Build Coastguard Worker };
3282*35238bceSAndroid Build Coastguard Worker
3283*35238bceSAndroid Build Coastguard Worker // cross
3284*35238bceSAndroid Build Coastguard Worker
3285*35238bceSAndroid Build Coastguard Worker class Cross : public DerivedFunc<Signature<Vec3, Vec3, Vec3>>
3286*35238bceSAndroid Build Coastguard Worker {
3287*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3288*35238bceSAndroid Build Coastguard Worker string getName(void) const
3289*35238bceSAndroid Build Coastguard Worker {
3290*35238bceSAndroid Build Coastguard Worker return "cross";
3291*35238bceSAndroid Build Coastguard Worker }
3292*35238bceSAndroid Build Coastguard Worker
3293*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & x) const3294*35238bceSAndroid Build Coastguard Worker ExprP<Vec3> doExpand(ExpandContext &, const ArgExprs &x) const
3295*35238bceSAndroid Build Coastguard Worker {
3296*35238bceSAndroid Build Coastguard Worker return vec3(x.a[1] * x.b[2] - x.b[1] * x.a[2], x.a[2] * x.b[0] - x.b[2] * x.a[0],
3297*35238bceSAndroid Build Coastguard Worker x.a[0] * x.b[1] - x.b[0] * x.a[1]);
3298*35238bceSAndroid Build Coastguard Worker }
3299*35238bceSAndroid Build Coastguard Worker };
3300*35238bceSAndroid Build Coastguard Worker
3301*35238bceSAndroid Build Coastguard Worker DEFINE_CONSTRUCTOR2(Cross, Vec3, cross, Vec3, Vec3)
3302*35238bceSAndroid Build Coastguard Worker
3303*35238bceSAndroid Build Coastguard Worker template <int Size>
3304*35238bceSAndroid Build Coastguard Worker class Normalize
3305*35238bceSAndroid Build Coastguard Worker : public DerivedFunc<
3306*35238bceSAndroid Build Coastguard Worker Signature<typename ContainerOf<float, Size>::Container, typename ContainerOf<float, Size>::Container>>
3307*35238bceSAndroid Build Coastguard Worker {
3308*35238bceSAndroid Build Coastguard Worker public:
3309*35238bceSAndroid Build Coastguard Worker typedef typename Normalize::Ret Ret;
3310*35238bceSAndroid Build Coastguard Worker typedef typename Normalize::ArgExprs ArgExprs;
3311*35238bceSAndroid Build Coastguard Worker
getName(void) const3312*35238bceSAndroid Build Coastguard Worker string getName(void) const
3313*35238bceSAndroid Build Coastguard Worker {
3314*35238bceSAndroid Build Coastguard Worker return "normalize";
3315*35238bceSAndroid Build Coastguard Worker }
3316*35238bceSAndroid Build Coastguard Worker
3317*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const3318*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &, const ArgExprs &args) const
3319*35238bceSAndroid Build Coastguard Worker {
3320*35238bceSAndroid Build Coastguard Worker return args.a / length<Size>(args.a);
3321*35238bceSAndroid Build Coastguard Worker }
3322*35238bceSAndroid Build Coastguard Worker };
3323*35238bceSAndroid Build Coastguard Worker
3324*35238bceSAndroid Build Coastguard Worker template <int Size>
3325*35238bceSAndroid Build Coastguard Worker class FaceForward
3326*35238bceSAndroid Build Coastguard Worker : public DerivedFunc<
3327*35238bceSAndroid Build Coastguard Worker Signature<typename ContainerOf<float, Size>::Container, typename ContainerOf<float, Size>::Container,
3328*35238bceSAndroid Build Coastguard Worker typename ContainerOf<float, Size>::Container, typename ContainerOf<float, Size>::Container>>
3329*35238bceSAndroid Build Coastguard Worker {
3330*35238bceSAndroid Build Coastguard Worker public:
3331*35238bceSAndroid Build Coastguard Worker typedef typename FaceForward::Ret Ret;
3332*35238bceSAndroid Build Coastguard Worker typedef typename FaceForward::ArgExprs ArgExprs;
3333*35238bceSAndroid Build Coastguard Worker
getName(void) const3334*35238bceSAndroid Build Coastguard Worker string getName(void) const
3335*35238bceSAndroid Build Coastguard Worker {
3336*35238bceSAndroid Build Coastguard Worker return "faceforward";
3337*35238bceSAndroid Build Coastguard Worker }
3338*35238bceSAndroid Build Coastguard Worker
3339*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const3340*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &, const ArgExprs &args) const
3341*35238bceSAndroid Build Coastguard Worker {
3342*35238bceSAndroid Build Coastguard Worker return cond(dot(args.c, args.b) < constant(0.0f), args.a, -args.a);
3343*35238bceSAndroid Build Coastguard Worker }
3344*35238bceSAndroid Build Coastguard Worker };
3345*35238bceSAndroid Build Coastguard Worker
3346*35238bceSAndroid Build Coastguard Worker template <int Size, typename Ret, typename Arg0, typename Arg1>
3347*35238bceSAndroid Build Coastguard Worker struct ApplyReflect
3348*35238bceSAndroid Build Coastguard Worker {
applydeqp::gls::BuiltinPrecisionTests::Functions::ApplyReflect3349*35238bceSAndroid Build Coastguard Worker static ExprP<Ret> apply(ExpandContext &ctx, const ExprP<Arg0> &i, const ExprP<Arg1> &n)
3350*35238bceSAndroid Build Coastguard Worker {
3351*35238bceSAndroid Build Coastguard Worker const ExprP<float> dotNI = bindExpression("dotNI", ctx, dot(n, i));
3352*35238bceSAndroid Build Coastguard Worker
3353*35238bceSAndroid Build Coastguard Worker return i - alternatives((n * dotNI) * constant(2.0f), n * (dotNI * constant(2.0f)));
3354*35238bceSAndroid Build Coastguard Worker }
3355*35238bceSAndroid Build Coastguard Worker };
3356*35238bceSAndroid Build Coastguard Worker
3357*35238bceSAndroid Build Coastguard Worker template <typename Ret, typename Arg0, typename Arg1>
3358*35238bceSAndroid Build Coastguard Worker struct ApplyReflect<1, Ret, Arg0, Arg1>
3359*35238bceSAndroid Build Coastguard Worker {
applydeqp::gls::BuiltinPrecisionTests::Functions::ApplyReflect3360*35238bceSAndroid Build Coastguard Worker static ExprP<Ret> apply(ExpandContext &, const ExprP<Arg0> &i, const ExprP<Arg1> &n)
3361*35238bceSAndroid Build Coastguard Worker {
3362*35238bceSAndroid Build Coastguard Worker return i - alternatives(alternatives((n * (n * i)) * constant(2.0f), n * ((n * i) * constant(2.0f))),
3363*35238bceSAndroid Build Coastguard Worker (n * n) * (i * constant(2.0f)));
3364*35238bceSAndroid Build Coastguard Worker }
3365*35238bceSAndroid Build Coastguard Worker };
3366*35238bceSAndroid Build Coastguard Worker
3367*35238bceSAndroid Build Coastguard Worker template <int Size>
3368*35238bceSAndroid Build Coastguard Worker class Reflect
3369*35238bceSAndroid Build Coastguard Worker : public DerivedFunc<
3370*35238bceSAndroid Build Coastguard Worker Signature<typename ContainerOf<float, Size>::Container, typename ContainerOf<float, Size>::Container,
3371*35238bceSAndroid Build Coastguard Worker typename ContainerOf<float, Size>::Container>>
3372*35238bceSAndroid Build Coastguard Worker {
3373*35238bceSAndroid Build Coastguard Worker public:
3374*35238bceSAndroid Build Coastguard Worker typedef typename Reflect::Ret Ret;
3375*35238bceSAndroid Build Coastguard Worker typedef typename Reflect::Arg0 Arg0;
3376*35238bceSAndroid Build Coastguard Worker typedef typename Reflect::Arg1 Arg1;
3377*35238bceSAndroid Build Coastguard Worker typedef typename Reflect::ArgExprs ArgExprs;
3378*35238bceSAndroid Build Coastguard Worker
getName(void) const3379*35238bceSAndroid Build Coastguard Worker string getName(void) const
3380*35238bceSAndroid Build Coastguard Worker {
3381*35238bceSAndroid Build Coastguard Worker return "reflect";
3382*35238bceSAndroid Build Coastguard Worker }
3383*35238bceSAndroid Build Coastguard Worker
3384*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext & ctx,const ArgExprs & args) const3385*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args) const
3386*35238bceSAndroid Build Coastguard Worker {
3387*35238bceSAndroid Build Coastguard Worker const ExprP<Arg0> &i = args.a;
3388*35238bceSAndroid Build Coastguard Worker const ExprP<Arg1> &n = args.b;
3389*35238bceSAndroid Build Coastguard Worker
3390*35238bceSAndroid Build Coastguard Worker return ApplyReflect<Size, Ret, Arg0, Arg1>::apply(ctx, i, n);
3391*35238bceSAndroid Build Coastguard Worker }
3392*35238bceSAndroid Build Coastguard Worker };
3393*35238bceSAndroid Build Coastguard Worker
3394*35238bceSAndroid Build Coastguard Worker template <int Size>
3395*35238bceSAndroid Build Coastguard Worker class Refract
3396*35238bceSAndroid Build Coastguard Worker : public DerivedFunc<
3397*35238bceSAndroid Build Coastguard Worker Signature<typename ContainerOf<float, Size>::Container, typename ContainerOf<float, Size>::Container,
3398*35238bceSAndroid Build Coastguard Worker typename ContainerOf<float, Size>::Container, float>>
3399*35238bceSAndroid Build Coastguard Worker {
3400*35238bceSAndroid Build Coastguard Worker public:
3401*35238bceSAndroid Build Coastguard Worker typedef typename Refract::Ret Ret;
3402*35238bceSAndroid Build Coastguard Worker typedef typename Refract::Arg0 Arg0;
3403*35238bceSAndroid Build Coastguard Worker typedef typename Refract::Arg1 Arg1;
3404*35238bceSAndroid Build Coastguard Worker typedef typename Refract::ArgExprs ArgExprs;
3405*35238bceSAndroid Build Coastguard Worker
getName(void) const3406*35238bceSAndroid Build Coastguard Worker string getName(void) const
3407*35238bceSAndroid Build Coastguard Worker {
3408*35238bceSAndroid Build Coastguard Worker return "refract";
3409*35238bceSAndroid Build Coastguard Worker }
3410*35238bceSAndroid Build Coastguard Worker
3411*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext & ctx,const ArgExprs & args) const3412*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args) const
3413*35238bceSAndroid Build Coastguard Worker {
3414*35238bceSAndroid Build Coastguard Worker const ExprP<Arg0> &i = args.a;
3415*35238bceSAndroid Build Coastguard Worker const ExprP<Arg1> &n = args.b;
3416*35238bceSAndroid Build Coastguard Worker const ExprP<float> &eta = args.c;
3417*35238bceSAndroid Build Coastguard Worker const ExprP<float> dotNI = bindExpression("dotNI", ctx, dot(n, i));
3418*35238bceSAndroid Build Coastguard Worker const ExprP<float> k1 =
3419*35238bceSAndroid Build Coastguard Worker bindExpression("k1", ctx, constant(1.0f) - eta * eta * (constant(1.0f) - dotNI * dotNI));
3420*35238bceSAndroid Build Coastguard Worker
3421*35238bceSAndroid Build Coastguard Worker const ExprP<float> k2 =
3422*35238bceSAndroid Build Coastguard Worker bindExpression("k2", ctx, (((dotNI * (-dotNI)) + constant(1.0f)) * eta) * (-eta) + constant(1.0f));
3423*35238bceSAndroid Build Coastguard Worker const ExprP<float> k = bindExpression("k", ctx, alternatives(k1, k2));
3424*35238bceSAndroid Build Coastguard Worker
3425*35238bceSAndroid Build Coastguard Worker return cond(k < constant(0.0f), genXType<float, Size>(constant(0.0f)), i * eta - n * (eta * dotNI + sqrt(k)));
3426*35238bceSAndroid Build Coastguard Worker }
3427*35238bceSAndroid Build Coastguard Worker };
3428*35238bceSAndroid Build Coastguard Worker
3429*35238bceSAndroid Build Coastguard Worker class PreciseFunc1 : public CFloatFunc1
3430*35238bceSAndroid Build Coastguard Worker {
3431*35238bceSAndroid Build Coastguard Worker public:
PreciseFunc1(const string & name,DoubleFunc1 & func)3432*35238bceSAndroid Build Coastguard Worker PreciseFunc1(const string &name, DoubleFunc1 &func) : CFloatFunc1(name, func)
3433*35238bceSAndroid Build Coastguard Worker {
3434*35238bceSAndroid Build Coastguard Worker }
3435*35238bceSAndroid Build Coastguard Worker
3436*35238bceSAndroid Build Coastguard Worker protected:
precision(const EvalContext &,double,double) const3437*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &, double, double) const
3438*35238bceSAndroid Build Coastguard Worker {
3439*35238bceSAndroid Build Coastguard Worker return 0.0;
3440*35238bceSAndroid Build Coastguard Worker }
3441*35238bceSAndroid Build Coastguard Worker };
3442*35238bceSAndroid Build Coastguard Worker
3443*35238bceSAndroid Build Coastguard Worker class Abs : public PreciseFunc1
3444*35238bceSAndroid Build Coastguard Worker {
3445*35238bceSAndroid Build Coastguard Worker public:
Abs(void)3446*35238bceSAndroid Build Coastguard Worker Abs(void) : PreciseFunc1("abs", deAbs)
3447*35238bceSAndroid Build Coastguard Worker {
3448*35238bceSAndroid Build Coastguard Worker }
3449*35238bceSAndroid Build Coastguard Worker };
3450*35238bceSAndroid Build Coastguard Worker
3451*35238bceSAndroid Build Coastguard Worker class Sign : public PreciseFunc1
3452*35238bceSAndroid Build Coastguard Worker {
3453*35238bceSAndroid Build Coastguard Worker public:
Sign(void)3454*35238bceSAndroid Build Coastguard Worker Sign(void) : PreciseFunc1("sign", deSign)
3455*35238bceSAndroid Build Coastguard Worker {
3456*35238bceSAndroid Build Coastguard Worker }
3457*35238bceSAndroid Build Coastguard Worker };
3458*35238bceSAndroid Build Coastguard Worker
3459*35238bceSAndroid Build Coastguard Worker class Floor : public PreciseFunc1
3460*35238bceSAndroid Build Coastguard Worker {
3461*35238bceSAndroid Build Coastguard Worker public:
Floor(void)3462*35238bceSAndroid Build Coastguard Worker Floor(void) : PreciseFunc1("floor", deFloor)
3463*35238bceSAndroid Build Coastguard Worker {
3464*35238bceSAndroid Build Coastguard Worker }
3465*35238bceSAndroid Build Coastguard Worker };
3466*35238bceSAndroid Build Coastguard Worker
3467*35238bceSAndroid Build Coastguard Worker class Trunc : public PreciseFunc1
3468*35238bceSAndroid Build Coastguard Worker {
3469*35238bceSAndroid Build Coastguard Worker public:
Trunc(void)3470*35238bceSAndroid Build Coastguard Worker Trunc(void) : PreciseFunc1("trunc", deTrunc)
3471*35238bceSAndroid Build Coastguard Worker {
3472*35238bceSAndroid Build Coastguard Worker }
3473*35238bceSAndroid Build Coastguard Worker };
3474*35238bceSAndroid Build Coastguard Worker
3475*35238bceSAndroid Build Coastguard Worker class Round : public FloatFunc1
3476*35238bceSAndroid Build Coastguard Worker {
3477*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3478*35238bceSAndroid Build Coastguard Worker string getName(void) const
3479*35238bceSAndroid Build Coastguard Worker {
3480*35238bceSAndroid Build Coastguard Worker return "round";
3481*35238bceSAndroid Build Coastguard Worker }
3482*35238bceSAndroid Build Coastguard Worker
3483*35238bceSAndroid Build Coastguard Worker protected:
applyPoint(const EvalContext &,double x) const3484*35238bceSAndroid Build Coastguard Worker Interval applyPoint(const EvalContext &, double x) const
3485*35238bceSAndroid Build Coastguard Worker {
3486*35238bceSAndroid Build Coastguard Worker double truncated = 0.0;
3487*35238bceSAndroid Build Coastguard Worker const double fract = deModf(x, &truncated);
3488*35238bceSAndroid Build Coastguard Worker Interval ret;
3489*35238bceSAndroid Build Coastguard Worker
3490*35238bceSAndroid Build Coastguard Worker if (fabs(fract) <= 0.5)
3491*35238bceSAndroid Build Coastguard Worker ret |= truncated;
3492*35238bceSAndroid Build Coastguard Worker if (fabs(fract) >= 0.5)
3493*35238bceSAndroid Build Coastguard Worker ret |= truncated + deSign(fract);
3494*35238bceSAndroid Build Coastguard Worker
3495*35238bceSAndroid Build Coastguard Worker return ret;
3496*35238bceSAndroid Build Coastguard Worker }
3497*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext &,double,double) const3498*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &, double, double) const
3499*35238bceSAndroid Build Coastguard Worker {
3500*35238bceSAndroid Build Coastguard Worker return 0.0;
3501*35238bceSAndroid Build Coastguard Worker }
3502*35238bceSAndroid Build Coastguard Worker };
3503*35238bceSAndroid Build Coastguard Worker
3504*35238bceSAndroid Build Coastguard Worker class RoundEven : public PreciseFunc1
3505*35238bceSAndroid Build Coastguard Worker {
3506*35238bceSAndroid Build Coastguard Worker public:
RoundEven(void)3507*35238bceSAndroid Build Coastguard Worker RoundEven(void) : PreciseFunc1("roundEven", deRoundEven)
3508*35238bceSAndroid Build Coastguard Worker {
3509*35238bceSAndroid Build Coastguard Worker }
3510*35238bceSAndroid Build Coastguard Worker };
3511*35238bceSAndroid Build Coastguard Worker
3512*35238bceSAndroid Build Coastguard Worker class Ceil : public PreciseFunc1
3513*35238bceSAndroid Build Coastguard Worker {
3514*35238bceSAndroid Build Coastguard Worker public:
Ceil(void)3515*35238bceSAndroid Build Coastguard Worker Ceil(void) : PreciseFunc1("ceil", deCeil)
3516*35238bceSAndroid Build Coastguard Worker {
3517*35238bceSAndroid Build Coastguard Worker }
3518*35238bceSAndroid Build Coastguard Worker };
3519*35238bceSAndroid Build Coastguard Worker
3520*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT1(Fract, fract, x, x - app<Floor>(x))
3521*35238bceSAndroid Build Coastguard Worker
3522*35238bceSAndroid Build Coastguard Worker class PreciseFunc2 : public CFloatFunc2
3523*35238bceSAndroid Build Coastguard Worker {
3524*35238bceSAndroid Build Coastguard Worker public:
PreciseFunc2(const string & name,DoubleFunc2 & func)3525*35238bceSAndroid Build Coastguard Worker PreciseFunc2(const string &name, DoubleFunc2 &func) : CFloatFunc2(name, func)
3526*35238bceSAndroid Build Coastguard Worker {
3527*35238bceSAndroid Build Coastguard Worker }
3528*35238bceSAndroid Build Coastguard Worker
3529*35238bceSAndroid Build Coastguard Worker protected:
precision(const EvalContext &,double,double,double) const3530*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &, double, double, double) const
3531*35238bceSAndroid Build Coastguard Worker {
3532*35238bceSAndroid Build Coastguard Worker return 0.0;
3533*35238bceSAndroid Build Coastguard Worker }
3534*35238bceSAndroid Build Coastguard Worker };
3535*35238bceSAndroid Build Coastguard Worker
3536*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT2(Mod, mod, x, y, x - y * app<Floor>(x / y))
3537*35238bceSAndroid Build Coastguard Worker
3538*35238bceSAndroid Build Coastguard Worker class Modf : public PrimitiveFunc<Signature<float, float, float>>
3539*35238bceSAndroid Build Coastguard Worker {
3540*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3541*35238bceSAndroid Build Coastguard Worker string getName(void) const
3542*35238bceSAndroid Build Coastguard Worker {
3543*35238bceSAndroid Build Coastguard Worker return "modf";
3544*35238bceSAndroid Build Coastguard Worker }
3545*35238bceSAndroid Build Coastguard Worker
3546*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const3547*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
3548*35238bceSAndroid Build Coastguard Worker {
3549*35238bceSAndroid Build Coastguard Worker Interval fracIV;
3550*35238bceSAndroid Build Coastguard Worker Interval &wholeIV = const_cast<Interval &>(iargs.b);
3551*35238bceSAndroid Build Coastguard Worker double intPart = 0;
3552*35238bceSAndroid Build Coastguard Worker
3553*35238bceSAndroid Build Coastguard Worker TCU_INTERVAL_APPLY_MONOTONE1(fracIV, x, iargs.a, frac, frac = deModf(x, &intPart));
3554*35238bceSAndroid Build Coastguard Worker TCU_INTERVAL_APPLY_MONOTONE1(wholeIV, x, iargs.a, whole, deModf(x, &intPart); whole = intPart);
3555*35238bceSAndroid Build Coastguard Worker
3556*35238bceSAndroid Build Coastguard Worker if (!iargs.a.isFinite(ctx.format.getMaxValue()))
3557*35238bceSAndroid Build Coastguard Worker {
3558*35238bceSAndroid Build Coastguard Worker // Behavior on modf(Inf) not well-defined, allow anything as a fractional part
3559*35238bceSAndroid Build Coastguard Worker // See Khronos bug 13907
3560*35238bceSAndroid Build Coastguard Worker fracIV |= TCU_NAN;
3561*35238bceSAndroid Build Coastguard Worker }
3562*35238bceSAndroid Build Coastguard Worker
3563*35238bceSAndroid Build Coastguard Worker return fracIV;
3564*35238bceSAndroid Build Coastguard Worker }
3565*35238bceSAndroid Build Coastguard Worker
getOutParamIndex(void) const3566*35238bceSAndroid Build Coastguard Worker int getOutParamIndex(void) const
3567*35238bceSAndroid Build Coastguard Worker {
3568*35238bceSAndroid Build Coastguard Worker return 1;
3569*35238bceSAndroid Build Coastguard Worker }
3570*35238bceSAndroid Build Coastguard Worker };
3571*35238bceSAndroid Build Coastguard Worker
compare(const EvalContext & ctx,double x,double y)3572*35238bceSAndroid Build Coastguard Worker int compare(const EvalContext &ctx, double x, double y)
3573*35238bceSAndroid Build Coastguard Worker {
3574*35238bceSAndroid Build Coastguard Worker if (ctx.format.hasSubnormal() != tcu::YES)
3575*35238bceSAndroid Build Coastguard Worker {
3576*35238bceSAndroid Build Coastguard Worker const int minExp = ctx.format.getMinExp();
3577*35238bceSAndroid Build Coastguard Worker const int fractionBits = ctx.format.getFractionBits();
3578*35238bceSAndroid Build Coastguard Worker const double minQuantum = deLdExp(1.0f, minExp - fractionBits);
3579*35238bceSAndroid Build Coastguard Worker const double minNormalized = deLdExp(1.0f, minExp);
3580*35238bceSAndroid Build Coastguard Worker const double maxSubnormal = minNormalized - minQuantum;
3581*35238bceSAndroid Build Coastguard Worker const double minSubnormal = -maxSubnormal;
3582*35238bceSAndroid Build Coastguard Worker
3583*35238bceSAndroid Build Coastguard Worker if (minSubnormal <= x && x <= maxSubnormal && minSubnormal <= y && y <= maxSubnormal)
3584*35238bceSAndroid Build Coastguard Worker return 0;
3585*35238bceSAndroid Build Coastguard Worker }
3586*35238bceSAndroid Build Coastguard Worker
3587*35238bceSAndroid Build Coastguard Worker if (x < y)
3588*35238bceSAndroid Build Coastguard Worker return -1;
3589*35238bceSAndroid Build Coastguard Worker if (y < x)
3590*35238bceSAndroid Build Coastguard Worker return 1;
3591*35238bceSAndroid Build Coastguard Worker return 0;
3592*35238bceSAndroid Build Coastguard Worker }
3593*35238bceSAndroid Build Coastguard Worker
3594*35238bceSAndroid Build Coastguard Worker class MinMaxFunc : public FloatFunc2
3595*35238bceSAndroid Build Coastguard Worker {
3596*35238bceSAndroid Build Coastguard Worker public:
MinMaxFunc(const string & name,int sign)3597*35238bceSAndroid Build Coastguard Worker MinMaxFunc(const string &name, int sign) : m_name(name), m_sign(sign)
3598*35238bceSAndroid Build Coastguard Worker {
3599*35238bceSAndroid Build Coastguard Worker }
3600*35238bceSAndroid Build Coastguard Worker
getName(void) const3601*35238bceSAndroid Build Coastguard Worker string getName(void) const
3602*35238bceSAndroid Build Coastguard Worker {
3603*35238bceSAndroid Build Coastguard Worker return m_name;
3604*35238bceSAndroid Build Coastguard Worker }
3605*35238bceSAndroid Build Coastguard Worker
3606*35238bceSAndroid Build Coastguard Worker protected:
applyPoint(const EvalContext & ctx,double x,double y) const3607*35238bceSAndroid Build Coastguard Worker Interval applyPoint(const EvalContext &ctx, double x, double y) const
3608*35238bceSAndroid Build Coastguard Worker {
3609*35238bceSAndroid Build Coastguard Worker const int cmp = compare(ctx, x, y) * m_sign;
3610*35238bceSAndroid Build Coastguard Worker
3611*35238bceSAndroid Build Coastguard Worker if (cmp > 0)
3612*35238bceSAndroid Build Coastguard Worker return x;
3613*35238bceSAndroid Build Coastguard Worker if (cmp < 0)
3614*35238bceSAndroid Build Coastguard Worker return y;
3615*35238bceSAndroid Build Coastguard Worker
3616*35238bceSAndroid Build Coastguard Worker // An implementation without subnormals may not be able to distinguish
3617*35238bceSAndroid Build Coastguard Worker // between x and y even when they're not equal in host arithmetic.
3618*35238bceSAndroid Build Coastguard Worker return Interval(x, y);
3619*35238bceSAndroid Build Coastguard Worker }
3620*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext &,double,double,double) const3621*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &, double, double, double) const
3622*35238bceSAndroid Build Coastguard Worker {
3623*35238bceSAndroid Build Coastguard Worker return 0.0;
3624*35238bceSAndroid Build Coastguard Worker }
3625*35238bceSAndroid Build Coastguard Worker
3626*35238bceSAndroid Build Coastguard Worker const string m_name;
3627*35238bceSAndroid Build Coastguard Worker const int m_sign;
3628*35238bceSAndroid Build Coastguard Worker };
3629*35238bceSAndroid Build Coastguard Worker
3630*35238bceSAndroid Build Coastguard Worker class Min : public MinMaxFunc
3631*35238bceSAndroid Build Coastguard Worker {
3632*35238bceSAndroid Build Coastguard Worker public:
Min(void)3633*35238bceSAndroid Build Coastguard Worker Min(void) : MinMaxFunc("min", -1)
3634*35238bceSAndroid Build Coastguard Worker {
3635*35238bceSAndroid Build Coastguard Worker }
3636*35238bceSAndroid Build Coastguard Worker };
3637*35238bceSAndroid Build Coastguard Worker class Max : public MinMaxFunc
3638*35238bceSAndroid Build Coastguard Worker {
3639*35238bceSAndroid Build Coastguard Worker public:
Max(void)3640*35238bceSAndroid Build Coastguard Worker Max(void) : MinMaxFunc("max", 1)
3641*35238bceSAndroid Build Coastguard Worker {
3642*35238bceSAndroid Build Coastguard Worker }
3643*35238bceSAndroid Build Coastguard Worker };
3644*35238bceSAndroid Build Coastguard Worker
3645*35238bceSAndroid Build Coastguard Worker class Clamp : public FloatFunc3
3646*35238bceSAndroid Build Coastguard Worker {
3647*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3648*35238bceSAndroid Build Coastguard Worker string getName(void) const
3649*35238bceSAndroid Build Coastguard Worker {
3650*35238bceSAndroid Build Coastguard Worker return "clamp";
3651*35238bceSAndroid Build Coastguard Worker }
3652*35238bceSAndroid Build Coastguard Worker
3653*35238bceSAndroid Build Coastguard Worker protected:
applyPoint(const EvalContext & ctx,double x,double minVal,double maxVal) const3654*35238bceSAndroid Build Coastguard Worker Interval applyPoint(const EvalContext &ctx, double x, double minVal, double maxVal) const
3655*35238bceSAndroid Build Coastguard Worker {
3656*35238bceSAndroid Build Coastguard Worker if (minVal > maxVal)
3657*35238bceSAndroid Build Coastguard Worker return TCU_NAN;
3658*35238bceSAndroid Build Coastguard Worker
3659*35238bceSAndroid Build Coastguard Worker const int cmpMin = compare(ctx, x, minVal);
3660*35238bceSAndroid Build Coastguard Worker const int cmpMax = compare(ctx, x, maxVal);
3661*35238bceSAndroid Build Coastguard Worker const int cmpMinMax = compare(ctx, minVal, maxVal);
3662*35238bceSAndroid Build Coastguard Worker
3663*35238bceSAndroid Build Coastguard Worker if (cmpMin < 0)
3664*35238bceSAndroid Build Coastguard Worker {
3665*35238bceSAndroid Build Coastguard Worker if (cmpMinMax < 0)
3666*35238bceSAndroid Build Coastguard Worker return minVal;
3667*35238bceSAndroid Build Coastguard Worker else
3668*35238bceSAndroid Build Coastguard Worker return Interval(minVal, maxVal);
3669*35238bceSAndroid Build Coastguard Worker }
3670*35238bceSAndroid Build Coastguard Worker if (cmpMax > 0)
3671*35238bceSAndroid Build Coastguard Worker {
3672*35238bceSAndroid Build Coastguard Worker if (cmpMinMax < 0)
3673*35238bceSAndroid Build Coastguard Worker return maxVal;
3674*35238bceSAndroid Build Coastguard Worker else
3675*35238bceSAndroid Build Coastguard Worker return Interval(minVal, maxVal);
3676*35238bceSAndroid Build Coastguard Worker }
3677*35238bceSAndroid Build Coastguard Worker
3678*35238bceSAndroid Build Coastguard Worker Interval result = x;
3679*35238bceSAndroid Build Coastguard Worker if (cmpMin == 0)
3680*35238bceSAndroid Build Coastguard Worker result |= minVal;
3681*35238bceSAndroid Build Coastguard Worker if (cmpMax == 0)
3682*35238bceSAndroid Build Coastguard Worker result |= maxVal;
3683*35238bceSAndroid Build Coastguard Worker return result;
3684*35238bceSAndroid Build Coastguard Worker }
3685*35238bceSAndroid Build Coastguard Worker
precision(const EvalContext &,double,double,double minVal,double maxVal) const3686*35238bceSAndroid Build Coastguard Worker double precision(const EvalContext &, double, double, double minVal, double maxVal) const
3687*35238bceSAndroid Build Coastguard Worker {
3688*35238bceSAndroid Build Coastguard Worker return minVal > maxVal ? TCU_NAN : 0.0;
3689*35238bceSAndroid Build Coastguard Worker }
3690*35238bceSAndroid Build Coastguard Worker };
3691*35238bceSAndroid Build Coastguard Worker
clamp(const ExprP<float> & x,const ExprP<float> & minVal,const ExprP<float> & maxVal)3692*35238bceSAndroid Build Coastguard Worker ExprP<float> clamp(const ExprP<float> &x, const ExprP<float> &minVal, const ExprP<float> &maxVal)
3693*35238bceSAndroid Build Coastguard Worker {
3694*35238bceSAndroid Build Coastguard Worker return app<Clamp>(x, minVal, maxVal);
3695*35238bceSAndroid Build Coastguard Worker }
3696*35238bceSAndroid Build Coastguard Worker
3697*35238bceSAndroid Build Coastguard Worker DEFINE_DERIVED_FLOAT3(Mix, mix, x, y, a, alternatives((x * (constant(1.0f) - a)) + y * a, x + (y - x) * a))
3698*35238bceSAndroid Build Coastguard Worker
step(double edge,double x)3699*35238bceSAndroid Build Coastguard Worker static double step(double edge, double x)
3700*35238bceSAndroid Build Coastguard Worker {
3701*35238bceSAndroid Build Coastguard Worker return x < edge ? 0.0 : 1.0;
3702*35238bceSAndroid Build Coastguard Worker }
3703*35238bceSAndroid Build Coastguard Worker
3704*35238bceSAndroid Build Coastguard Worker class Step : public PreciseFunc2
3705*35238bceSAndroid Build Coastguard Worker {
3706*35238bceSAndroid Build Coastguard Worker public:
Step(void)3707*35238bceSAndroid Build Coastguard Worker Step(void) : PreciseFunc2("step", step)
3708*35238bceSAndroid Build Coastguard Worker {
3709*35238bceSAndroid Build Coastguard Worker }
3710*35238bceSAndroid Build Coastguard Worker };
3711*35238bceSAndroid Build Coastguard Worker
3712*35238bceSAndroid Build Coastguard Worker class SmoothStep : public DerivedFunc<Signature<float, float, float, float>>
3713*35238bceSAndroid Build Coastguard Worker {
3714*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3715*35238bceSAndroid Build Coastguard Worker string getName(void) const
3716*35238bceSAndroid Build Coastguard Worker {
3717*35238bceSAndroid Build Coastguard Worker return "smoothstep";
3718*35238bceSAndroid Build Coastguard Worker }
3719*35238bceSAndroid Build Coastguard Worker
3720*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext & ctx,const ArgExprs & args) const3721*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args) const
3722*35238bceSAndroid Build Coastguard Worker {
3723*35238bceSAndroid Build Coastguard Worker const ExprP<float> &edge0 = args.a;
3724*35238bceSAndroid Build Coastguard Worker const ExprP<float> &edge1 = args.b;
3725*35238bceSAndroid Build Coastguard Worker const ExprP<float> &x = args.c;
3726*35238bceSAndroid Build Coastguard Worker const ExprP<float> tExpr = clamp((x - edge0) / (edge1 - edge0), constant(0.0f), constant(1.0f));
3727*35238bceSAndroid Build Coastguard Worker const ExprP<float> t = bindExpression("t", ctx, tExpr);
3728*35238bceSAndroid Build Coastguard Worker
3729*35238bceSAndroid Build Coastguard Worker return (t * t * (constant(3.0f) - constant(2.0f) * t));
3730*35238bceSAndroid Build Coastguard Worker }
3731*35238bceSAndroid Build Coastguard Worker };
3732*35238bceSAndroid Build Coastguard Worker
3733*35238bceSAndroid Build Coastguard Worker class FrExp : public PrimitiveFunc<Signature<float, float, int>>
3734*35238bceSAndroid Build Coastguard Worker {
3735*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3736*35238bceSAndroid Build Coastguard Worker string getName(void) const
3737*35238bceSAndroid Build Coastguard Worker {
3738*35238bceSAndroid Build Coastguard Worker return "frexp";
3739*35238bceSAndroid Build Coastguard Worker }
3740*35238bceSAndroid Build Coastguard Worker
3741*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const3742*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
3743*35238bceSAndroid Build Coastguard Worker {
3744*35238bceSAndroid Build Coastguard Worker IRet ret;
3745*35238bceSAndroid Build Coastguard Worker const IArg0 &x = iargs.a;
3746*35238bceSAndroid Build Coastguard Worker IArg1 &exponent = const_cast<IArg1 &>(iargs.b);
3747*35238bceSAndroid Build Coastguard Worker
3748*35238bceSAndroid Build Coastguard Worker if (x.hasNaN() || x.contains(TCU_INFINITY) || x.contains(-TCU_INFINITY))
3749*35238bceSAndroid Build Coastguard Worker {
3750*35238bceSAndroid Build Coastguard Worker // GLSL (in contrast to IEEE) says that result of applying frexp
3751*35238bceSAndroid Build Coastguard Worker // to infinity is undefined
3752*35238bceSAndroid Build Coastguard Worker ret = Interval::unbounded() | TCU_NAN;
3753*35238bceSAndroid Build Coastguard Worker exponent = Interval(-deLdExp(1.0, 31), deLdExp(1.0, 31) - 1);
3754*35238bceSAndroid Build Coastguard Worker }
3755*35238bceSAndroid Build Coastguard Worker else if (!x.empty())
3756*35238bceSAndroid Build Coastguard Worker {
3757*35238bceSAndroid Build Coastguard Worker int loExp = 0;
3758*35238bceSAndroid Build Coastguard Worker const double loFrac = deFrExp(x.lo(), &loExp);
3759*35238bceSAndroid Build Coastguard Worker int hiExp = 0;
3760*35238bceSAndroid Build Coastguard Worker const double hiFrac = deFrExp(x.hi(), &hiExp);
3761*35238bceSAndroid Build Coastguard Worker
3762*35238bceSAndroid Build Coastguard Worker if (deSign(loFrac) != deSign(hiFrac))
3763*35238bceSAndroid Build Coastguard Worker {
3764*35238bceSAndroid Build Coastguard Worker exponent = Interval(-TCU_INFINITY, de::max(loExp, hiExp));
3765*35238bceSAndroid Build Coastguard Worker ret = Interval();
3766*35238bceSAndroid Build Coastguard Worker if (deSign(loFrac) < 0)
3767*35238bceSAndroid Build Coastguard Worker ret |= Interval(-1.0 + DBL_EPSILON * 0.5, 0.0);
3768*35238bceSAndroid Build Coastguard Worker if (deSign(hiFrac) > 0)
3769*35238bceSAndroid Build Coastguard Worker ret |= Interval(0.0, 1.0 - DBL_EPSILON * 0.5);
3770*35238bceSAndroid Build Coastguard Worker }
3771*35238bceSAndroid Build Coastguard Worker else
3772*35238bceSAndroid Build Coastguard Worker {
3773*35238bceSAndroid Build Coastguard Worker exponent = Interval(loExp, hiExp);
3774*35238bceSAndroid Build Coastguard Worker if (loExp == hiExp)
3775*35238bceSAndroid Build Coastguard Worker ret = Interval(loFrac, hiFrac);
3776*35238bceSAndroid Build Coastguard Worker else
3777*35238bceSAndroid Build Coastguard Worker ret = deSign(loFrac) * Interval(0.5, 1.0 - DBL_EPSILON * 0.5);
3778*35238bceSAndroid Build Coastguard Worker }
3779*35238bceSAndroid Build Coastguard Worker }
3780*35238bceSAndroid Build Coastguard Worker
3781*35238bceSAndroid Build Coastguard Worker return ret;
3782*35238bceSAndroid Build Coastguard Worker }
3783*35238bceSAndroid Build Coastguard Worker
getOutParamIndex(void) const3784*35238bceSAndroid Build Coastguard Worker int getOutParamIndex(void) const
3785*35238bceSAndroid Build Coastguard Worker {
3786*35238bceSAndroid Build Coastguard Worker return 1;
3787*35238bceSAndroid Build Coastguard Worker }
3788*35238bceSAndroid Build Coastguard Worker };
3789*35238bceSAndroid Build Coastguard Worker
3790*35238bceSAndroid Build Coastguard Worker class LdExp : public PrimitiveFunc<Signature<float, float, int>>
3791*35238bceSAndroid Build Coastguard Worker {
3792*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3793*35238bceSAndroid Build Coastguard Worker string getName(void) const
3794*35238bceSAndroid Build Coastguard Worker {
3795*35238bceSAndroid Build Coastguard Worker return "ldexp";
3796*35238bceSAndroid Build Coastguard Worker }
3797*35238bceSAndroid Build Coastguard Worker
3798*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const3799*35238bceSAndroid Build Coastguard Worker Interval doApply(const EvalContext &ctx, const IArgs &iargs) const
3800*35238bceSAndroid Build Coastguard Worker {
3801*35238bceSAndroid Build Coastguard Worker Interval ret = call<Exp2>(ctx, iargs.b);
3802*35238bceSAndroid Build Coastguard Worker // Khronos bug 11180 consensus: if exp2(exponent) cannot be represented,
3803*35238bceSAndroid Build Coastguard Worker // the result is undefined.
3804*35238bceSAndroid Build Coastguard Worker
3805*35238bceSAndroid Build Coastguard Worker if (ret.contains(TCU_INFINITY) || ret.contains(-TCU_INFINITY))
3806*35238bceSAndroid Build Coastguard Worker ret |= TCU_NAN;
3807*35238bceSAndroid Build Coastguard Worker
3808*35238bceSAndroid Build Coastguard Worker return call<Mul>(ctx, iargs.a, ret);
3809*35238bceSAndroid Build Coastguard Worker }
3810*35238bceSAndroid Build Coastguard Worker };
3811*35238bceSAndroid Build Coastguard Worker
3812*35238bceSAndroid Build Coastguard Worker template <int Rows, int Columns>
3813*35238bceSAndroid Build Coastguard Worker class Transpose : public PrimitiveFunc<Signature<Matrix<float, Rows, Columns>, Matrix<float, Columns, Rows>>>
3814*35238bceSAndroid Build Coastguard Worker {
3815*35238bceSAndroid Build Coastguard Worker public:
3816*35238bceSAndroid Build Coastguard Worker typedef typename Transpose::IRet IRet;
3817*35238bceSAndroid Build Coastguard Worker typedef typename Transpose::IArgs IArgs;
3818*35238bceSAndroid Build Coastguard Worker
getName(void) const3819*35238bceSAndroid Build Coastguard Worker string getName(void) const
3820*35238bceSAndroid Build Coastguard Worker {
3821*35238bceSAndroid Build Coastguard Worker return "transpose";
3822*35238bceSAndroid Build Coastguard Worker }
3823*35238bceSAndroid Build Coastguard Worker
3824*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext &,const IArgs & iargs) const3825*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &, const IArgs &iargs) const
3826*35238bceSAndroid Build Coastguard Worker {
3827*35238bceSAndroid Build Coastguard Worker IRet ret;
3828*35238bceSAndroid Build Coastguard Worker
3829*35238bceSAndroid Build Coastguard Worker for (int rowNdx = 0; rowNdx < Rows; ++rowNdx)
3830*35238bceSAndroid Build Coastguard Worker {
3831*35238bceSAndroid Build Coastguard Worker for (int colNdx = 0; colNdx < Columns; ++colNdx)
3832*35238bceSAndroid Build Coastguard Worker ret(rowNdx, colNdx) = iargs.a(colNdx, rowNdx);
3833*35238bceSAndroid Build Coastguard Worker }
3834*35238bceSAndroid Build Coastguard Worker
3835*35238bceSAndroid Build Coastguard Worker return ret;
3836*35238bceSAndroid Build Coastguard Worker }
3837*35238bceSAndroid Build Coastguard Worker };
3838*35238bceSAndroid Build Coastguard Worker
3839*35238bceSAndroid Build Coastguard Worker template <typename Ret, typename Arg0, typename Arg1>
3840*35238bceSAndroid Build Coastguard Worker class MulFunc : public PrimitiveFunc<Signature<Ret, Arg0, Arg1>>
3841*35238bceSAndroid Build Coastguard Worker {
3842*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3843*35238bceSAndroid Build Coastguard Worker string getName(void) const
3844*35238bceSAndroid Build Coastguard Worker {
3845*35238bceSAndroid Build Coastguard Worker return "mul";
3846*35238bceSAndroid Build Coastguard Worker }
3847*35238bceSAndroid Build Coastguard Worker
3848*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os,const BaseArgExprs & args) const3849*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
3850*35238bceSAndroid Build Coastguard Worker {
3851*35238bceSAndroid Build Coastguard Worker os << "(" << *args[0] << " * " << *args[1] << ")";
3852*35238bceSAndroid Build Coastguard Worker }
3853*35238bceSAndroid Build Coastguard Worker };
3854*35238bceSAndroid Build Coastguard Worker
3855*35238bceSAndroid Build Coastguard Worker template <int LeftRows, int Middle, int RightCols>
3856*35238bceSAndroid Build Coastguard Worker class MatMul : public MulFunc<Matrix<float, LeftRows, RightCols>, Matrix<float, LeftRows, Middle>,
3857*35238bceSAndroid Build Coastguard Worker Matrix<float, Middle, RightCols>>
3858*35238bceSAndroid Build Coastguard Worker {
3859*35238bceSAndroid Build Coastguard Worker protected:
3860*35238bceSAndroid Build Coastguard Worker typedef typename MatMul::IRet IRet;
3861*35238bceSAndroid Build Coastguard Worker typedef typename MatMul::IArgs IArgs;
3862*35238bceSAndroid Build Coastguard Worker typedef typename MatMul::IArg0 IArg0;
3863*35238bceSAndroid Build Coastguard Worker typedef typename MatMul::IArg1 IArg1;
3864*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext & ctx,const IArgs & iargs) const3865*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
3866*35238bceSAndroid Build Coastguard Worker {
3867*35238bceSAndroid Build Coastguard Worker const IArg0 &left = iargs.a;
3868*35238bceSAndroid Build Coastguard Worker const IArg1 &right = iargs.b;
3869*35238bceSAndroid Build Coastguard Worker IRet ret;
3870*35238bceSAndroid Build Coastguard Worker
3871*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < LeftRows; ++row)
3872*35238bceSAndroid Build Coastguard Worker {
3873*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < RightCols; ++col)
3874*35238bceSAndroid Build Coastguard Worker {
3875*35238bceSAndroid Build Coastguard Worker Interval element(0.0);
3876*35238bceSAndroid Build Coastguard Worker
3877*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Middle; ++ndx)
3878*35238bceSAndroid Build Coastguard Worker element = call<Add>(ctx, element, call<Mul>(ctx, left[ndx][row], right[col][ndx]));
3879*35238bceSAndroid Build Coastguard Worker
3880*35238bceSAndroid Build Coastguard Worker ret[col][row] = element;
3881*35238bceSAndroid Build Coastguard Worker }
3882*35238bceSAndroid Build Coastguard Worker }
3883*35238bceSAndroid Build Coastguard Worker
3884*35238bceSAndroid Build Coastguard Worker return ret;
3885*35238bceSAndroid Build Coastguard Worker }
3886*35238bceSAndroid Build Coastguard Worker };
3887*35238bceSAndroid Build Coastguard Worker
3888*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
3889*35238bceSAndroid Build Coastguard Worker class VecMatMul : public MulFunc<Vector<float, Cols>, Vector<float, Rows>, Matrix<float, Rows, Cols>>
3890*35238bceSAndroid Build Coastguard Worker {
3891*35238bceSAndroid Build Coastguard Worker public:
3892*35238bceSAndroid Build Coastguard Worker typedef typename VecMatMul::IRet IRet;
3893*35238bceSAndroid Build Coastguard Worker typedef typename VecMatMul::IArgs IArgs;
3894*35238bceSAndroid Build Coastguard Worker typedef typename VecMatMul::IArg0 IArg0;
3895*35238bceSAndroid Build Coastguard Worker typedef typename VecMatMul::IArg1 IArg1;
3896*35238bceSAndroid Build Coastguard Worker
3897*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const3898*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
3899*35238bceSAndroid Build Coastguard Worker {
3900*35238bceSAndroid Build Coastguard Worker const IArg0 &left = iargs.a;
3901*35238bceSAndroid Build Coastguard Worker const IArg1 &right = iargs.b;
3902*35238bceSAndroid Build Coastguard Worker IRet ret;
3903*35238bceSAndroid Build Coastguard Worker
3904*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < Cols; ++col)
3905*35238bceSAndroid Build Coastguard Worker {
3906*35238bceSAndroid Build Coastguard Worker Interval element(0.0);
3907*35238bceSAndroid Build Coastguard Worker
3908*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < Rows; ++row)
3909*35238bceSAndroid Build Coastguard Worker element = call<Add>(ctx, element, call<Mul>(ctx, left[row], right[col][row]));
3910*35238bceSAndroid Build Coastguard Worker
3911*35238bceSAndroid Build Coastguard Worker ret[col] = element;
3912*35238bceSAndroid Build Coastguard Worker }
3913*35238bceSAndroid Build Coastguard Worker
3914*35238bceSAndroid Build Coastguard Worker return ret;
3915*35238bceSAndroid Build Coastguard Worker }
3916*35238bceSAndroid Build Coastguard Worker };
3917*35238bceSAndroid Build Coastguard Worker
3918*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
3919*35238bceSAndroid Build Coastguard Worker class MatVecMul : public MulFunc<Vector<float, Rows>, Matrix<float, Rows, Cols>, Vector<float, Cols>>
3920*35238bceSAndroid Build Coastguard Worker {
3921*35238bceSAndroid Build Coastguard Worker public:
3922*35238bceSAndroid Build Coastguard Worker typedef typename MatVecMul::IRet IRet;
3923*35238bceSAndroid Build Coastguard Worker typedef typename MatVecMul::IArgs IArgs;
3924*35238bceSAndroid Build Coastguard Worker typedef typename MatVecMul::IArg0 IArg0;
3925*35238bceSAndroid Build Coastguard Worker typedef typename MatVecMul::IArg1 IArg1;
3926*35238bceSAndroid Build Coastguard Worker
3927*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const3928*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
3929*35238bceSAndroid Build Coastguard Worker {
3930*35238bceSAndroid Build Coastguard Worker const IArg0 &left = iargs.a;
3931*35238bceSAndroid Build Coastguard Worker const IArg1 &right = iargs.b;
3932*35238bceSAndroid Build Coastguard Worker
3933*35238bceSAndroid Build Coastguard Worker return call<VecMatMul<Cols, Rows>>(ctx, right, call<Transpose<Rows, Cols>>(ctx, left));
3934*35238bceSAndroid Build Coastguard Worker }
3935*35238bceSAndroid Build Coastguard Worker };
3936*35238bceSAndroid Build Coastguard Worker
3937*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
3938*35238bceSAndroid Build Coastguard Worker class OuterProduct
3939*35238bceSAndroid Build Coastguard Worker : public PrimitiveFunc<Signature<Matrix<float, Rows, Cols>, Vector<float, Rows>, Vector<float, Cols>>>
3940*35238bceSAndroid Build Coastguard Worker {
3941*35238bceSAndroid Build Coastguard Worker public:
3942*35238bceSAndroid Build Coastguard Worker typedef typename OuterProduct::IRet IRet;
3943*35238bceSAndroid Build Coastguard Worker typedef typename OuterProduct::IArgs IArgs;
3944*35238bceSAndroid Build Coastguard Worker
getName(void) const3945*35238bceSAndroid Build Coastguard Worker string getName(void) const
3946*35238bceSAndroid Build Coastguard Worker {
3947*35238bceSAndroid Build Coastguard Worker return "outerProduct";
3948*35238bceSAndroid Build Coastguard Worker }
3949*35238bceSAndroid Build Coastguard Worker
3950*35238bceSAndroid Build Coastguard Worker protected:
doApply(const EvalContext & ctx,const IArgs & iargs) const3951*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
3952*35238bceSAndroid Build Coastguard Worker {
3953*35238bceSAndroid Build Coastguard Worker IRet ret;
3954*35238bceSAndroid Build Coastguard Worker
3955*35238bceSAndroid Build Coastguard Worker for (int row = 0; row < Rows; ++row)
3956*35238bceSAndroid Build Coastguard Worker {
3957*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < Cols; ++col)
3958*35238bceSAndroid Build Coastguard Worker ret[col][row] = call<Mul>(ctx, iargs.a[row], iargs.b[col]);
3959*35238bceSAndroid Build Coastguard Worker }
3960*35238bceSAndroid Build Coastguard Worker
3961*35238bceSAndroid Build Coastguard Worker return ret;
3962*35238bceSAndroid Build Coastguard Worker }
3963*35238bceSAndroid Build Coastguard Worker };
3964*35238bceSAndroid Build Coastguard Worker
3965*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
outerProduct(const ExprP<Vector<float,Rows>> & left,const ExprP<Vector<float,Cols>> & right)3966*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Rows, Cols>> outerProduct(const ExprP<Vector<float, Rows>> &left,
3967*35238bceSAndroid Build Coastguard Worker const ExprP<Vector<float, Cols>> &right)
3968*35238bceSAndroid Build Coastguard Worker {
3969*35238bceSAndroid Build Coastguard Worker return app<OuterProduct<Rows, Cols>>(left, right);
3970*35238bceSAndroid Build Coastguard Worker }
3971*35238bceSAndroid Build Coastguard Worker
3972*35238bceSAndroid Build Coastguard Worker template <int Size>
3973*35238bceSAndroid Build Coastguard Worker class DeterminantBase : public DerivedFunc<Signature<float, Matrix<float, Size, Size>>>
3974*35238bceSAndroid Build Coastguard Worker {
3975*35238bceSAndroid Build Coastguard Worker public:
getName(void) const3976*35238bceSAndroid Build Coastguard Worker string getName(void) const
3977*35238bceSAndroid Build Coastguard Worker {
3978*35238bceSAndroid Build Coastguard Worker return "determinant";
3979*35238bceSAndroid Build Coastguard Worker }
3980*35238bceSAndroid Build Coastguard Worker };
3981*35238bceSAndroid Build Coastguard Worker
3982*35238bceSAndroid Build Coastguard Worker template <int Size>
3983*35238bceSAndroid Build Coastguard Worker class Determinant;
3984*35238bceSAndroid Build Coastguard Worker
3985*35238bceSAndroid Build Coastguard Worker template <int Size>
determinant(ExprP<Matrix<float,Size,Size>> mat)3986*35238bceSAndroid Build Coastguard Worker ExprP<float> determinant(ExprP<Matrix<float, Size, Size>> mat)
3987*35238bceSAndroid Build Coastguard Worker {
3988*35238bceSAndroid Build Coastguard Worker return app<Determinant<Size>>(mat);
3989*35238bceSAndroid Build Coastguard Worker }
3990*35238bceSAndroid Build Coastguard Worker
3991*35238bceSAndroid Build Coastguard Worker template <>
3992*35238bceSAndroid Build Coastguard Worker class Determinant<2> : public DeterminantBase<2>
3993*35238bceSAndroid Build Coastguard Worker {
3994*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const3995*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &, const ArgExprs &args) const
3996*35238bceSAndroid Build Coastguard Worker {
3997*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> mat = args.a;
3998*35238bceSAndroid Build Coastguard Worker
3999*35238bceSAndroid Build Coastguard Worker return mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
4000*35238bceSAndroid Build Coastguard Worker }
4001*35238bceSAndroid Build Coastguard Worker };
4002*35238bceSAndroid Build Coastguard Worker
4003*35238bceSAndroid Build Coastguard Worker template <>
4004*35238bceSAndroid Build Coastguard Worker class Determinant<3> : public DeterminantBase<3>
4005*35238bceSAndroid Build Coastguard Worker {
4006*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & args) const4007*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &, const ArgExprs &args) const
4008*35238bceSAndroid Build Coastguard Worker {
4009*35238bceSAndroid Build Coastguard Worker ExprP<Mat3> mat = args.a;
4010*35238bceSAndroid Build Coastguard Worker
4011*35238bceSAndroid Build Coastguard Worker return (mat[0][0] * (mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]) +
4012*35238bceSAndroid Build Coastguard Worker mat[0][1] * (mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]) +
4013*35238bceSAndroid Build Coastguard Worker mat[0][2] * (mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]));
4014*35238bceSAndroid Build Coastguard Worker }
4015*35238bceSAndroid Build Coastguard Worker };
4016*35238bceSAndroid Build Coastguard Worker
4017*35238bceSAndroid Build Coastguard Worker template <>
4018*35238bceSAndroid Build Coastguard Worker class Determinant<4> : public DeterminantBase<4>
4019*35238bceSAndroid Build Coastguard Worker {
4020*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext & ctx,const ArgExprs & args) const4021*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args) const
4022*35238bceSAndroid Build Coastguard Worker {
4023*35238bceSAndroid Build Coastguard Worker ExprP<Mat4> mat = args.a;
4024*35238bceSAndroid Build Coastguard Worker ExprP<Mat3> minors[4];
4025*35238bceSAndroid Build Coastguard Worker
4026*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < 4; ++ndx)
4027*35238bceSAndroid Build Coastguard Worker {
4028*35238bceSAndroid Build Coastguard Worker ExprP<Vec4> minorColumns[3];
4029*35238bceSAndroid Build Coastguard Worker ExprP<Vec3> columns[3];
4030*35238bceSAndroid Build Coastguard Worker
4031*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < 3; ++col)
4032*35238bceSAndroid Build Coastguard Worker minorColumns[col] = mat[col < ndx ? col : col + 1];
4033*35238bceSAndroid Build Coastguard Worker
4034*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < 3; ++col)
4035*35238bceSAndroid Build Coastguard Worker columns[col] = vec3(minorColumns[0][col + 1], minorColumns[1][col + 1], minorColumns[2][col + 1]);
4036*35238bceSAndroid Build Coastguard Worker
4037*35238bceSAndroid Build Coastguard Worker minors[ndx] = bindExpression("minor", ctx, mat3(columns[0], columns[1], columns[2]));
4038*35238bceSAndroid Build Coastguard Worker }
4039*35238bceSAndroid Build Coastguard Worker
4040*35238bceSAndroid Build Coastguard Worker return (mat[0][0] * determinant(minors[0]) - mat[1][0] * determinant(minors[1]) +
4041*35238bceSAndroid Build Coastguard Worker mat[2][0] * determinant(minors[2]) - mat[3][0] * determinant(minors[3]));
4042*35238bceSAndroid Build Coastguard Worker }
4043*35238bceSAndroid Build Coastguard Worker };
4044*35238bceSAndroid Build Coastguard Worker
4045*35238bceSAndroid Build Coastguard Worker template <int Size>
4046*35238bceSAndroid Build Coastguard Worker class Inverse;
4047*35238bceSAndroid Build Coastguard Worker
4048*35238bceSAndroid Build Coastguard Worker template <int Size>
inverse(ExprP<Matrix<float,Size,Size>> mat)4049*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Size, Size>> inverse(ExprP<Matrix<float, Size, Size>> mat)
4050*35238bceSAndroid Build Coastguard Worker {
4051*35238bceSAndroid Build Coastguard Worker return app<Inverse<Size>>(mat);
4052*35238bceSAndroid Build Coastguard Worker }
4053*35238bceSAndroid Build Coastguard Worker
4054*35238bceSAndroid Build Coastguard Worker template <>
4055*35238bceSAndroid Build Coastguard Worker class Inverse<2> : public DerivedFunc<Signature<Mat2, Mat2>>
4056*35238bceSAndroid Build Coastguard Worker {
4057*35238bceSAndroid Build Coastguard Worker public:
getName(void) const4058*35238bceSAndroid Build Coastguard Worker string getName(void) const
4059*35238bceSAndroid Build Coastguard Worker {
4060*35238bceSAndroid Build Coastguard Worker return "inverse";
4061*35238bceSAndroid Build Coastguard Worker }
4062*35238bceSAndroid Build Coastguard Worker
4063*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext & ctx,const ArgExprs & args) const4064*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args) const
4065*35238bceSAndroid Build Coastguard Worker {
4066*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> mat = args.a;
4067*35238bceSAndroid Build Coastguard Worker ExprP<float> det = bindExpression("det", ctx, determinant(mat));
4068*35238bceSAndroid Build Coastguard Worker
4069*35238bceSAndroid Build Coastguard Worker return mat2(vec2(mat[1][1] / det, -mat[0][1] / det), vec2(-mat[1][0] / det, mat[0][0] / det));
4070*35238bceSAndroid Build Coastguard Worker }
4071*35238bceSAndroid Build Coastguard Worker };
4072*35238bceSAndroid Build Coastguard Worker
4073*35238bceSAndroid Build Coastguard Worker template <>
4074*35238bceSAndroid Build Coastguard Worker class Inverse<3> : public DerivedFunc<Signature<Mat3, Mat3>>
4075*35238bceSAndroid Build Coastguard Worker {
4076*35238bceSAndroid Build Coastguard Worker public:
getName(void) const4077*35238bceSAndroid Build Coastguard Worker string getName(void) const
4078*35238bceSAndroid Build Coastguard Worker {
4079*35238bceSAndroid Build Coastguard Worker return "inverse";
4080*35238bceSAndroid Build Coastguard Worker }
4081*35238bceSAndroid Build Coastguard Worker
4082*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext & ctx,const ArgExprs & args) const4083*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args) const
4084*35238bceSAndroid Build Coastguard Worker {
4085*35238bceSAndroid Build Coastguard Worker ExprP<Mat3> mat = args.a;
4086*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> invA =
4087*35238bceSAndroid Build Coastguard Worker bindExpression("invA", ctx, inverse(mat2(vec2(mat[0][0], mat[0][1]), vec2(mat[1][0], mat[1][1]))));
4088*35238bceSAndroid Build Coastguard Worker
4089*35238bceSAndroid Build Coastguard Worker ExprP<Vec2> matB = bindExpression("matB", ctx, vec2(mat[2][0], mat[2][1]));
4090*35238bceSAndroid Build Coastguard Worker ExprP<Vec2> matC = bindExpression("matC", ctx, vec2(mat[0][2], mat[1][2]));
4091*35238bceSAndroid Build Coastguard Worker ExprP<float> matD = bindExpression("matD", ctx, mat[2][2]);
4092*35238bceSAndroid Build Coastguard Worker
4093*35238bceSAndroid Build Coastguard Worker ExprP<float> schur = bindExpression("schur", ctx, constant(1.0f) / (matD - dot(matC * invA, matB)));
4094*35238bceSAndroid Build Coastguard Worker
4095*35238bceSAndroid Build Coastguard Worker ExprP<Vec2> t1 = invA * matB;
4096*35238bceSAndroid Build Coastguard Worker ExprP<Vec2> t2 = t1 * schur;
4097*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> t3 = outerProduct(t2, matC);
4098*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> t4 = t3 * invA;
4099*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> t5 = invA + t4;
4100*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> blockA = bindExpression("blockA", ctx, t5);
4101*35238bceSAndroid Build Coastguard Worker ExprP<Vec2> blockB = bindExpression("blockB", ctx, (invA * matB) * -schur);
4102*35238bceSAndroid Build Coastguard Worker ExprP<Vec2> blockC = bindExpression("blockC", ctx, (matC * invA) * -schur);
4103*35238bceSAndroid Build Coastguard Worker
4104*35238bceSAndroid Build Coastguard Worker return mat3(vec3(blockA[0][0], blockA[0][1], blockC[0]), vec3(blockA[1][0], blockA[1][1], blockC[1]),
4105*35238bceSAndroid Build Coastguard Worker vec3(blockB[0], blockB[1], schur));
4106*35238bceSAndroid Build Coastguard Worker }
4107*35238bceSAndroid Build Coastguard Worker };
4108*35238bceSAndroid Build Coastguard Worker
4109*35238bceSAndroid Build Coastguard Worker template <>
4110*35238bceSAndroid Build Coastguard Worker class Inverse<4> : public DerivedFunc<Signature<Mat4, Mat4>>
4111*35238bceSAndroid Build Coastguard Worker {
4112*35238bceSAndroid Build Coastguard Worker public:
getName(void) const4113*35238bceSAndroid Build Coastguard Worker string getName(void) const
4114*35238bceSAndroid Build Coastguard Worker {
4115*35238bceSAndroid Build Coastguard Worker return "inverse";
4116*35238bceSAndroid Build Coastguard Worker }
4117*35238bceSAndroid Build Coastguard Worker
4118*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext & ctx,const ArgExprs & args) const4119*35238bceSAndroid Build Coastguard Worker ExprP<Ret> doExpand(ExpandContext &ctx, const ArgExprs &args) const
4120*35238bceSAndroid Build Coastguard Worker {
4121*35238bceSAndroid Build Coastguard Worker ExprP<Mat4> mat = args.a;
4122*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> invA =
4123*35238bceSAndroid Build Coastguard Worker bindExpression("invA", ctx, inverse(mat2(vec2(mat[0][0], mat[0][1]), vec2(mat[1][0], mat[1][1]))));
4124*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> matB = bindExpression("matB", ctx, mat2(vec2(mat[2][0], mat[2][1]), vec2(mat[3][0], mat[3][1])));
4125*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> matC = bindExpression("matC", ctx, mat2(vec2(mat[0][2], mat[0][3]), vec2(mat[1][2], mat[1][3])));
4126*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> matD = bindExpression("matD", ctx, mat2(vec2(mat[2][2], mat[2][3]), vec2(mat[3][2], mat[3][3])));
4127*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> schur = bindExpression("schur", ctx, inverse(matD + -(matC * invA * matB)));
4128*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> blockA = bindExpression("blockA", ctx, invA + (invA * matB * schur * matC * invA));
4129*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> blockB = bindExpression("blockB", ctx, (-invA) * matB * schur);
4130*35238bceSAndroid Build Coastguard Worker ExprP<Mat2> blockC = bindExpression("blockC", ctx, (-schur) * matC * invA);
4131*35238bceSAndroid Build Coastguard Worker
4132*35238bceSAndroid Build Coastguard Worker return mat4(vec4(blockA[0][0], blockA[0][1], blockC[0][0], blockC[0][1]),
4133*35238bceSAndroid Build Coastguard Worker vec4(blockA[1][0], blockA[1][1], blockC[1][0], blockC[1][1]),
4134*35238bceSAndroid Build Coastguard Worker vec4(blockB[0][0], blockB[0][1], schur[0][0], schur[0][1]),
4135*35238bceSAndroid Build Coastguard Worker vec4(blockB[1][0], blockB[1][1], schur[1][0], schur[1][1]));
4136*35238bceSAndroid Build Coastguard Worker }
4137*35238bceSAndroid Build Coastguard Worker };
4138*35238bceSAndroid Build Coastguard Worker
4139*35238bceSAndroid Build Coastguard Worker class Fma : public DerivedFunc<Signature<float, float, float, float>>
4140*35238bceSAndroid Build Coastguard Worker {
4141*35238bceSAndroid Build Coastguard Worker public:
getName(void) const4142*35238bceSAndroid Build Coastguard Worker string getName(void) const
4143*35238bceSAndroid Build Coastguard Worker {
4144*35238bceSAndroid Build Coastguard Worker return "fma";
4145*35238bceSAndroid Build Coastguard Worker }
4146*35238bceSAndroid Build Coastguard Worker
getRequiredExtension(const RenderContext & context) const4147*35238bceSAndroid Build Coastguard Worker string getRequiredExtension(const RenderContext &context) const
4148*35238bceSAndroid Build Coastguard Worker {
4149*35238bceSAndroid Build Coastguard Worker return (glu::contextSupports(context.getType(), glu::ApiType::core(4, 5))) ? "" : "GL_EXT_gpu_shader5";
4150*35238bceSAndroid Build Coastguard Worker }
4151*35238bceSAndroid Build Coastguard Worker
4152*35238bceSAndroid Build Coastguard Worker protected:
doExpand(ExpandContext &,const ArgExprs & x) const4153*35238bceSAndroid Build Coastguard Worker ExprP<float> doExpand(ExpandContext &, const ArgExprs &x) const
4154*35238bceSAndroid Build Coastguard Worker {
4155*35238bceSAndroid Build Coastguard Worker return x.a * x.b + x.c;
4156*35238bceSAndroid Build Coastguard Worker }
4157*35238bceSAndroid Build Coastguard Worker };
4158*35238bceSAndroid Build Coastguard Worker
4159*35238bceSAndroid Build Coastguard Worker } // namespace Functions
4160*35238bceSAndroid Build Coastguard Worker
4161*35238bceSAndroid Build Coastguard Worker using namespace Functions;
4162*35238bceSAndroid Build Coastguard Worker
4163*35238bceSAndroid Build Coastguard Worker template <typename T>
operator [](int i) const4164*35238bceSAndroid Build Coastguard Worker ExprP<typename T::Element> ContainerExprPBase<T>::operator[](int i) const
4165*35238bceSAndroid Build Coastguard Worker {
4166*35238bceSAndroid Build Coastguard Worker return Functions::getComponent(exprP<T>(*this), i);
4167*35238bceSAndroid Build Coastguard Worker }
4168*35238bceSAndroid Build Coastguard Worker
operator +(const ExprP<float> & arg0,const ExprP<float> & arg1)4169*35238bceSAndroid Build Coastguard Worker ExprP<float> operator+(const ExprP<float> &arg0, const ExprP<float> &arg1)
4170*35238bceSAndroid Build Coastguard Worker {
4171*35238bceSAndroid Build Coastguard Worker return app<Add>(arg0, arg1);
4172*35238bceSAndroid Build Coastguard Worker }
4173*35238bceSAndroid Build Coastguard Worker
operator -(const ExprP<float> & arg0,const ExprP<float> & arg1)4174*35238bceSAndroid Build Coastguard Worker ExprP<float> operator-(const ExprP<float> &arg0, const ExprP<float> &arg1)
4175*35238bceSAndroid Build Coastguard Worker {
4176*35238bceSAndroid Build Coastguard Worker return app<Sub>(arg0, arg1);
4177*35238bceSAndroid Build Coastguard Worker }
4178*35238bceSAndroid Build Coastguard Worker
operator -(const ExprP<float> & arg0)4179*35238bceSAndroid Build Coastguard Worker ExprP<float> operator-(const ExprP<float> &arg0)
4180*35238bceSAndroid Build Coastguard Worker {
4181*35238bceSAndroid Build Coastguard Worker return app<Negate>(arg0);
4182*35238bceSAndroid Build Coastguard Worker }
4183*35238bceSAndroid Build Coastguard Worker
operator *(const ExprP<float> & arg0,const ExprP<float> & arg1)4184*35238bceSAndroid Build Coastguard Worker ExprP<float> operator*(const ExprP<float> &arg0, const ExprP<float> &arg1)
4185*35238bceSAndroid Build Coastguard Worker {
4186*35238bceSAndroid Build Coastguard Worker return app<Mul>(arg0, arg1);
4187*35238bceSAndroid Build Coastguard Worker }
4188*35238bceSAndroid Build Coastguard Worker
operator /(const ExprP<float> & arg0,const ExprP<float> & arg1)4189*35238bceSAndroid Build Coastguard Worker ExprP<float> operator/(const ExprP<float> &arg0, const ExprP<float> &arg1)
4190*35238bceSAndroid Build Coastguard Worker {
4191*35238bceSAndroid Build Coastguard Worker return app<Div>(arg0, arg1);
4192*35238bceSAndroid Build Coastguard Worker }
4193*35238bceSAndroid Build Coastguard Worker
4194*35238bceSAndroid Build Coastguard Worker template <typename Sig_, int Size>
4195*35238bceSAndroid Build Coastguard Worker class GenFunc : public PrimitiveFunc<Signature<typename ContainerOf<typename Sig_::Ret, Size>::Container,
4196*35238bceSAndroid Build Coastguard Worker typename ContainerOf<typename Sig_::Arg0, Size>::Container,
4197*35238bceSAndroid Build Coastguard Worker typename ContainerOf<typename Sig_::Arg1, Size>::Container,
4198*35238bceSAndroid Build Coastguard Worker typename ContainerOf<typename Sig_::Arg2, Size>::Container,
4199*35238bceSAndroid Build Coastguard Worker typename ContainerOf<typename Sig_::Arg3, Size>::Container>>
4200*35238bceSAndroid Build Coastguard Worker {
4201*35238bceSAndroid Build Coastguard Worker public:
4202*35238bceSAndroid Build Coastguard Worker typedef typename GenFunc::IArgs IArgs;
4203*35238bceSAndroid Build Coastguard Worker typedef typename GenFunc::IRet IRet;
4204*35238bceSAndroid Build Coastguard Worker
GenFunc(const Func<Sig_> & scalarFunc)4205*35238bceSAndroid Build Coastguard Worker GenFunc(const Func<Sig_> &scalarFunc) : m_func(scalarFunc)
4206*35238bceSAndroid Build Coastguard Worker {
4207*35238bceSAndroid Build Coastguard Worker }
4208*35238bceSAndroid Build Coastguard Worker
getName(void) const4209*35238bceSAndroid Build Coastguard Worker string getName(void) const
4210*35238bceSAndroid Build Coastguard Worker {
4211*35238bceSAndroid Build Coastguard Worker return m_func.getName();
4212*35238bceSAndroid Build Coastguard Worker }
4213*35238bceSAndroid Build Coastguard Worker
getOutParamIndex(void) const4214*35238bceSAndroid Build Coastguard Worker int getOutParamIndex(void) const
4215*35238bceSAndroid Build Coastguard Worker {
4216*35238bceSAndroid Build Coastguard Worker return m_func.getOutParamIndex();
4217*35238bceSAndroid Build Coastguard Worker }
4218*35238bceSAndroid Build Coastguard Worker
getRequiredExtension(const RenderContext & context) const4219*35238bceSAndroid Build Coastguard Worker string getRequiredExtension(const RenderContext &context) const
4220*35238bceSAndroid Build Coastguard Worker {
4221*35238bceSAndroid Build Coastguard Worker return m_func.getRequiredExtension(context);
4222*35238bceSAndroid Build Coastguard Worker }
4223*35238bceSAndroid Build Coastguard Worker
4224*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os,const BaseArgExprs & args) const4225*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
4226*35238bceSAndroid Build Coastguard Worker {
4227*35238bceSAndroid Build Coastguard Worker m_func.print(os, args);
4228*35238bceSAndroid Build Coastguard Worker }
4229*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext & ctx,const IArgs & iargs) const4230*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
4231*35238bceSAndroid Build Coastguard Worker {
4232*35238bceSAndroid Build Coastguard Worker IRet ret;
4233*35238bceSAndroid Build Coastguard Worker
4234*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ++ndx)
4235*35238bceSAndroid Build Coastguard Worker {
4236*35238bceSAndroid Build Coastguard Worker ret[ndx] = m_func.apply(ctx, iargs.a[ndx], iargs.b[ndx], iargs.c[ndx], iargs.d[ndx]);
4237*35238bceSAndroid Build Coastguard Worker }
4238*35238bceSAndroid Build Coastguard Worker
4239*35238bceSAndroid Build Coastguard Worker return ret;
4240*35238bceSAndroid Build Coastguard Worker }
4241*35238bceSAndroid Build Coastguard Worker
doGetUsedFuncs(FuncSet & dst) const4242*35238bceSAndroid Build Coastguard Worker void doGetUsedFuncs(FuncSet &dst) const
4243*35238bceSAndroid Build Coastguard Worker {
4244*35238bceSAndroid Build Coastguard Worker m_func.getUsedFuncs(dst);
4245*35238bceSAndroid Build Coastguard Worker }
4246*35238bceSAndroid Build Coastguard Worker
4247*35238bceSAndroid Build Coastguard Worker const Func<Sig_> &m_func;
4248*35238bceSAndroid Build Coastguard Worker };
4249*35238bceSAndroid Build Coastguard Worker
4250*35238bceSAndroid Build Coastguard Worker template <typename F, int Size>
4251*35238bceSAndroid Build Coastguard Worker class VectorizedFunc : public GenFunc<typename F::Sig, Size>
4252*35238bceSAndroid Build Coastguard Worker {
4253*35238bceSAndroid Build Coastguard Worker public:
VectorizedFunc(void)4254*35238bceSAndroid Build Coastguard Worker VectorizedFunc(void) : GenFunc<typename F::Sig, Size>(instance<F>())
4255*35238bceSAndroid Build Coastguard Worker {
4256*35238bceSAndroid Build Coastguard Worker }
4257*35238bceSAndroid Build Coastguard Worker };
4258*35238bceSAndroid Build Coastguard Worker
4259*35238bceSAndroid Build Coastguard Worker template <typename Sig_, int Size>
4260*35238bceSAndroid Build Coastguard Worker class FixedGenFunc
4261*35238bceSAndroid Build Coastguard Worker : public PrimitiveFunc<Signature<typename ContainerOf<typename Sig_::Ret, Size>::Container,
4262*35238bceSAndroid Build Coastguard Worker typename ContainerOf<typename Sig_::Arg0, Size>::Container, typename Sig_::Arg1,
4263*35238bceSAndroid Build Coastguard Worker typename ContainerOf<typename Sig_::Arg2, Size>::Container,
4264*35238bceSAndroid Build Coastguard Worker typename ContainerOf<typename Sig_::Arg3, Size>::Container>>
4265*35238bceSAndroid Build Coastguard Worker {
4266*35238bceSAndroid Build Coastguard Worker public:
4267*35238bceSAndroid Build Coastguard Worker typedef typename FixedGenFunc::IArgs IArgs;
4268*35238bceSAndroid Build Coastguard Worker typedef typename FixedGenFunc::IRet IRet;
4269*35238bceSAndroid Build Coastguard Worker
getName(void) const4270*35238bceSAndroid Build Coastguard Worker string getName(void) const
4271*35238bceSAndroid Build Coastguard Worker {
4272*35238bceSAndroid Build Coastguard Worker return this->doGetScalarFunc().getName();
4273*35238bceSAndroid Build Coastguard Worker }
4274*35238bceSAndroid Build Coastguard Worker
4275*35238bceSAndroid Build Coastguard Worker protected:
doPrint(ostream & os,const BaseArgExprs & args) const4276*35238bceSAndroid Build Coastguard Worker void doPrint(ostream &os, const BaseArgExprs &args) const
4277*35238bceSAndroid Build Coastguard Worker {
4278*35238bceSAndroid Build Coastguard Worker this->doGetScalarFunc().print(os, args);
4279*35238bceSAndroid Build Coastguard Worker }
4280*35238bceSAndroid Build Coastguard Worker
doApply(const EvalContext & ctx,const IArgs & iargs) const4281*35238bceSAndroid Build Coastguard Worker IRet doApply(const EvalContext &ctx, const IArgs &iargs) const
4282*35238bceSAndroid Build Coastguard Worker {
4283*35238bceSAndroid Build Coastguard Worker IRet ret;
4284*35238bceSAndroid Build Coastguard Worker const Func<Sig_> &func = this->doGetScalarFunc();
4285*35238bceSAndroid Build Coastguard Worker
4286*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ++ndx)
4287*35238bceSAndroid Build Coastguard Worker ret[ndx] = func.apply(ctx, iargs.a[ndx], iargs.b, iargs.c[ndx], iargs.d[ndx]);
4288*35238bceSAndroid Build Coastguard Worker
4289*35238bceSAndroid Build Coastguard Worker return ret;
4290*35238bceSAndroid Build Coastguard Worker }
4291*35238bceSAndroid Build Coastguard Worker
4292*35238bceSAndroid Build Coastguard Worker virtual const Func<Sig_> &doGetScalarFunc(void) const = 0;
4293*35238bceSAndroid Build Coastguard Worker };
4294*35238bceSAndroid Build Coastguard Worker
4295*35238bceSAndroid Build Coastguard Worker template <typename F, int Size>
4296*35238bceSAndroid Build Coastguard Worker class FixedVecFunc : public FixedGenFunc<typename F::Sig, Size>
4297*35238bceSAndroid Build Coastguard Worker {
4298*35238bceSAndroid Build Coastguard Worker protected:
doGetScalarFunc(void) const4299*35238bceSAndroid Build Coastguard Worker const Func<typename F::Sig> &doGetScalarFunc(void) const
4300*35238bceSAndroid Build Coastguard Worker {
4301*35238bceSAndroid Build Coastguard Worker return instance<F>();
4302*35238bceSAndroid Build Coastguard Worker }
4303*35238bceSAndroid Build Coastguard Worker };
4304*35238bceSAndroid Build Coastguard Worker
4305*35238bceSAndroid Build Coastguard Worker template <typename Sig>
4306*35238bceSAndroid Build Coastguard Worker struct GenFuncs
4307*35238bceSAndroid Build Coastguard Worker {
GenFuncsdeqp::gls::BuiltinPrecisionTests::GenFuncs4308*35238bceSAndroid Build Coastguard Worker GenFuncs(const Func<Sig> &func_, const GenFunc<Sig, 2> &func2_, const GenFunc<Sig, 3> &func3_,
4309*35238bceSAndroid Build Coastguard Worker const GenFunc<Sig, 4> &func4_)
4310*35238bceSAndroid Build Coastguard Worker : func(func_)
4311*35238bceSAndroid Build Coastguard Worker , func2(func2_)
4312*35238bceSAndroid Build Coastguard Worker , func3(func3_)
4313*35238bceSAndroid Build Coastguard Worker , func4(func4_)
4314*35238bceSAndroid Build Coastguard Worker {
4315*35238bceSAndroid Build Coastguard Worker }
4316*35238bceSAndroid Build Coastguard Worker
4317*35238bceSAndroid Build Coastguard Worker const Func<Sig> &func;
4318*35238bceSAndroid Build Coastguard Worker const GenFunc<Sig, 2> &func2;
4319*35238bceSAndroid Build Coastguard Worker const GenFunc<Sig, 3> &func3;
4320*35238bceSAndroid Build Coastguard Worker const GenFunc<Sig, 4> &func4;
4321*35238bceSAndroid Build Coastguard Worker };
4322*35238bceSAndroid Build Coastguard Worker
4323*35238bceSAndroid Build Coastguard Worker template <typename F>
makeVectorizedFuncs(void)4324*35238bceSAndroid Build Coastguard Worker GenFuncs<typename F::Sig> makeVectorizedFuncs(void)
4325*35238bceSAndroid Build Coastguard Worker {
4326*35238bceSAndroid Build Coastguard Worker return GenFuncs<typename F::Sig>(instance<F>(), instance<VectorizedFunc<F, 2>>(), instance<VectorizedFunc<F, 3>>(),
4327*35238bceSAndroid Build Coastguard Worker instance<VectorizedFunc<F, 4>>());
4328*35238bceSAndroid Build Coastguard Worker }
4329*35238bceSAndroid Build Coastguard Worker
4330*35238bceSAndroid Build Coastguard Worker template <int Size>
operator *(const ExprP<Vector<float,Size>> & arg0,const ExprP<Vector<float,Size>> & arg1)4331*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator*(const ExprP<Vector<float, Size>> &arg0, const ExprP<Vector<float, Size>> &arg1)
4332*35238bceSAndroid Build Coastguard Worker {
4333*35238bceSAndroid Build Coastguard Worker return app<VectorizedFunc<Mul, Size>>(arg0, arg1);
4334*35238bceSAndroid Build Coastguard Worker }
4335*35238bceSAndroid Build Coastguard Worker
4336*35238bceSAndroid Build Coastguard Worker template <int Size>
operator *(const ExprP<Vector<float,Size>> & arg0,const ExprP<float> & arg1)4337*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator*(const ExprP<Vector<float, Size>> &arg0, const ExprP<float> &arg1)
4338*35238bceSAndroid Build Coastguard Worker {
4339*35238bceSAndroid Build Coastguard Worker return app<FixedVecFunc<Mul, Size>>(arg0, arg1);
4340*35238bceSAndroid Build Coastguard Worker }
4341*35238bceSAndroid Build Coastguard Worker
4342*35238bceSAndroid Build Coastguard Worker template <int Size>
operator /(const ExprP<Vector<float,Size>> & arg0,const ExprP<float> & arg1)4343*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator/(const ExprP<Vector<float, Size>> &arg0, const ExprP<float> &arg1)
4344*35238bceSAndroid Build Coastguard Worker {
4345*35238bceSAndroid Build Coastguard Worker return app<FixedVecFunc<Div, Size>>(arg0, arg1);
4346*35238bceSAndroid Build Coastguard Worker }
4347*35238bceSAndroid Build Coastguard Worker
4348*35238bceSAndroid Build Coastguard Worker template <int Size>
operator -(const ExprP<Vector<float,Size>> & arg0)4349*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator-(const ExprP<Vector<float, Size>> &arg0)
4350*35238bceSAndroid Build Coastguard Worker {
4351*35238bceSAndroid Build Coastguard Worker return app<VectorizedFunc<Negate, Size>>(arg0);
4352*35238bceSAndroid Build Coastguard Worker }
4353*35238bceSAndroid Build Coastguard Worker
4354*35238bceSAndroid Build Coastguard Worker template <int Size>
operator -(const ExprP<Vector<float,Size>> & arg0,const ExprP<Vector<float,Size>> & arg1)4355*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Size>> operator-(const ExprP<Vector<float, Size>> &arg0, const ExprP<Vector<float, Size>> &arg1)
4356*35238bceSAndroid Build Coastguard Worker {
4357*35238bceSAndroid Build Coastguard Worker return app<VectorizedFunc<Sub, Size>>(arg0, arg1);
4358*35238bceSAndroid Build Coastguard Worker }
4359*35238bceSAndroid Build Coastguard Worker
4360*35238bceSAndroid Build Coastguard Worker template <int LeftRows, int Middle, int RightCols>
operator *(const ExprP<Matrix<float,LeftRows,Middle>> & left,const ExprP<Matrix<float,Middle,RightCols>> & right)4361*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, LeftRows, RightCols>> operator*(const ExprP<Matrix<float, LeftRows, Middle>> &left,
4362*35238bceSAndroid Build Coastguard Worker const ExprP<Matrix<float, Middle, RightCols>> &right)
4363*35238bceSAndroid Build Coastguard Worker {
4364*35238bceSAndroid Build Coastguard Worker return app<MatMul<LeftRows, Middle, RightCols>>(left, right);
4365*35238bceSAndroid Build Coastguard Worker }
4366*35238bceSAndroid Build Coastguard Worker
4367*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
operator *(const ExprP<Vector<float,Cols>> & left,const ExprP<Matrix<float,Rows,Cols>> & right)4368*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Rows>> operator*(const ExprP<Vector<float, Cols>> &left,
4369*35238bceSAndroid Build Coastguard Worker const ExprP<Matrix<float, Rows, Cols>> &right)
4370*35238bceSAndroid Build Coastguard Worker {
4371*35238bceSAndroid Build Coastguard Worker return app<VecMatMul<Rows, Cols>>(left, right);
4372*35238bceSAndroid Build Coastguard Worker }
4373*35238bceSAndroid Build Coastguard Worker
4374*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
operator *(const ExprP<Matrix<float,Rows,Cols>> & left,const ExprP<Vector<float,Rows>> & right)4375*35238bceSAndroid Build Coastguard Worker ExprP<Vector<float, Cols>> operator*(const ExprP<Matrix<float, Rows, Cols>> &left,
4376*35238bceSAndroid Build Coastguard Worker const ExprP<Vector<float, Rows>> &right)
4377*35238bceSAndroid Build Coastguard Worker {
4378*35238bceSAndroid Build Coastguard Worker return app<MatVecMul<Rows, Cols>>(left, right);
4379*35238bceSAndroid Build Coastguard Worker }
4380*35238bceSAndroid Build Coastguard Worker
4381*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
operator *(const ExprP<Matrix<float,Rows,Cols>> & left,const ExprP<float> & right)4382*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Rows, Cols>> operator*(const ExprP<Matrix<float, Rows, Cols>> &left, const ExprP<float> &right)
4383*35238bceSAndroid Build Coastguard Worker {
4384*35238bceSAndroid Build Coastguard Worker return app<ScalarMatFunc<Mul, Rows, Cols>>(left, right);
4385*35238bceSAndroid Build Coastguard Worker }
4386*35238bceSAndroid Build Coastguard Worker
4387*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
operator +(const ExprP<Matrix<float,Rows,Cols>> & left,const ExprP<Matrix<float,Rows,Cols>> & right)4388*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Rows, Cols>> operator+(const ExprP<Matrix<float, Rows, Cols>> &left,
4389*35238bceSAndroid Build Coastguard Worker const ExprP<Matrix<float, Rows, Cols>> &right)
4390*35238bceSAndroid Build Coastguard Worker {
4391*35238bceSAndroid Build Coastguard Worker return app<CompMatFunc<Add, Rows, Cols>>(left, right);
4392*35238bceSAndroid Build Coastguard Worker }
4393*35238bceSAndroid Build Coastguard Worker
4394*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
operator -(const ExprP<Matrix<float,Rows,Cols>> & mat)4395*35238bceSAndroid Build Coastguard Worker ExprP<Matrix<float, Rows, Cols>> operator-(const ExprP<Matrix<float, Rows, Cols>> &mat)
4396*35238bceSAndroid Build Coastguard Worker {
4397*35238bceSAndroid Build Coastguard Worker return app<MatNeg<Rows, Cols>>(mat);
4398*35238bceSAndroid Build Coastguard Worker }
4399*35238bceSAndroid Build Coastguard Worker
4400*35238bceSAndroid Build Coastguard Worker template <typename T>
4401*35238bceSAndroid Build Coastguard Worker class Sampling
4402*35238bceSAndroid Build Coastguard Worker {
4403*35238bceSAndroid Build Coastguard Worker public:
genFixeds(const FloatFormat &,vector<T> &) const4404*35238bceSAndroid Build Coastguard Worker virtual void genFixeds(const FloatFormat &, vector<T> &) const
4405*35238bceSAndroid Build Coastguard Worker {
4406*35238bceSAndroid Build Coastguard Worker }
genRandom(const FloatFormat &,Precision,Random &) const4407*35238bceSAndroid Build Coastguard Worker virtual T genRandom(const FloatFormat &, Precision, Random &) const
4408*35238bceSAndroid Build Coastguard Worker {
4409*35238bceSAndroid Build Coastguard Worker return T();
4410*35238bceSAndroid Build Coastguard Worker }
getWeight(void) const4411*35238bceSAndroid Build Coastguard Worker virtual double getWeight(void) const
4412*35238bceSAndroid Build Coastguard Worker {
4413*35238bceSAndroid Build Coastguard Worker return 0.0;
4414*35238bceSAndroid Build Coastguard Worker }
4415*35238bceSAndroid Build Coastguard Worker };
4416*35238bceSAndroid Build Coastguard Worker
4417*35238bceSAndroid Build Coastguard Worker template <>
4418*35238bceSAndroid Build Coastguard Worker class DefaultSampling<Void> : public Sampling<Void>
4419*35238bceSAndroid Build Coastguard Worker {
4420*35238bceSAndroid Build Coastguard Worker public:
genFixeds(const FloatFormat &,vector<Void> & dst) const4421*35238bceSAndroid Build Coastguard Worker void genFixeds(const FloatFormat &, vector<Void> &dst) const
4422*35238bceSAndroid Build Coastguard Worker {
4423*35238bceSAndroid Build Coastguard Worker dst.push_back(Void());
4424*35238bceSAndroid Build Coastguard Worker }
4425*35238bceSAndroid Build Coastguard Worker };
4426*35238bceSAndroid Build Coastguard Worker
4427*35238bceSAndroid Build Coastguard Worker template <>
4428*35238bceSAndroid Build Coastguard Worker class DefaultSampling<bool> : public Sampling<bool>
4429*35238bceSAndroid Build Coastguard Worker {
4430*35238bceSAndroid Build Coastguard Worker public:
genFixeds(const FloatFormat &,vector<bool> & dst) const4431*35238bceSAndroid Build Coastguard Worker void genFixeds(const FloatFormat &, vector<bool> &dst) const
4432*35238bceSAndroid Build Coastguard Worker {
4433*35238bceSAndroid Build Coastguard Worker dst.push_back(true);
4434*35238bceSAndroid Build Coastguard Worker dst.push_back(false);
4435*35238bceSAndroid Build Coastguard Worker }
4436*35238bceSAndroid Build Coastguard Worker };
4437*35238bceSAndroid Build Coastguard Worker
4438*35238bceSAndroid Build Coastguard Worker template <>
4439*35238bceSAndroid Build Coastguard Worker class DefaultSampling<int> : public Sampling<int>
4440*35238bceSAndroid Build Coastguard Worker {
4441*35238bceSAndroid Build Coastguard Worker public:
genRandom(const FloatFormat &,Precision prec,Random & rnd) const4442*35238bceSAndroid Build Coastguard Worker int genRandom(const FloatFormat &, Precision prec, Random &rnd) const
4443*35238bceSAndroid Build Coastguard Worker {
4444*35238bceSAndroid Build Coastguard Worker const int exp = rnd.getInt(0, getNumBits(prec) - 2);
4445*35238bceSAndroid Build Coastguard Worker const int sign = rnd.getBool() ? -1 : 1;
4446*35238bceSAndroid Build Coastguard Worker
4447*35238bceSAndroid Build Coastguard Worker return sign * rnd.getInt(0, (int32_t)1 << exp);
4448*35238bceSAndroid Build Coastguard Worker }
4449*35238bceSAndroid Build Coastguard Worker
genFixeds(const FloatFormat &,vector<int> & dst) const4450*35238bceSAndroid Build Coastguard Worker void genFixeds(const FloatFormat &, vector<int> &dst) const
4451*35238bceSAndroid Build Coastguard Worker {
4452*35238bceSAndroid Build Coastguard Worker dst.push_back(0);
4453*35238bceSAndroid Build Coastguard Worker dst.push_back(-1);
4454*35238bceSAndroid Build Coastguard Worker dst.push_back(1);
4455*35238bceSAndroid Build Coastguard Worker }
getWeight(void) const4456*35238bceSAndroid Build Coastguard Worker double getWeight(void) const
4457*35238bceSAndroid Build Coastguard Worker {
4458*35238bceSAndroid Build Coastguard Worker return 1.0;
4459*35238bceSAndroid Build Coastguard Worker }
4460*35238bceSAndroid Build Coastguard Worker
4461*35238bceSAndroid Build Coastguard Worker private:
getNumBits(Precision prec)4462*35238bceSAndroid Build Coastguard Worker static inline int getNumBits(Precision prec)
4463*35238bceSAndroid Build Coastguard Worker {
4464*35238bceSAndroid Build Coastguard Worker switch (prec)
4465*35238bceSAndroid Build Coastguard Worker {
4466*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
4467*35238bceSAndroid Build Coastguard Worker return 8;
4468*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
4469*35238bceSAndroid Build Coastguard Worker return 16;
4470*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
4471*35238bceSAndroid Build Coastguard Worker return 32;
4472*35238bceSAndroid Build Coastguard Worker default:
4473*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
4474*35238bceSAndroid Build Coastguard Worker return 0;
4475*35238bceSAndroid Build Coastguard Worker }
4476*35238bceSAndroid Build Coastguard Worker }
4477*35238bceSAndroid Build Coastguard Worker };
4478*35238bceSAndroid Build Coastguard Worker
4479*35238bceSAndroid Build Coastguard Worker template <>
4480*35238bceSAndroid Build Coastguard Worker class DefaultSampling<float> : public Sampling<float>
4481*35238bceSAndroid Build Coastguard Worker {
4482*35238bceSAndroid Build Coastguard Worker public:
4483*35238bceSAndroid Build Coastguard Worker float genRandom(const FloatFormat &format, Precision prec, Random &rnd) const;
4484*35238bceSAndroid Build Coastguard Worker void genFixeds(const FloatFormat &format, vector<float> &dst) const;
getWeight(void) const4485*35238bceSAndroid Build Coastguard Worker double getWeight(void) const
4486*35238bceSAndroid Build Coastguard Worker {
4487*35238bceSAndroid Build Coastguard Worker return 1.0;
4488*35238bceSAndroid Build Coastguard Worker }
4489*35238bceSAndroid Build Coastguard Worker };
4490*35238bceSAndroid Build Coastguard Worker
4491*35238bceSAndroid Build Coastguard Worker //! Generate a random float from a reasonable general-purpose distribution.
genRandom(const FloatFormat & format,Precision,Random & rnd) const4492*35238bceSAndroid Build Coastguard Worker float DefaultSampling<float>::genRandom(const FloatFormat &format, Precision, Random &rnd) const
4493*35238bceSAndroid Build Coastguard Worker {
4494*35238bceSAndroid Build Coastguard Worker const int minExp = format.getMinExp();
4495*35238bceSAndroid Build Coastguard Worker const int maxExp = format.getMaxExp();
4496*35238bceSAndroid Build Coastguard Worker const bool haveSubnormal = format.hasSubnormal() != tcu::NO;
4497*35238bceSAndroid Build Coastguard Worker
4498*35238bceSAndroid Build Coastguard Worker // Choose exponent so that the cumulative distribution is cubic.
4499*35238bceSAndroid Build Coastguard Worker // This makes the probability distribution quadratic, with the peak centered on zero.
4500*35238bceSAndroid Build Coastguard Worker const double minRoot = deCbrt(minExp - 0.5 - (haveSubnormal ? 1.0 : 0.0));
4501*35238bceSAndroid Build Coastguard Worker const double maxRoot = deCbrt(maxExp + 0.5);
4502*35238bceSAndroid Build Coastguard Worker const int fractionBits = format.getFractionBits();
4503*35238bceSAndroid Build Coastguard Worker const int exp = int(deRoundEven(dePow(rnd.getDouble(minRoot, maxRoot), 3.0)));
4504*35238bceSAndroid Build Coastguard Worker float base = 0.0f; // integral power of two
4505*35238bceSAndroid Build Coastguard Worker float quantum = 0.0f; // smallest representable difference in the binade
4506*35238bceSAndroid Build Coastguard Worker float significand = 0.0f; // Significand.
4507*35238bceSAndroid Build Coastguard Worker
4508*35238bceSAndroid Build Coastguard Worker DE_ASSERT(fractionBits < std::numeric_limits<float>::digits);
4509*35238bceSAndroid Build Coastguard Worker
4510*35238bceSAndroid Build Coastguard Worker // Generate some occasional special numbers
4511*35238bceSAndroid Build Coastguard Worker switch (rnd.getInt(0, 64))
4512*35238bceSAndroid Build Coastguard Worker {
4513*35238bceSAndroid Build Coastguard Worker case 0:
4514*35238bceSAndroid Build Coastguard Worker return 0;
4515*35238bceSAndroid Build Coastguard Worker case 1:
4516*35238bceSAndroid Build Coastguard Worker return TCU_INFINITY;
4517*35238bceSAndroid Build Coastguard Worker case 2:
4518*35238bceSAndroid Build Coastguard Worker return -TCU_INFINITY;
4519*35238bceSAndroid Build Coastguard Worker case 3:
4520*35238bceSAndroid Build Coastguard Worker return TCU_NAN;
4521*35238bceSAndroid Build Coastguard Worker default:
4522*35238bceSAndroid Build Coastguard Worker break;
4523*35238bceSAndroid Build Coastguard Worker }
4524*35238bceSAndroid Build Coastguard Worker
4525*35238bceSAndroid Build Coastguard Worker if (exp >= minExp)
4526*35238bceSAndroid Build Coastguard Worker {
4527*35238bceSAndroid Build Coastguard Worker // Normal number
4528*35238bceSAndroid Build Coastguard Worker base = deFloatLdExp(1.0f, exp);
4529*35238bceSAndroid Build Coastguard Worker quantum = deFloatLdExp(1.0f, exp - fractionBits);
4530*35238bceSAndroid Build Coastguard Worker }
4531*35238bceSAndroid Build Coastguard Worker else
4532*35238bceSAndroid Build Coastguard Worker {
4533*35238bceSAndroid Build Coastguard Worker // Subnormal
4534*35238bceSAndroid Build Coastguard Worker base = 0.0f;
4535*35238bceSAndroid Build Coastguard Worker quantum = deFloatLdExp(1.0f, minExp - fractionBits);
4536*35238bceSAndroid Build Coastguard Worker }
4537*35238bceSAndroid Build Coastguard Worker
4538*35238bceSAndroid Build Coastguard Worker switch (rnd.getInt(0, 16))
4539*35238bceSAndroid Build Coastguard Worker {
4540*35238bceSAndroid Build Coastguard Worker case 0: // The highest number in this binade, significand is all bits one.
4541*35238bceSAndroid Build Coastguard Worker significand = base - quantum;
4542*35238bceSAndroid Build Coastguard Worker break;
4543*35238bceSAndroid Build Coastguard Worker case 1: // Significand is one.
4544*35238bceSAndroid Build Coastguard Worker significand = quantum;
4545*35238bceSAndroid Build Coastguard Worker break;
4546*35238bceSAndroid Build Coastguard Worker case 2: // Significand is zero.
4547*35238bceSAndroid Build Coastguard Worker significand = 0.0;
4548*35238bceSAndroid Build Coastguard Worker break;
4549*35238bceSAndroid Build Coastguard Worker default: // Random (evenly distributed) significand.
4550*35238bceSAndroid Build Coastguard Worker {
4551*35238bceSAndroid Build Coastguard Worker uint64_t intFraction = rnd.getUint64() & ((1ull << fractionBits) - 1);
4552*35238bceSAndroid Build Coastguard Worker significand = float(intFraction) * quantum;
4553*35238bceSAndroid Build Coastguard Worker }
4554*35238bceSAndroid Build Coastguard Worker }
4555*35238bceSAndroid Build Coastguard Worker
4556*35238bceSAndroid Build Coastguard Worker // Produce positive numbers more often than negative.
4557*35238bceSAndroid Build Coastguard Worker return (rnd.getInt(0, 3) == 0 ? -1.0f : 1.0f) * (base + significand);
4558*35238bceSAndroid Build Coastguard Worker }
4559*35238bceSAndroid Build Coastguard Worker
4560*35238bceSAndroid Build Coastguard Worker //! Generate a standard set of floats that should always be tested.
genFixeds(const FloatFormat & format,vector<float> & dst) const4561*35238bceSAndroid Build Coastguard Worker void DefaultSampling<float>::genFixeds(const FloatFormat &format, vector<float> &dst) const
4562*35238bceSAndroid Build Coastguard Worker {
4563*35238bceSAndroid Build Coastguard Worker const int minExp = format.getMinExp();
4564*35238bceSAndroid Build Coastguard Worker const int maxExp = format.getMaxExp();
4565*35238bceSAndroid Build Coastguard Worker const int fractionBits = format.getFractionBits();
4566*35238bceSAndroid Build Coastguard Worker const float minQuantum = deFloatLdExp(1.0f, minExp - fractionBits);
4567*35238bceSAndroid Build Coastguard Worker const float minNormalized = deFloatLdExp(1.0f, minExp);
4568*35238bceSAndroid Build Coastguard Worker const float maxQuantum = deFloatLdExp(1.0f, maxExp - fractionBits);
4569*35238bceSAndroid Build Coastguard Worker
4570*35238bceSAndroid Build Coastguard Worker // NaN
4571*35238bceSAndroid Build Coastguard Worker dst.push_back(TCU_NAN);
4572*35238bceSAndroid Build Coastguard Worker // Zero
4573*35238bceSAndroid Build Coastguard Worker dst.push_back(0.0f);
4574*35238bceSAndroid Build Coastguard Worker
4575*35238bceSAndroid Build Coastguard Worker for (int sign = -1; sign <= 1; sign += 2)
4576*35238bceSAndroid Build Coastguard Worker {
4577*35238bceSAndroid Build Coastguard Worker // Smallest subnormal
4578*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * minQuantum);
4579*35238bceSAndroid Build Coastguard Worker
4580*35238bceSAndroid Build Coastguard Worker // Largest subnormal
4581*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * (minNormalized - minQuantum));
4582*35238bceSAndroid Build Coastguard Worker
4583*35238bceSAndroid Build Coastguard Worker // Smallest normalized
4584*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * minNormalized);
4585*35238bceSAndroid Build Coastguard Worker
4586*35238bceSAndroid Build Coastguard Worker // Next smallest normalized
4587*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * (minNormalized + minQuantum));
4588*35238bceSAndroid Build Coastguard Worker
4589*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * 0.5f);
4590*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * 1.0f);
4591*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * 2.0f);
4592*35238bceSAndroid Build Coastguard Worker
4593*35238bceSAndroid Build Coastguard Worker // Largest number
4594*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * (deFloatLdExp(1.0f, maxExp) + (deFloatLdExp(1.0f, maxExp) - maxQuantum)));
4595*35238bceSAndroid Build Coastguard Worker
4596*35238bceSAndroid Build Coastguard Worker dst.push_back((float)sign * TCU_INFINITY);
4597*35238bceSAndroid Build Coastguard Worker }
4598*35238bceSAndroid Build Coastguard Worker }
4599*35238bceSAndroid Build Coastguard Worker
4600*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
4601*35238bceSAndroid Build Coastguard Worker class DefaultSampling<Vector<T, Size>> : public Sampling<Vector<T, Size>>
4602*35238bceSAndroid Build Coastguard Worker {
4603*35238bceSAndroid Build Coastguard Worker public:
4604*35238bceSAndroid Build Coastguard Worker typedef Vector<T, Size> Value;
4605*35238bceSAndroid Build Coastguard Worker
genRandom(const FloatFormat & fmt,Precision prec,Random & rnd) const4606*35238bceSAndroid Build Coastguard Worker Value genRandom(const FloatFormat &fmt, Precision prec, Random &rnd) const
4607*35238bceSAndroid Build Coastguard Worker {
4608*35238bceSAndroid Build Coastguard Worker Value ret;
4609*35238bceSAndroid Build Coastguard Worker
4610*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ++ndx)
4611*35238bceSAndroid Build Coastguard Worker ret[ndx] = instance<DefaultSampling<T>>().genRandom(fmt, prec, rnd);
4612*35238bceSAndroid Build Coastguard Worker
4613*35238bceSAndroid Build Coastguard Worker return ret;
4614*35238bceSAndroid Build Coastguard Worker }
4615*35238bceSAndroid Build Coastguard Worker
genFixeds(const FloatFormat & fmt,vector<Value> & dst) const4616*35238bceSAndroid Build Coastguard Worker void genFixeds(const FloatFormat &fmt, vector<Value> &dst) const
4617*35238bceSAndroid Build Coastguard Worker {
4618*35238bceSAndroid Build Coastguard Worker vector<T> scalars;
4619*35238bceSAndroid Build Coastguard Worker
4620*35238bceSAndroid Build Coastguard Worker instance<DefaultSampling<T>>().genFixeds(fmt, scalars);
4621*35238bceSAndroid Build Coastguard Worker
4622*35238bceSAndroid Build Coastguard Worker for (size_t scalarNdx = 0; scalarNdx < scalars.size(); ++scalarNdx)
4623*35238bceSAndroid Build Coastguard Worker dst.push_back(Value(scalars[scalarNdx]));
4624*35238bceSAndroid Build Coastguard Worker }
4625*35238bceSAndroid Build Coastguard Worker
getWeight(void) const4626*35238bceSAndroid Build Coastguard Worker double getWeight(void) const
4627*35238bceSAndroid Build Coastguard Worker {
4628*35238bceSAndroid Build Coastguard Worker return dePow(instance<DefaultSampling<T>>().getWeight(), Size);
4629*35238bceSAndroid Build Coastguard Worker }
4630*35238bceSAndroid Build Coastguard Worker };
4631*35238bceSAndroid Build Coastguard Worker
4632*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Columns>
4633*35238bceSAndroid Build Coastguard Worker class DefaultSampling<Matrix<T, Rows, Columns>> : public Sampling<Matrix<T, Rows, Columns>>
4634*35238bceSAndroid Build Coastguard Worker {
4635*35238bceSAndroid Build Coastguard Worker public:
4636*35238bceSAndroid Build Coastguard Worker typedef Matrix<T, Rows, Columns> Value;
4637*35238bceSAndroid Build Coastguard Worker
genRandom(const FloatFormat & fmt,Precision prec,Random & rnd) const4638*35238bceSAndroid Build Coastguard Worker Value genRandom(const FloatFormat &fmt, Precision prec, Random &rnd) const
4639*35238bceSAndroid Build Coastguard Worker {
4640*35238bceSAndroid Build Coastguard Worker Value ret;
4641*35238bceSAndroid Build Coastguard Worker
4642*35238bceSAndroid Build Coastguard Worker for (int rowNdx = 0; rowNdx < Rows; ++rowNdx)
4643*35238bceSAndroid Build Coastguard Worker for (int colNdx = 0; colNdx < Columns; ++colNdx)
4644*35238bceSAndroid Build Coastguard Worker ret(rowNdx, colNdx) = instance<DefaultSampling<T>>().genRandom(fmt, prec, rnd);
4645*35238bceSAndroid Build Coastguard Worker
4646*35238bceSAndroid Build Coastguard Worker return ret;
4647*35238bceSAndroid Build Coastguard Worker }
4648*35238bceSAndroid Build Coastguard Worker
genFixeds(const FloatFormat & fmt,vector<Value> & dst) const4649*35238bceSAndroid Build Coastguard Worker void genFixeds(const FloatFormat &fmt, vector<Value> &dst) const
4650*35238bceSAndroid Build Coastguard Worker {
4651*35238bceSAndroid Build Coastguard Worker vector<T> scalars;
4652*35238bceSAndroid Build Coastguard Worker
4653*35238bceSAndroid Build Coastguard Worker instance<DefaultSampling<T>>().genFixeds(fmt, scalars);
4654*35238bceSAndroid Build Coastguard Worker
4655*35238bceSAndroid Build Coastguard Worker for (size_t scalarNdx = 0; scalarNdx < scalars.size(); ++scalarNdx)
4656*35238bceSAndroid Build Coastguard Worker dst.push_back(Value(scalars[scalarNdx]));
4657*35238bceSAndroid Build Coastguard Worker
4658*35238bceSAndroid Build Coastguard Worker if (Columns == Rows)
4659*35238bceSAndroid Build Coastguard Worker {
4660*35238bceSAndroid Build Coastguard Worker Value mat(0.0);
4661*35238bceSAndroid Build Coastguard Worker T x = T(1.0f);
4662*35238bceSAndroid Build Coastguard Worker mat[0][0] = x;
4663*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Columns; ++ndx)
4664*35238bceSAndroid Build Coastguard Worker {
4665*35238bceSAndroid Build Coastguard Worker mat[Columns - 1 - ndx][ndx] = x;
4666*35238bceSAndroid Build Coastguard Worker x *= T(2.0f);
4667*35238bceSAndroid Build Coastguard Worker }
4668*35238bceSAndroid Build Coastguard Worker dst.push_back(mat);
4669*35238bceSAndroid Build Coastguard Worker }
4670*35238bceSAndroid Build Coastguard Worker }
4671*35238bceSAndroid Build Coastguard Worker
getWeight(void) const4672*35238bceSAndroid Build Coastguard Worker double getWeight(void) const
4673*35238bceSAndroid Build Coastguard Worker {
4674*35238bceSAndroid Build Coastguard Worker return dePow(instance<DefaultSampling<T>>().getWeight(), Rows * Columns);
4675*35238bceSAndroid Build Coastguard Worker }
4676*35238bceSAndroid Build Coastguard Worker };
4677*35238bceSAndroid Build Coastguard Worker
4678*35238bceSAndroid Build Coastguard Worker struct Context
4679*35238bceSAndroid Build Coastguard Worker {
Contextdeqp::gls::BuiltinPrecisionTests::Context4680*35238bceSAndroid Build Coastguard Worker Context(const string &name_, TestContext &testContext_, RenderContext &renderContext_,
4681*35238bceSAndroid Build Coastguard Worker const FloatFormat &floatFormat_, const FloatFormat &highpFormat_, Precision precision_,
4682*35238bceSAndroid Build Coastguard Worker ShaderType shaderType_, size_t numRandoms_)
4683*35238bceSAndroid Build Coastguard Worker : name(name_)
4684*35238bceSAndroid Build Coastguard Worker , testContext(testContext_)
4685*35238bceSAndroid Build Coastguard Worker , renderContext(renderContext_)
4686*35238bceSAndroid Build Coastguard Worker , floatFormat(floatFormat_)
4687*35238bceSAndroid Build Coastguard Worker , highpFormat(highpFormat_)
4688*35238bceSAndroid Build Coastguard Worker , precision(precision_)
4689*35238bceSAndroid Build Coastguard Worker , shaderType(shaderType_)
4690*35238bceSAndroid Build Coastguard Worker , numRandoms(numRandoms_)
4691*35238bceSAndroid Build Coastguard Worker {
4692*35238bceSAndroid Build Coastguard Worker }
4693*35238bceSAndroid Build Coastguard Worker
4694*35238bceSAndroid Build Coastguard Worker string name;
4695*35238bceSAndroid Build Coastguard Worker TestContext &testContext;
4696*35238bceSAndroid Build Coastguard Worker RenderContext &renderContext;
4697*35238bceSAndroid Build Coastguard Worker FloatFormat floatFormat;
4698*35238bceSAndroid Build Coastguard Worker FloatFormat highpFormat;
4699*35238bceSAndroid Build Coastguard Worker Precision precision;
4700*35238bceSAndroid Build Coastguard Worker ShaderType shaderType;
4701*35238bceSAndroid Build Coastguard Worker size_t numRandoms;
4702*35238bceSAndroid Build Coastguard Worker };
4703*35238bceSAndroid Build Coastguard Worker
4704*35238bceSAndroid Build Coastguard Worker template <typename In0_ = Void, typename In1_ = Void, typename In2_ = Void, typename In3_ = Void>
4705*35238bceSAndroid Build Coastguard Worker struct InTypes
4706*35238bceSAndroid Build Coastguard Worker {
4707*35238bceSAndroid Build Coastguard Worker typedef In0_ In0;
4708*35238bceSAndroid Build Coastguard Worker typedef In1_ In1;
4709*35238bceSAndroid Build Coastguard Worker typedef In2_ In2;
4710*35238bceSAndroid Build Coastguard Worker typedef In3_ In3;
4711*35238bceSAndroid Build Coastguard Worker };
4712*35238bceSAndroid Build Coastguard Worker
4713*35238bceSAndroid Build Coastguard Worker template <typename In>
numInputs(void)4714*35238bceSAndroid Build Coastguard Worker int numInputs(void)
4715*35238bceSAndroid Build Coastguard Worker {
4716*35238bceSAndroid Build Coastguard Worker return (!isTypeValid<typename In::In0>() ? 0 :
4717*35238bceSAndroid Build Coastguard Worker !isTypeValid<typename In::In1>() ? 1 :
4718*35238bceSAndroid Build Coastguard Worker !isTypeValid<typename In::In2>() ? 2 :
4719*35238bceSAndroid Build Coastguard Worker !isTypeValid<typename In::In3>() ? 3 :
4720*35238bceSAndroid Build Coastguard Worker 4);
4721*35238bceSAndroid Build Coastguard Worker }
4722*35238bceSAndroid Build Coastguard Worker
4723*35238bceSAndroid Build Coastguard Worker template <typename Out0_, typename Out1_ = Void>
4724*35238bceSAndroid Build Coastguard Worker struct OutTypes
4725*35238bceSAndroid Build Coastguard Worker {
4726*35238bceSAndroid Build Coastguard Worker typedef Out0_ Out0;
4727*35238bceSAndroid Build Coastguard Worker typedef Out1_ Out1;
4728*35238bceSAndroid Build Coastguard Worker };
4729*35238bceSAndroid Build Coastguard Worker
4730*35238bceSAndroid Build Coastguard Worker template <typename Out>
numOutputs(void)4731*35238bceSAndroid Build Coastguard Worker int numOutputs(void)
4732*35238bceSAndroid Build Coastguard Worker {
4733*35238bceSAndroid Build Coastguard Worker return (!isTypeValid<typename Out::Out0>() ? 0 : !isTypeValid<typename Out::Out1>() ? 1 : 2);
4734*35238bceSAndroid Build Coastguard Worker }
4735*35238bceSAndroid Build Coastguard Worker
4736*35238bceSAndroid Build Coastguard Worker template <typename In>
4737*35238bceSAndroid Build Coastguard Worker struct Inputs
4738*35238bceSAndroid Build Coastguard Worker {
4739*35238bceSAndroid Build Coastguard Worker vector<typename In::In0> in0;
4740*35238bceSAndroid Build Coastguard Worker vector<typename In::In1> in1;
4741*35238bceSAndroid Build Coastguard Worker vector<typename In::In2> in2;
4742*35238bceSAndroid Build Coastguard Worker vector<typename In::In3> in3;
4743*35238bceSAndroid Build Coastguard Worker };
4744*35238bceSAndroid Build Coastguard Worker
4745*35238bceSAndroid Build Coastguard Worker template <typename Out>
4746*35238bceSAndroid Build Coastguard Worker struct Outputs
4747*35238bceSAndroid Build Coastguard Worker {
Outputsdeqp::gls::BuiltinPrecisionTests::Outputs4748*35238bceSAndroid Build Coastguard Worker Outputs(size_t size) : out0(size), out1(size)
4749*35238bceSAndroid Build Coastguard Worker {
4750*35238bceSAndroid Build Coastguard Worker }
4751*35238bceSAndroid Build Coastguard Worker
4752*35238bceSAndroid Build Coastguard Worker vector<typename Out::Out0> out0;
4753*35238bceSAndroid Build Coastguard Worker vector<typename Out::Out1> out1;
4754*35238bceSAndroid Build Coastguard Worker };
4755*35238bceSAndroid Build Coastguard Worker
4756*35238bceSAndroid Build Coastguard Worker template <typename In, typename Out>
4757*35238bceSAndroid Build Coastguard Worker struct Variables
4758*35238bceSAndroid Build Coastguard Worker {
4759*35238bceSAndroid Build Coastguard Worker VariableP<typename In::In0> in0;
4760*35238bceSAndroid Build Coastguard Worker VariableP<typename In::In1> in1;
4761*35238bceSAndroid Build Coastguard Worker VariableP<typename In::In2> in2;
4762*35238bceSAndroid Build Coastguard Worker VariableP<typename In::In3> in3;
4763*35238bceSAndroid Build Coastguard Worker VariableP<typename Out::Out0> out0;
4764*35238bceSAndroid Build Coastguard Worker VariableP<typename Out::Out1> out1;
4765*35238bceSAndroid Build Coastguard Worker };
4766*35238bceSAndroid Build Coastguard Worker
4767*35238bceSAndroid Build Coastguard Worker template <typename In>
4768*35238bceSAndroid Build Coastguard Worker struct Samplings
4769*35238bceSAndroid Build Coastguard Worker {
Samplingsdeqp::gls::BuiltinPrecisionTests::Samplings4770*35238bceSAndroid Build Coastguard Worker Samplings(const Sampling<typename In::In0> &in0_, const Sampling<typename In::In1> &in1_,
4771*35238bceSAndroid Build Coastguard Worker const Sampling<typename In::In2> &in2_, const Sampling<typename In::In3> &in3_)
4772*35238bceSAndroid Build Coastguard Worker : in0(in0_)
4773*35238bceSAndroid Build Coastguard Worker , in1(in1_)
4774*35238bceSAndroid Build Coastguard Worker , in2(in2_)
4775*35238bceSAndroid Build Coastguard Worker , in3(in3_)
4776*35238bceSAndroid Build Coastguard Worker {
4777*35238bceSAndroid Build Coastguard Worker }
4778*35238bceSAndroid Build Coastguard Worker
4779*35238bceSAndroid Build Coastguard Worker const Sampling<typename In::In0> &in0;
4780*35238bceSAndroid Build Coastguard Worker const Sampling<typename In::In1> &in1;
4781*35238bceSAndroid Build Coastguard Worker const Sampling<typename In::In2> &in2;
4782*35238bceSAndroid Build Coastguard Worker const Sampling<typename In::In3> &in3;
4783*35238bceSAndroid Build Coastguard Worker };
4784*35238bceSAndroid Build Coastguard Worker
4785*35238bceSAndroid Build Coastguard Worker template <typename In>
4786*35238bceSAndroid Build Coastguard Worker struct DefaultSamplings : Samplings<In>
4787*35238bceSAndroid Build Coastguard Worker {
DefaultSamplingsdeqp::gls::BuiltinPrecisionTests::DefaultSamplings4788*35238bceSAndroid Build Coastguard Worker DefaultSamplings(void)
4789*35238bceSAndroid Build Coastguard Worker : Samplings<In>(instance<DefaultSampling<typename In::In0>>(), instance<DefaultSampling<typename In::In1>>(),
4790*35238bceSAndroid Build Coastguard Worker instance<DefaultSampling<typename In::In2>>(), instance<DefaultSampling<typename In::In3>>())
4791*35238bceSAndroid Build Coastguard Worker {
4792*35238bceSAndroid Build Coastguard Worker }
4793*35238bceSAndroid Build Coastguard Worker };
4794*35238bceSAndroid Build Coastguard Worker
4795*35238bceSAndroid Build Coastguard Worker class PrecisionCase : public TestCase
4796*35238bceSAndroid Build Coastguard Worker {
4797*35238bceSAndroid Build Coastguard Worker public:
4798*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
4799*35238bceSAndroid Build Coastguard Worker
4800*35238bceSAndroid Build Coastguard Worker protected:
PrecisionCase(const Context & context,const string & name,const string & extension="")4801*35238bceSAndroid Build Coastguard Worker PrecisionCase(const Context &context, const string &name, const string &extension = "")
4802*35238bceSAndroid Build Coastguard Worker : TestCase(context.testContext, name.c_str(), name.c_str())
4803*35238bceSAndroid Build Coastguard Worker , m_ctx(context)
4804*35238bceSAndroid Build Coastguard Worker , m_status()
4805*35238bceSAndroid Build Coastguard Worker , m_rnd(0xdeadbeefu + context.testContext.getCommandLine().getBaseSeed())
4806*35238bceSAndroid Build Coastguard Worker , m_extension(extension)
4807*35238bceSAndroid Build Coastguard Worker {
4808*35238bceSAndroid Build Coastguard Worker }
4809*35238bceSAndroid Build Coastguard Worker
getRenderContext(void) const4810*35238bceSAndroid Build Coastguard Worker RenderContext &getRenderContext(void) const
4811*35238bceSAndroid Build Coastguard Worker {
4812*35238bceSAndroid Build Coastguard Worker return m_ctx.renderContext;
4813*35238bceSAndroid Build Coastguard Worker }
4814*35238bceSAndroid Build Coastguard Worker
getFormat(void) const4815*35238bceSAndroid Build Coastguard Worker const FloatFormat &getFormat(void) const
4816*35238bceSAndroid Build Coastguard Worker {
4817*35238bceSAndroid Build Coastguard Worker return m_ctx.floatFormat;
4818*35238bceSAndroid Build Coastguard Worker }
4819*35238bceSAndroid Build Coastguard Worker
log(void) const4820*35238bceSAndroid Build Coastguard Worker TestLog &log(void) const
4821*35238bceSAndroid Build Coastguard Worker {
4822*35238bceSAndroid Build Coastguard Worker return m_testCtx.getLog();
4823*35238bceSAndroid Build Coastguard Worker }
4824*35238bceSAndroid Build Coastguard Worker
4825*35238bceSAndroid Build Coastguard Worker virtual void runTest(void) = 0;
4826*35238bceSAndroid Build Coastguard Worker
4827*35238bceSAndroid Build Coastguard Worker template <typename In, typename Out>
4828*35238bceSAndroid Build Coastguard Worker void testStatement(const Variables<In, Out> &variables, const Inputs<In> &inputs, const Statement &stmt);
4829*35238bceSAndroid Build Coastguard Worker
4830*35238bceSAndroid Build Coastguard Worker template <typename T>
makeSymbol(const Variable<T> & variable)4831*35238bceSAndroid Build Coastguard Worker Symbol makeSymbol(const Variable<T> &variable)
4832*35238bceSAndroid Build Coastguard Worker {
4833*35238bceSAndroid Build Coastguard Worker return Symbol(variable.getName(), getVarTypeOf<T>(m_ctx.precision));
4834*35238bceSAndroid Build Coastguard Worker }
4835*35238bceSAndroid Build Coastguard Worker
4836*35238bceSAndroid Build Coastguard Worker Context m_ctx;
4837*35238bceSAndroid Build Coastguard Worker ResultCollector m_status;
4838*35238bceSAndroid Build Coastguard Worker Random m_rnd;
4839*35238bceSAndroid Build Coastguard Worker const string m_extension;
4840*35238bceSAndroid Build Coastguard Worker };
4841*35238bceSAndroid Build Coastguard Worker
iterate(void)4842*35238bceSAndroid Build Coastguard Worker IterateResult PrecisionCase::iterate(void)
4843*35238bceSAndroid Build Coastguard Worker {
4844*35238bceSAndroid Build Coastguard Worker runTest();
4845*35238bceSAndroid Build Coastguard Worker m_status.setTestContextResult(m_testCtx);
4846*35238bceSAndroid Build Coastguard Worker return STOP;
4847*35238bceSAndroid Build Coastguard Worker }
4848*35238bceSAndroid Build Coastguard Worker
4849*35238bceSAndroid Build Coastguard Worker template <typename In, typename Out>
testStatement(const Variables<In,Out> & variables,const Inputs<In> & inputs,const Statement & stmt)4850*35238bceSAndroid Build Coastguard Worker void PrecisionCase::testStatement(const Variables<In, Out> &variables, const Inputs<In> &inputs, const Statement &stmt)
4851*35238bceSAndroid Build Coastguard Worker {
4852*35238bceSAndroid Build Coastguard Worker using namespace ShaderExecUtil;
4853*35238bceSAndroid Build Coastguard Worker
4854*35238bceSAndroid Build Coastguard Worker typedef typename In::In0 In0;
4855*35238bceSAndroid Build Coastguard Worker typedef typename In::In1 In1;
4856*35238bceSAndroid Build Coastguard Worker typedef typename In::In2 In2;
4857*35238bceSAndroid Build Coastguard Worker typedef typename In::In3 In3;
4858*35238bceSAndroid Build Coastguard Worker typedef typename Out::Out0 Out0;
4859*35238bceSAndroid Build Coastguard Worker typedef typename Out::Out1 Out1;
4860*35238bceSAndroid Build Coastguard Worker
4861*35238bceSAndroid Build Coastguard Worker const FloatFormat &fmt = getFormat();
4862*35238bceSAndroid Build Coastguard Worker const int inCount = numInputs<In>();
4863*35238bceSAndroid Build Coastguard Worker const int outCount = numOutputs<Out>();
4864*35238bceSAndroid Build Coastguard Worker const size_t numValues = (inCount > 0) ? inputs.in0.size() : 1;
4865*35238bceSAndroid Build Coastguard Worker Outputs<Out> outputs(numValues);
4866*35238bceSAndroid Build Coastguard Worker ShaderSpec spec;
4867*35238bceSAndroid Build Coastguard Worker const FloatFormat highpFmt = m_ctx.highpFormat;
4868*35238bceSAndroid Build Coastguard Worker const int maxMsgs = 100;
4869*35238bceSAndroid Build Coastguard Worker int numErrors = 0;
4870*35238bceSAndroid Build Coastguard Worker Environment env; // Hoisted out of the inner loop for optimization.
4871*35238bceSAndroid Build Coastguard Worker
4872*35238bceSAndroid Build Coastguard Worker switch (inCount)
4873*35238bceSAndroid Build Coastguard Worker {
4874*35238bceSAndroid Build Coastguard Worker case 4:
4875*35238bceSAndroid Build Coastguard Worker DE_ASSERT(inputs.in3.size() == numValues);
4876*35238bceSAndroid Build Coastguard Worker // Fallthrough
4877*35238bceSAndroid Build Coastguard Worker case 3:
4878*35238bceSAndroid Build Coastguard Worker DE_ASSERT(inputs.in2.size() == numValues);
4879*35238bceSAndroid Build Coastguard Worker // Fallthrough
4880*35238bceSAndroid Build Coastguard Worker case 2:
4881*35238bceSAndroid Build Coastguard Worker DE_ASSERT(inputs.in1.size() == numValues);
4882*35238bceSAndroid Build Coastguard Worker // Fallthrough
4883*35238bceSAndroid Build Coastguard Worker case 1:
4884*35238bceSAndroid Build Coastguard Worker DE_ASSERT(inputs.in0.size() == numValues);
4885*35238bceSAndroid Build Coastguard Worker // Fallthrough
4886*35238bceSAndroid Build Coastguard Worker default:
4887*35238bceSAndroid Build Coastguard Worker break;
4888*35238bceSAndroid Build Coastguard Worker }
4889*35238bceSAndroid Build Coastguard Worker
4890*35238bceSAndroid Build Coastguard Worker // Print out the statement and its definitions
4891*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Statement: " << stmt << TestLog::EndMessage;
4892*35238bceSAndroid Build Coastguard Worker {
4893*35238bceSAndroid Build Coastguard Worker ostringstream oss;
4894*35238bceSAndroid Build Coastguard Worker FuncSet funcs;
4895*35238bceSAndroid Build Coastguard Worker
4896*35238bceSAndroid Build Coastguard Worker stmt.getUsedFuncs(funcs);
4897*35238bceSAndroid Build Coastguard Worker for (FuncSet::const_iterator it = funcs.begin(); it != funcs.end(); ++it)
4898*35238bceSAndroid Build Coastguard Worker {
4899*35238bceSAndroid Build Coastguard Worker (*it)->printDefinition(oss);
4900*35238bceSAndroid Build Coastguard Worker }
4901*35238bceSAndroid Build Coastguard Worker if (!funcs.empty())
4902*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Reference definitions:\n" << oss.str() << TestLog::EndMessage;
4903*35238bceSAndroid Build Coastguard Worker }
4904*35238bceSAndroid Build Coastguard Worker
4905*35238bceSAndroid Build Coastguard Worker // Initialize ShaderSpec from precision, variables and statement.
4906*35238bceSAndroid Build Coastguard Worker {
4907*35238bceSAndroid Build Coastguard Worker ostringstream os;
4908*35238bceSAndroid Build Coastguard Worker os << "precision " << glu::getPrecisionName(m_ctx.precision) << " float;\n";
4909*35238bceSAndroid Build Coastguard Worker spec.globalDeclarations = os.str();
4910*35238bceSAndroid Build Coastguard Worker }
4911*35238bceSAndroid Build Coastguard Worker
4912*35238bceSAndroid Build Coastguard Worker spec.version = getContextTypeGLSLVersion(getRenderContext().getType());
4913*35238bceSAndroid Build Coastguard Worker
4914*35238bceSAndroid Build Coastguard Worker if (!m_extension.empty())
4915*35238bceSAndroid Build Coastguard Worker spec.globalDeclarations = "#extension " + m_extension + " : require\n";
4916*35238bceSAndroid Build Coastguard Worker
4917*35238bceSAndroid Build Coastguard Worker spec.inputs.resize(inCount);
4918*35238bceSAndroid Build Coastguard Worker
4919*35238bceSAndroid Build Coastguard Worker switch (inCount)
4920*35238bceSAndroid Build Coastguard Worker {
4921*35238bceSAndroid Build Coastguard Worker case 4:
4922*35238bceSAndroid Build Coastguard Worker spec.inputs[3] = makeSymbol(*variables.in3);
4923*35238bceSAndroid Build Coastguard Worker // Fallthrough
4924*35238bceSAndroid Build Coastguard Worker case 3:
4925*35238bceSAndroid Build Coastguard Worker spec.inputs[2] = makeSymbol(*variables.in2);
4926*35238bceSAndroid Build Coastguard Worker // Fallthrough
4927*35238bceSAndroid Build Coastguard Worker case 2:
4928*35238bceSAndroid Build Coastguard Worker spec.inputs[1] = makeSymbol(*variables.in1);
4929*35238bceSAndroid Build Coastguard Worker // Fallthrough
4930*35238bceSAndroid Build Coastguard Worker case 1:
4931*35238bceSAndroid Build Coastguard Worker spec.inputs[0] = makeSymbol(*variables.in0);
4932*35238bceSAndroid Build Coastguard Worker // Fallthrough
4933*35238bceSAndroid Build Coastguard Worker default:
4934*35238bceSAndroid Build Coastguard Worker break;
4935*35238bceSAndroid Build Coastguard Worker }
4936*35238bceSAndroid Build Coastguard Worker
4937*35238bceSAndroid Build Coastguard Worker spec.outputs.resize(outCount);
4938*35238bceSAndroid Build Coastguard Worker
4939*35238bceSAndroid Build Coastguard Worker switch (outCount)
4940*35238bceSAndroid Build Coastguard Worker {
4941*35238bceSAndroid Build Coastguard Worker case 2:
4942*35238bceSAndroid Build Coastguard Worker spec.outputs[1] = makeSymbol(*variables.out1); // Fallthrough
4943*35238bceSAndroid Build Coastguard Worker case 1:
4944*35238bceSAndroid Build Coastguard Worker spec.outputs[0] = makeSymbol(*variables.out0);
4945*35238bceSAndroid Build Coastguard Worker default:
4946*35238bceSAndroid Build Coastguard Worker break;
4947*35238bceSAndroid Build Coastguard Worker }
4948*35238bceSAndroid Build Coastguard Worker
4949*35238bceSAndroid Build Coastguard Worker spec.source = de::toString(stmt);
4950*35238bceSAndroid Build Coastguard Worker
4951*35238bceSAndroid Build Coastguard Worker // Run the shader with inputs.
4952*35238bceSAndroid Build Coastguard Worker {
4953*35238bceSAndroid Build Coastguard Worker UniquePtr<ShaderExecutor> executor(createExecutor(getRenderContext(), m_ctx.shaderType, spec));
4954*35238bceSAndroid Build Coastguard Worker const void *inputArr[] = {
4955*35238bceSAndroid Build Coastguard Worker &inputs.in0.front(),
4956*35238bceSAndroid Build Coastguard Worker &inputs.in1.front(),
4957*35238bceSAndroid Build Coastguard Worker &inputs.in2.front(),
4958*35238bceSAndroid Build Coastguard Worker &inputs.in3.front(),
4959*35238bceSAndroid Build Coastguard Worker };
4960*35238bceSAndroid Build Coastguard Worker void *outputArr[] = {
4961*35238bceSAndroid Build Coastguard Worker &outputs.out0.front(),
4962*35238bceSAndroid Build Coastguard Worker &outputs.out1.front(),
4963*35238bceSAndroid Build Coastguard Worker };
4964*35238bceSAndroid Build Coastguard Worker
4965*35238bceSAndroid Build Coastguard Worker executor->log(log());
4966*35238bceSAndroid Build Coastguard Worker if (!executor->isOk())
4967*35238bceSAndroid Build Coastguard Worker TCU_FAIL("Shader compilation failed");
4968*35238bceSAndroid Build Coastguard Worker
4969*35238bceSAndroid Build Coastguard Worker executor->useProgram();
4970*35238bceSAndroid Build Coastguard Worker executor->execute(int(numValues), inputArr, outputArr);
4971*35238bceSAndroid Build Coastguard Worker }
4972*35238bceSAndroid Build Coastguard Worker
4973*35238bceSAndroid Build Coastguard Worker // Initialize environment with unused values so we don't need to bind in inner loop.
4974*35238bceSAndroid Build Coastguard Worker {
4975*35238bceSAndroid Build Coastguard Worker const typename Traits<In0>::IVal in0;
4976*35238bceSAndroid Build Coastguard Worker const typename Traits<In1>::IVal in1;
4977*35238bceSAndroid Build Coastguard Worker const typename Traits<In2>::IVal in2;
4978*35238bceSAndroid Build Coastguard Worker const typename Traits<In3>::IVal in3;
4979*35238bceSAndroid Build Coastguard Worker const typename Traits<Out0>::IVal reference0;
4980*35238bceSAndroid Build Coastguard Worker const typename Traits<Out1>::IVal reference1;
4981*35238bceSAndroid Build Coastguard Worker
4982*35238bceSAndroid Build Coastguard Worker env.bind(*variables.in0, in0);
4983*35238bceSAndroid Build Coastguard Worker env.bind(*variables.in1, in1);
4984*35238bceSAndroid Build Coastguard Worker env.bind(*variables.in2, in2);
4985*35238bceSAndroid Build Coastguard Worker env.bind(*variables.in3, in3);
4986*35238bceSAndroid Build Coastguard Worker env.bind(*variables.out0, reference0);
4987*35238bceSAndroid Build Coastguard Worker env.bind(*variables.out1, reference1);
4988*35238bceSAndroid Build Coastguard Worker }
4989*35238bceSAndroid Build Coastguard Worker
4990*35238bceSAndroid Build Coastguard Worker // For each input tuple, compute output reference interval and compare
4991*35238bceSAndroid Build Coastguard Worker // shader output to the reference.
4992*35238bceSAndroid Build Coastguard Worker for (size_t valueNdx = 0; valueNdx < numValues; valueNdx++)
4993*35238bceSAndroid Build Coastguard Worker {
4994*35238bceSAndroid Build Coastguard Worker bool result = true;
4995*35238bceSAndroid Build Coastguard Worker bool inExpectedRange;
4996*35238bceSAndroid Build Coastguard Worker bool inWarningRange;
4997*35238bceSAndroid Build Coastguard Worker const char *failStr = "Fail";
4998*35238bceSAndroid Build Coastguard Worker typename Traits<Out0>::IVal reference0;
4999*35238bceSAndroid Build Coastguard Worker typename Traits<Out1>::IVal reference1;
5000*35238bceSAndroid Build Coastguard Worker
5001*35238bceSAndroid Build Coastguard Worker if (valueNdx % (size_t)TOUCH_WATCHDOG_VALUE_FREQUENCY == 0)
5002*35238bceSAndroid Build Coastguard Worker m_testCtx.touchWatchdog();
5003*35238bceSAndroid Build Coastguard Worker
5004*35238bceSAndroid Build Coastguard Worker env.lookup(*variables.in0) = convert<In0>(fmt, round(fmt, inputs.in0[valueNdx]));
5005*35238bceSAndroid Build Coastguard Worker env.lookup(*variables.in1) = convert<In1>(fmt, round(fmt, inputs.in1[valueNdx]));
5006*35238bceSAndroid Build Coastguard Worker env.lookup(*variables.in2) = convert<In2>(fmt, round(fmt, inputs.in2[valueNdx]));
5007*35238bceSAndroid Build Coastguard Worker env.lookup(*variables.in3) = convert<In3>(fmt, round(fmt, inputs.in3[valueNdx]));
5008*35238bceSAndroid Build Coastguard Worker
5009*35238bceSAndroid Build Coastguard Worker {
5010*35238bceSAndroid Build Coastguard Worker EvalContext ctx(fmt, m_ctx.precision, env);
5011*35238bceSAndroid Build Coastguard Worker stmt.execute(ctx);
5012*35238bceSAndroid Build Coastguard Worker }
5013*35238bceSAndroid Build Coastguard Worker
5014*35238bceSAndroid Build Coastguard Worker switch (outCount)
5015*35238bceSAndroid Build Coastguard Worker {
5016*35238bceSAndroid Build Coastguard Worker case 2:
5017*35238bceSAndroid Build Coastguard Worker reference1 = convert<Out1>(highpFmt, env.lookup(*variables.out1));
5018*35238bceSAndroid Build Coastguard Worker inExpectedRange = contains(reference1, outputs.out1[valueNdx]);
5019*35238bceSAndroid Build Coastguard Worker inWarningRange = containsWarning(reference1, outputs.out1[valueNdx]);
5020*35238bceSAndroid Build Coastguard Worker if (!inExpectedRange && inWarningRange)
5021*35238bceSAndroid Build Coastguard Worker {
5022*35238bceSAndroid Build Coastguard Worker m_status.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Shader output 1 has low-quality shader precision");
5023*35238bceSAndroid Build Coastguard Worker failStr = "QualityWarning";
5024*35238bceSAndroid Build Coastguard Worker result = false;
5025*35238bceSAndroid Build Coastguard Worker }
5026*35238bceSAndroid Build Coastguard Worker else if (!inExpectedRange)
5027*35238bceSAndroid Build Coastguard Worker {
5028*35238bceSAndroid Build Coastguard Worker m_status.addResult(QP_TEST_RESULT_FAIL, "Shader output 1 is outside acceptable range");
5029*35238bceSAndroid Build Coastguard Worker failStr = "Fail";
5030*35238bceSAndroid Build Coastguard Worker result = false;
5031*35238bceSAndroid Build Coastguard Worker }
5032*35238bceSAndroid Build Coastguard Worker // Fallthrough
5033*35238bceSAndroid Build Coastguard Worker
5034*35238bceSAndroid Build Coastguard Worker case 1:
5035*35238bceSAndroid Build Coastguard Worker reference0 = convert<Out0>(highpFmt, env.lookup(*variables.out0));
5036*35238bceSAndroid Build Coastguard Worker inExpectedRange = contains(reference0, outputs.out0[valueNdx]);
5037*35238bceSAndroid Build Coastguard Worker inWarningRange = containsWarning(reference0, outputs.out0[valueNdx]);
5038*35238bceSAndroid Build Coastguard Worker if (!inExpectedRange && inWarningRange)
5039*35238bceSAndroid Build Coastguard Worker {
5040*35238bceSAndroid Build Coastguard Worker m_status.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Shader output 0 has low-quality shader precision");
5041*35238bceSAndroid Build Coastguard Worker failStr = "QualityWarning";
5042*35238bceSAndroid Build Coastguard Worker result = false;
5043*35238bceSAndroid Build Coastguard Worker }
5044*35238bceSAndroid Build Coastguard Worker else if (!inExpectedRange)
5045*35238bceSAndroid Build Coastguard Worker {
5046*35238bceSAndroid Build Coastguard Worker m_status.addResult(QP_TEST_RESULT_FAIL, "Shader output 0 is outside acceptable range");
5047*35238bceSAndroid Build Coastguard Worker failStr = "Fail";
5048*35238bceSAndroid Build Coastguard Worker result = false;
5049*35238bceSAndroid Build Coastguard Worker }
5050*35238bceSAndroid Build Coastguard Worker
5051*35238bceSAndroid Build Coastguard Worker default:
5052*35238bceSAndroid Build Coastguard Worker break;
5053*35238bceSAndroid Build Coastguard Worker }
5054*35238bceSAndroid Build Coastguard Worker
5055*35238bceSAndroid Build Coastguard Worker if (!result)
5056*35238bceSAndroid Build Coastguard Worker ++numErrors;
5057*35238bceSAndroid Build Coastguard Worker
5058*35238bceSAndroid Build Coastguard Worker if ((!result && numErrors <= maxMsgs) || GLS_LOG_ALL_RESULTS)
5059*35238bceSAndroid Build Coastguard Worker {
5060*35238bceSAndroid Build Coastguard Worker MessageBuilder builder = log().message();
5061*35238bceSAndroid Build Coastguard Worker
5062*35238bceSAndroid Build Coastguard Worker builder << (result ? "Passed" : failStr) << " sample:\n";
5063*35238bceSAndroid Build Coastguard Worker
5064*35238bceSAndroid Build Coastguard Worker if (inCount > 0)
5065*35238bceSAndroid Build Coastguard Worker {
5066*35238bceSAndroid Build Coastguard Worker builder << "\t" << variables.in0->getName() << " = " << valueToString(highpFmt, inputs.in0[valueNdx])
5067*35238bceSAndroid Build Coastguard Worker << "\n";
5068*35238bceSAndroid Build Coastguard Worker }
5069*35238bceSAndroid Build Coastguard Worker
5070*35238bceSAndroid Build Coastguard Worker if (inCount > 1)
5071*35238bceSAndroid Build Coastguard Worker {
5072*35238bceSAndroid Build Coastguard Worker builder << "\t" << variables.in1->getName() << " = " << valueToString(highpFmt, inputs.in1[valueNdx])
5073*35238bceSAndroid Build Coastguard Worker << "\n";
5074*35238bceSAndroid Build Coastguard Worker }
5075*35238bceSAndroid Build Coastguard Worker
5076*35238bceSAndroid Build Coastguard Worker if (inCount > 2)
5077*35238bceSAndroid Build Coastguard Worker {
5078*35238bceSAndroid Build Coastguard Worker builder << "\t" << variables.in2->getName() << " = " << valueToString(highpFmt, inputs.in2[valueNdx])
5079*35238bceSAndroid Build Coastguard Worker << "\n";
5080*35238bceSAndroid Build Coastguard Worker }
5081*35238bceSAndroid Build Coastguard Worker
5082*35238bceSAndroid Build Coastguard Worker if (inCount > 3)
5083*35238bceSAndroid Build Coastguard Worker {
5084*35238bceSAndroid Build Coastguard Worker builder << "\t" << variables.in3->getName() << " = " << valueToString(highpFmt, inputs.in3[valueNdx])
5085*35238bceSAndroid Build Coastguard Worker << "\n";
5086*35238bceSAndroid Build Coastguard Worker }
5087*35238bceSAndroid Build Coastguard Worker
5088*35238bceSAndroid Build Coastguard Worker if (outCount > 0)
5089*35238bceSAndroid Build Coastguard Worker {
5090*35238bceSAndroid Build Coastguard Worker builder << "\t" << variables.out0->getName() << " = " << valueToString(highpFmt, outputs.out0[valueNdx])
5091*35238bceSAndroid Build Coastguard Worker << "\n"
5092*35238bceSAndroid Build Coastguard Worker << "\tExpected range: " << intervalToString<typename Out::Out0>(highpFmt, reference0) << "\n";
5093*35238bceSAndroid Build Coastguard Worker }
5094*35238bceSAndroid Build Coastguard Worker
5095*35238bceSAndroid Build Coastguard Worker if (outCount > 1)
5096*35238bceSAndroid Build Coastguard Worker {
5097*35238bceSAndroid Build Coastguard Worker builder << "\t" << variables.out1->getName() << " = " << valueToString(highpFmt, outputs.out1[valueNdx])
5098*35238bceSAndroid Build Coastguard Worker << "\n"
5099*35238bceSAndroid Build Coastguard Worker << "\tExpected range: " << intervalToString<typename Out::Out1>(highpFmt, reference1) << "\n";
5100*35238bceSAndroid Build Coastguard Worker }
5101*35238bceSAndroid Build Coastguard Worker
5102*35238bceSAndroid Build Coastguard Worker builder << TestLog::EndMessage;
5103*35238bceSAndroid Build Coastguard Worker }
5104*35238bceSAndroid Build Coastguard Worker }
5105*35238bceSAndroid Build Coastguard Worker
5106*35238bceSAndroid Build Coastguard Worker if (numErrors > maxMsgs)
5107*35238bceSAndroid Build Coastguard Worker {
5108*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "(Skipped " << (numErrors - maxMsgs) << " messages.)" << TestLog::EndMessage;
5109*35238bceSAndroid Build Coastguard Worker }
5110*35238bceSAndroid Build Coastguard Worker
5111*35238bceSAndroid Build Coastguard Worker if (numErrors == 0)
5112*35238bceSAndroid Build Coastguard Worker {
5113*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "All " << numValues << " inputs passed." << TestLog::EndMessage;
5114*35238bceSAndroid Build Coastguard Worker }
5115*35238bceSAndroid Build Coastguard Worker else
5116*35238bceSAndroid Build Coastguard Worker {
5117*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << numErrors << "/" << numValues << " inputs failed or had quality warnings."
5118*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
5119*35238bceSAndroid Build Coastguard Worker }
5120*35238bceSAndroid Build Coastguard Worker }
5121*35238bceSAndroid Build Coastguard Worker
5122*35238bceSAndroid Build Coastguard Worker template <typename T>
5123*35238bceSAndroid Build Coastguard Worker struct InputLess
5124*35238bceSAndroid Build Coastguard Worker {
operator ()deqp::gls::BuiltinPrecisionTests::InputLess5125*35238bceSAndroid Build Coastguard Worker bool operator()(const T &val1, const T &val2) const
5126*35238bceSAndroid Build Coastguard Worker {
5127*35238bceSAndroid Build Coastguard Worker return val1 < val2;
5128*35238bceSAndroid Build Coastguard Worker }
5129*35238bceSAndroid Build Coastguard Worker };
5130*35238bceSAndroid Build Coastguard Worker
5131*35238bceSAndroid Build Coastguard Worker template <typename T>
inputLess(const T & val1,const T & val2)5132*35238bceSAndroid Build Coastguard Worker bool inputLess(const T &val1, const T &val2)
5133*35238bceSAndroid Build Coastguard Worker {
5134*35238bceSAndroid Build Coastguard Worker return InputLess<T>()(val1, val2);
5135*35238bceSAndroid Build Coastguard Worker }
5136*35238bceSAndroid Build Coastguard Worker
5137*35238bceSAndroid Build Coastguard Worker template <>
5138*35238bceSAndroid Build Coastguard Worker struct InputLess<float>
5139*35238bceSAndroid Build Coastguard Worker {
operator ()deqp::gls::BuiltinPrecisionTests::InputLess5140*35238bceSAndroid Build Coastguard Worker bool operator()(const float &val1, const float &val2) const
5141*35238bceSAndroid Build Coastguard Worker {
5142*35238bceSAndroid Build Coastguard Worker if (deIsNaN(val1))
5143*35238bceSAndroid Build Coastguard Worker return false;
5144*35238bceSAndroid Build Coastguard Worker if (deIsNaN(val2))
5145*35238bceSAndroid Build Coastguard Worker return true;
5146*35238bceSAndroid Build Coastguard Worker return val1 < val2;
5147*35238bceSAndroid Build Coastguard Worker }
5148*35238bceSAndroid Build Coastguard Worker };
5149*35238bceSAndroid Build Coastguard Worker
5150*35238bceSAndroid Build Coastguard Worker template <typename T, int Size>
5151*35238bceSAndroid Build Coastguard Worker struct InputLess<Vector<T, Size>>
5152*35238bceSAndroid Build Coastguard Worker {
operator ()deqp::gls::BuiltinPrecisionTests::InputLess5153*35238bceSAndroid Build Coastguard Worker bool operator()(const Vector<T, Size> &vec1, const Vector<T, Size> &vec2) const
5154*35238bceSAndroid Build Coastguard Worker {
5155*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ++ndx)
5156*35238bceSAndroid Build Coastguard Worker {
5157*35238bceSAndroid Build Coastguard Worker if (inputLess(vec1[ndx], vec2[ndx]))
5158*35238bceSAndroid Build Coastguard Worker return true;
5159*35238bceSAndroid Build Coastguard Worker if (inputLess(vec2[ndx], vec1[ndx]))
5160*35238bceSAndroid Build Coastguard Worker return false;
5161*35238bceSAndroid Build Coastguard Worker }
5162*35238bceSAndroid Build Coastguard Worker
5163*35238bceSAndroid Build Coastguard Worker return false;
5164*35238bceSAndroid Build Coastguard Worker }
5165*35238bceSAndroid Build Coastguard Worker };
5166*35238bceSAndroid Build Coastguard Worker
5167*35238bceSAndroid Build Coastguard Worker template <typename T, int Rows, int Cols>
5168*35238bceSAndroid Build Coastguard Worker struct InputLess<Matrix<T, Rows, Cols>>
5169*35238bceSAndroid Build Coastguard Worker {
operator ()deqp::gls::BuiltinPrecisionTests::InputLess5170*35238bceSAndroid Build Coastguard Worker bool operator()(const Matrix<T, Rows, Cols> &mat1, const Matrix<T, Rows, Cols> &mat2) const
5171*35238bceSAndroid Build Coastguard Worker {
5172*35238bceSAndroid Build Coastguard Worker for (int col = 0; col < Cols; ++col)
5173*35238bceSAndroid Build Coastguard Worker {
5174*35238bceSAndroid Build Coastguard Worker if (inputLess(mat1[col], mat2[col]))
5175*35238bceSAndroid Build Coastguard Worker return true;
5176*35238bceSAndroid Build Coastguard Worker if (inputLess(mat2[col], mat1[col]))
5177*35238bceSAndroid Build Coastguard Worker return false;
5178*35238bceSAndroid Build Coastguard Worker }
5179*35238bceSAndroid Build Coastguard Worker
5180*35238bceSAndroid Build Coastguard Worker return false;
5181*35238bceSAndroid Build Coastguard Worker }
5182*35238bceSAndroid Build Coastguard Worker };
5183*35238bceSAndroid Build Coastguard Worker
5184*35238bceSAndroid Build Coastguard Worker template <typename In>
5185*35238bceSAndroid Build Coastguard Worker struct InTuple : public Tuple4<typename In::In0, typename In::In1, typename In::In2, typename In::In3>
5186*35238bceSAndroid Build Coastguard Worker {
InTupledeqp::gls::BuiltinPrecisionTests::InTuple5187*35238bceSAndroid Build Coastguard Worker InTuple(const typename In::In0 &in0, const typename In::In1 &in1, const typename In::In2 &in2,
5188*35238bceSAndroid Build Coastguard Worker const typename In::In3 &in3)
5189*35238bceSAndroid Build Coastguard Worker : Tuple4<typename In::In0, typename In::In1, typename In::In2, typename In::In3>(in0, in1, in2, in3)
5190*35238bceSAndroid Build Coastguard Worker {
5191*35238bceSAndroid Build Coastguard Worker }
5192*35238bceSAndroid Build Coastguard Worker };
5193*35238bceSAndroid Build Coastguard Worker
5194*35238bceSAndroid Build Coastguard Worker template <typename In>
5195*35238bceSAndroid Build Coastguard Worker struct InputLess<InTuple<In>>
5196*35238bceSAndroid Build Coastguard Worker {
operator ()deqp::gls::BuiltinPrecisionTests::InputLess5197*35238bceSAndroid Build Coastguard Worker bool operator()(const InTuple<In> &in1, const InTuple<In> &in2) const
5198*35238bceSAndroid Build Coastguard Worker {
5199*35238bceSAndroid Build Coastguard Worker if (inputLess(in1.a, in2.a))
5200*35238bceSAndroid Build Coastguard Worker return true;
5201*35238bceSAndroid Build Coastguard Worker if (inputLess(in2.a, in1.a))
5202*35238bceSAndroid Build Coastguard Worker return false;
5203*35238bceSAndroid Build Coastguard Worker if (inputLess(in1.b, in2.b))
5204*35238bceSAndroid Build Coastguard Worker return true;
5205*35238bceSAndroid Build Coastguard Worker if (inputLess(in2.b, in1.b))
5206*35238bceSAndroid Build Coastguard Worker return false;
5207*35238bceSAndroid Build Coastguard Worker if (inputLess(in1.c, in2.c))
5208*35238bceSAndroid Build Coastguard Worker return true;
5209*35238bceSAndroid Build Coastguard Worker if (inputLess(in2.c, in1.c))
5210*35238bceSAndroid Build Coastguard Worker return false;
5211*35238bceSAndroid Build Coastguard Worker if (inputLess(in1.d, in2.d))
5212*35238bceSAndroid Build Coastguard Worker return true;
5213*35238bceSAndroid Build Coastguard Worker return false;
5214*35238bceSAndroid Build Coastguard Worker }
5215*35238bceSAndroid Build Coastguard Worker };
5216*35238bceSAndroid Build Coastguard Worker
5217*35238bceSAndroid Build Coastguard Worker template <typename In>
generateInputs(const Samplings<In> & samplings,const FloatFormat & floatFormat,Precision intPrecision,size_t numSamples,Random & rnd)5218*35238bceSAndroid Build Coastguard Worker Inputs<In> generateInputs(const Samplings<In> &samplings, const FloatFormat &floatFormat, Precision intPrecision,
5219*35238bceSAndroid Build Coastguard Worker size_t numSamples, Random &rnd)
5220*35238bceSAndroid Build Coastguard Worker {
5221*35238bceSAndroid Build Coastguard Worker Inputs<In> ret;
5222*35238bceSAndroid Build Coastguard Worker Inputs<In> fixedInputs;
5223*35238bceSAndroid Build Coastguard Worker set<InTuple<In>, InputLess<InTuple<In>>> seenInputs;
5224*35238bceSAndroid Build Coastguard Worker
5225*35238bceSAndroid Build Coastguard Worker samplings.in0.genFixeds(floatFormat, fixedInputs.in0);
5226*35238bceSAndroid Build Coastguard Worker samplings.in1.genFixeds(floatFormat, fixedInputs.in1);
5227*35238bceSAndroid Build Coastguard Worker samplings.in2.genFixeds(floatFormat, fixedInputs.in2);
5228*35238bceSAndroid Build Coastguard Worker samplings.in3.genFixeds(floatFormat, fixedInputs.in3);
5229*35238bceSAndroid Build Coastguard Worker
5230*35238bceSAndroid Build Coastguard Worker for (size_t ndx0 = 0; ndx0 < fixedInputs.in0.size(); ++ndx0)
5231*35238bceSAndroid Build Coastguard Worker {
5232*35238bceSAndroid Build Coastguard Worker for (size_t ndx1 = 0; ndx1 < fixedInputs.in1.size(); ++ndx1)
5233*35238bceSAndroid Build Coastguard Worker {
5234*35238bceSAndroid Build Coastguard Worker for (size_t ndx2 = 0; ndx2 < fixedInputs.in2.size(); ++ndx2)
5235*35238bceSAndroid Build Coastguard Worker {
5236*35238bceSAndroid Build Coastguard Worker for (size_t ndx3 = 0; ndx3 < fixedInputs.in3.size(); ++ndx3)
5237*35238bceSAndroid Build Coastguard Worker {
5238*35238bceSAndroid Build Coastguard Worker const InTuple<In> tuple(fixedInputs.in0[ndx0], fixedInputs.in1[ndx1], fixedInputs.in2[ndx2],
5239*35238bceSAndroid Build Coastguard Worker fixedInputs.in3[ndx3]);
5240*35238bceSAndroid Build Coastguard Worker
5241*35238bceSAndroid Build Coastguard Worker seenInputs.insert(tuple);
5242*35238bceSAndroid Build Coastguard Worker ret.in0.push_back(tuple.a);
5243*35238bceSAndroid Build Coastguard Worker ret.in1.push_back(tuple.b);
5244*35238bceSAndroid Build Coastguard Worker ret.in2.push_back(tuple.c);
5245*35238bceSAndroid Build Coastguard Worker ret.in3.push_back(tuple.d);
5246*35238bceSAndroid Build Coastguard Worker }
5247*35238bceSAndroid Build Coastguard Worker }
5248*35238bceSAndroid Build Coastguard Worker }
5249*35238bceSAndroid Build Coastguard Worker }
5250*35238bceSAndroid Build Coastguard Worker
5251*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < numSamples; ++ndx)
5252*35238bceSAndroid Build Coastguard Worker {
5253*35238bceSAndroid Build Coastguard Worker const typename In::In0 in0 = samplings.in0.genRandom(floatFormat, intPrecision, rnd);
5254*35238bceSAndroid Build Coastguard Worker const typename In::In1 in1 = samplings.in1.genRandom(floatFormat, intPrecision, rnd);
5255*35238bceSAndroid Build Coastguard Worker const typename In::In2 in2 = samplings.in2.genRandom(floatFormat, intPrecision, rnd);
5256*35238bceSAndroid Build Coastguard Worker const typename In::In3 in3 = samplings.in3.genRandom(floatFormat, intPrecision, rnd);
5257*35238bceSAndroid Build Coastguard Worker const InTuple<In> tuple(in0, in1, in2, in3);
5258*35238bceSAndroid Build Coastguard Worker
5259*35238bceSAndroid Build Coastguard Worker if (de::contains(seenInputs, tuple))
5260*35238bceSAndroid Build Coastguard Worker continue;
5261*35238bceSAndroid Build Coastguard Worker
5262*35238bceSAndroid Build Coastguard Worker seenInputs.insert(tuple);
5263*35238bceSAndroid Build Coastguard Worker ret.in0.push_back(in0);
5264*35238bceSAndroid Build Coastguard Worker ret.in1.push_back(in1);
5265*35238bceSAndroid Build Coastguard Worker ret.in2.push_back(in2);
5266*35238bceSAndroid Build Coastguard Worker ret.in3.push_back(in3);
5267*35238bceSAndroid Build Coastguard Worker }
5268*35238bceSAndroid Build Coastguard Worker
5269*35238bceSAndroid Build Coastguard Worker return ret;
5270*35238bceSAndroid Build Coastguard Worker }
5271*35238bceSAndroid Build Coastguard Worker
5272*35238bceSAndroid Build Coastguard Worker class FuncCaseBase : public PrecisionCase
5273*35238bceSAndroid Build Coastguard Worker {
5274*35238bceSAndroid Build Coastguard Worker public:
5275*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
5276*35238bceSAndroid Build Coastguard Worker
5277*35238bceSAndroid Build Coastguard Worker protected:
FuncCaseBase(const Context & context,const string & name,const FuncBase & func)5278*35238bceSAndroid Build Coastguard Worker FuncCaseBase(const Context &context, const string &name, const FuncBase &func)
5279*35238bceSAndroid Build Coastguard Worker : PrecisionCase(context, name, func.getRequiredExtension(context.renderContext))
5280*35238bceSAndroid Build Coastguard Worker {
5281*35238bceSAndroid Build Coastguard Worker }
5282*35238bceSAndroid Build Coastguard Worker };
5283*35238bceSAndroid Build Coastguard Worker
iterate(void)5284*35238bceSAndroid Build Coastguard Worker IterateResult FuncCaseBase::iterate(void)
5285*35238bceSAndroid Build Coastguard Worker {
5286*35238bceSAndroid Build Coastguard Worker MovePtr<ContextInfo> info(ContextInfo::create(getRenderContext()));
5287*35238bceSAndroid Build Coastguard Worker
5288*35238bceSAndroid Build Coastguard Worker if (!m_extension.empty() && !info->isExtensionSupported(m_extension.c_str()) &&
5289*35238bceSAndroid Build Coastguard Worker !glu::contextSupports(getRenderContext().getType(), glu::ApiType::core(4, 5)))
5290*35238bceSAndroid Build Coastguard Worker throw NotSupportedError("Unsupported extension: " + m_extension);
5291*35238bceSAndroid Build Coastguard Worker
5292*35238bceSAndroid Build Coastguard Worker runTest();
5293*35238bceSAndroid Build Coastguard Worker
5294*35238bceSAndroid Build Coastguard Worker m_status.setTestContextResult(m_testCtx);
5295*35238bceSAndroid Build Coastguard Worker return STOP;
5296*35238bceSAndroid Build Coastguard Worker }
5297*35238bceSAndroid Build Coastguard Worker
5298*35238bceSAndroid Build Coastguard Worker template <typename Sig>
5299*35238bceSAndroid Build Coastguard Worker class FuncCase : public FuncCaseBase
5300*35238bceSAndroid Build Coastguard Worker {
5301*35238bceSAndroid Build Coastguard Worker public:
5302*35238bceSAndroid Build Coastguard Worker typedef Func<Sig> CaseFunc;
5303*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Ret Ret;
5304*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg0 Arg0;
5305*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg1 Arg1;
5306*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg2 Arg2;
5307*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg3 Arg3;
5308*35238bceSAndroid Build Coastguard Worker typedef InTypes<Arg0, Arg1, Arg2, Arg3> In;
5309*35238bceSAndroid Build Coastguard Worker typedef OutTypes<Ret> Out;
5310*35238bceSAndroid Build Coastguard Worker
FuncCase(const Context & context,const string & name,const CaseFunc & func)5311*35238bceSAndroid Build Coastguard Worker FuncCase(const Context &context, const string &name, const CaseFunc &func)
5312*35238bceSAndroid Build Coastguard Worker : FuncCaseBase(context, name, func)
5313*35238bceSAndroid Build Coastguard Worker , m_func(func)
5314*35238bceSAndroid Build Coastguard Worker {
5315*35238bceSAndroid Build Coastguard Worker }
5316*35238bceSAndroid Build Coastguard Worker
5317*35238bceSAndroid Build Coastguard Worker protected:
5318*35238bceSAndroid Build Coastguard Worker void runTest(void);
5319*35238bceSAndroid Build Coastguard Worker
getSamplings(void)5320*35238bceSAndroid Build Coastguard Worker virtual const Samplings<In> &getSamplings(void)
5321*35238bceSAndroid Build Coastguard Worker {
5322*35238bceSAndroid Build Coastguard Worker return instance<DefaultSamplings<In>>();
5323*35238bceSAndroid Build Coastguard Worker }
5324*35238bceSAndroid Build Coastguard Worker
5325*35238bceSAndroid Build Coastguard Worker private:
5326*35238bceSAndroid Build Coastguard Worker const CaseFunc &m_func;
5327*35238bceSAndroid Build Coastguard Worker };
5328*35238bceSAndroid Build Coastguard Worker
5329*35238bceSAndroid Build Coastguard Worker template <typename Sig>
runTest(void)5330*35238bceSAndroid Build Coastguard Worker void FuncCase<Sig>::runTest(void)
5331*35238bceSAndroid Build Coastguard Worker {
5332*35238bceSAndroid Build Coastguard Worker const Inputs<In> inputs(
5333*35238bceSAndroid Build Coastguard Worker generateInputs(getSamplings(), m_ctx.floatFormat, m_ctx.precision, m_ctx.numRandoms, m_rnd));
5334*35238bceSAndroid Build Coastguard Worker Variables<In, Out> variables;
5335*35238bceSAndroid Build Coastguard Worker
5336*35238bceSAndroid Build Coastguard Worker variables.out0 = variable<Ret>("out0");
5337*35238bceSAndroid Build Coastguard Worker variables.out1 = variable<Void>("out1");
5338*35238bceSAndroid Build Coastguard Worker variables.in0 = variable<Arg0>("in0");
5339*35238bceSAndroid Build Coastguard Worker variables.in1 = variable<Arg1>("in1");
5340*35238bceSAndroid Build Coastguard Worker variables.in2 = variable<Arg2>("in2");
5341*35238bceSAndroid Build Coastguard Worker variables.in3 = variable<Arg3>("in3");
5342*35238bceSAndroid Build Coastguard Worker
5343*35238bceSAndroid Build Coastguard Worker {
5344*35238bceSAndroid Build Coastguard Worker ExprP<Ret> expr = applyVar(m_func, variables.in0, variables.in1, variables.in2, variables.in3);
5345*35238bceSAndroid Build Coastguard Worker StatementP stmt = variableAssignment(variables.out0, expr);
5346*35238bceSAndroid Build Coastguard Worker
5347*35238bceSAndroid Build Coastguard Worker this->testStatement(variables, inputs, *stmt);
5348*35238bceSAndroid Build Coastguard Worker }
5349*35238bceSAndroid Build Coastguard Worker }
5350*35238bceSAndroid Build Coastguard Worker
5351*35238bceSAndroid Build Coastguard Worker template <typename Sig>
5352*35238bceSAndroid Build Coastguard Worker class InOutFuncCase : public FuncCaseBase
5353*35238bceSAndroid Build Coastguard Worker {
5354*35238bceSAndroid Build Coastguard Worker public:
5355*35238bceSAndroid Build Coastguard Worker typedef Func<Sig> CaseFunc;
5356*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Ret Ret;
5357*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg0 Arg0;
5358*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg1 Arg1;
5359*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg2 Arg2;
5360*35238bceSAndroid Build Coastguard Worker typedef typename Sig::Arg3 Arg3;
5361*35238bceSAndroid Build Coastguard Worker typedef InTypes<Arg0, Arg2, Arg3> In;
5362*35238bceSAndroid Build Coastguard Worker typedef OutTypes<Ret, Arg1> Out;
5363*35238bceSAndroid Build Coastguard Worker
InOutFuncCase(const Context & context,const string & name,const CaseFunc & func)5364*35238bceSAndroid Build Coastguard Worker InOutFuncCase(const Context &context, const string &name, const CaseFunc &func)
5365*35238bceSAndroid Build Coastguard Worker : FuncCaseBase(context, name, func)
5366*35238bceSAndroid Build Coastguard Worker , m_func(func)
5367*35238bceSAndroid Build Coastguard Worker {
5368*35238bceSAndroid Build Coastguard Worker }
5369*35238bceSAndroid Build Coastguard Worker
5370*35238bceSAndroid Build Coastguard Worker protected:
5371*35238bceSAndroid Build Coastguard Worker void runTest(void);
5372*35238bceSAndroid Build Coastguard Worker
getSamplings(void)5373*35238bceSAndroid Build Coastguard Worker virtual const Samplings<In> &getSamplings(void)
5374*35238bceSAndroid Build Coastguard Worker {
5375*35238bceSAndroid Build Coastguard Worker return instance<DefaultSamplings<In>>();
5376*35238bceSAndroid Build Coastguard Worker }
5377*35238bceSAndroid Build Coastguard Worker
5378*35238bceSAndroid Build Coastguard Worker private:
5379*35238bceSAndroid Build Coastguard Worker const CaseFunc &m_func;
5380*35238bceSAndroid Build Coastguard Worker };
5381*35238bceSAndroid Build Coastguard Worker
5382*35238bceSAndroid Build Coastguard Worker template <typename Sig>
runTest(void)5383*35238bceSAndroid Build Coastguard Worker void InOutFuncCase<Sig>::runTest(void)
5384*35238bceSAndroid Build Coastguard Worker {
5385*35238bceSAndroid Build Coastguard Worker const Inputs<In> inputs(
5386*35238bceSAndroid Build Coastguard Worker generateInputs(getSamplings(), m_ctx.floatFormat, m_ctx.precision, m_ctx.numRandoms, m_rnd));
5387*35238bceSAndroid Build Coastguard Worker Variables<In, Out> variables;
5388*35238bceSAndroid Build Coastguard Worker
5389*35238bceSAndroid Build Coastguard Worker variables.out0 = variable<Ret>("out0");
5390*35238bceSAndroid Build Coastguard Worker variables.out1 = variable<Arg1>("out1");
5391*35238bceSAndroid Build Coastguard Worker variables.in0 = variable<Arg0>("in0");
5392*35238bceSAndroid Build Coastguard Worker variables.in1 = variable<Arg2>("in1");
5393*35238bceSAndroid Build Coastguard Worker variables.in2 = variable<Arg3>("in2");
5394*35238bceSAndroid Build Coastguard Worker variables.in3 = variable<Void>("in3");
5395*35238bceSAndroid Build Coastguard Worker
5396*35238bceSAndroid Build Coastguard Worker {
5397*35238bceSAndroid Build Coastguard Worker ExprP<Ret> expr = applyVar(m_func, variables.in0, variables.out1, variables.in1, variables.in2);
5398*35238bceSAndroid Build Coastguard Worker StatementP stmt = variableAssignment(variables.out0, expr);
5399*35238bceSAndroid Build Coastguard Worker
5400*35238bceSAndroid Build Coastguard Worker this->testStatement(variables, inputs, *stmt);
5401*35238bceSAndroid Build Coastguard Worker }
5402*35238bceSAndroid Build Coastguard Worker }
5403*35238bceSAndroid Build Coastguard Worker
5404*35238bceSAndroid Build Coastguard Worker template <typename Sig>
createFuncCase(const Context & context,const string & name,const Func<Sig> & func)5405*35238bceSAndroid Build Coastguard Worker PrecisionCase *createFuncCase(const Context &context, const string &name, const Func<Sig> &func)
5406*35238bceSAndroid Build Coastguard Worker {
5407*35238bceSAndroid Build Coastguard Worker switch (func.getOutParamIndex())
5408*35238bceSAndroid Build Coastguard Worker {
5409*35238bceSAndroid Build Coastguard Worker case -1:
5410*35238bceSAndroid Build Coastguard Worker return new FuncCase<Sig>(context, name, func);
5411*35238bceSAndroid Build Coastguard Worker case 1:
5412*35238bceSAndroid Build Coastguard Worker return new InOutFuncCase<Sig>(context, name, func);
5413*35238bceSAndroid Build Coastguard Worker default:
5414*35238bceSAndroid Build Coastguard Worker DE_FATAL("Impossible");
5415*35238bceSAndroid Build Coastguard Worker }
5416*35238bceSAndroid Build Coastguard Worker return DE_NULL;
5417*35238bceSAndroid Build Coastguard Worker }
5418*35238bceSAndroid Build Coastguard Worker
5419*35238bceSAndroid Build Coastguard Worker class CaseFactory
5420*35238bceSAndroid Build Coastguard Worker {
5421*35238bceSAndroid Build Coastguard Worker public:
~CaseFactory(void)5422*35238bceSAndroid Build Coastguard Worker virtual ~CaseFactory(void)
5423*35238bceSAndroid Build Coastguard Worker {
5424*35238bceSAndroid Build Coastguard Worker }
5425*35238bceSAndroid Build Coastguard Worker virtual MovePtr<TestNode> createCase(const Context &ctx) const = 0;
5426*35238bceSAndroid Build Coastguard Worker virtual string getName(void) const = 0;
5427*35238bceSAndroid Build Coastguard Worker virtual string getDesc(void) const = 0;
5428*35238bceSAndroid Build Coastguard Worker };
5429*35238bceSAndroid Build Coastguard Worker
5430*35238bceSAndroid Build Coastguard Worker class FuncCaseFactory : public CaseFactory
5431*35238bceSAndroid Build Coastguard Worker {
5432*35238bceSAndroid Build Coastguard Worker public:
5433*35238bceSAndroid Build Coastguard Worker virtual const FuncBase &getFunc(void) const = 0;
5434*35238bceSAndroid Build Coastguard Worker
getName(void) const5435*35238bceSAndroid Build Coastguard Worker string getName(void) const
5436*35238bceSAndroid Build Coastguard Worker {
5437*35238bceSAndroid Build Coastguard Worker return de::toLower(getFunc().getName());
5438*35238bceSAndroid Build Coastguard Worker }
5439*35238bceSAndroid Build Coastguard Worker
getDesc(void) const5440*35238bceSAndroid Build Coastguard Worker string getDesc(void) const
5441*35238bceSAndroid Build Coastguard Worker {
5442*35238bceSAndroid Build Coastguard Worker return "Function '" + getFunc().getName() + "'";
5443*35238bceSAndroid Build Coastguard Worker }
5444*35238bceSAndroid Build Coastguard Worker };
5445*35238bceSAndroid Build Coastguard Worker
5446*35238bceSAndroid Build Coastguard Worker template <typename Sig>
5447*35238bceSAndroid Build Coastguard Worker class GenFuncCaseFactory : public CaseFactory
5448*35238bceSAndroid Build Coastguard Worker {
5449*35238bceSAndroid Build Coastguard Worker public:
GenFuncCaseFactory(const GenFuncs<Sig> & funcs,const string & name)5450*35238bceSAndroid Build Coastguard Worker GenFuncCaseFactory(const GenFuncs<Sig> &funcs, const string &name) : m_funcs(funcs), m_name(de::toLower(name))
5451*35238bceSAndroid Build Coastguard Worker {
5452*35238bceSAndroid Build Coastguard Worker }
5453*35238bceSAndroid Build Coastguard Worker
createCase(const Context & ctx) const5454*35238bceSAndroid Build Coastguard Worker MovePtr<TestNode> createCase(const Context &ctx) const
5455*35238bceSAndroid Build Coastguard Worker {
5456*35238bceSAndroid Build Coastguard Worker TestCaseGroup *group = new TestCaseGroup(ctx.testContext, ctx.name.c_str(), ctx.name.c_str());
5457*35238bceSAndroid Build Coastguard Worker
5458*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "scalar", m_funcs.func));
5459*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "vec2", m_funcs.func2));
5460*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "vec3", m_funcs.func3));
5461*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "vec4", m_funcs.func4));
5462*35238bceSAndroid Build Coastguard Worker
5463*35238bceSAndroid Build Coastguard Worker return MovePtr<TestNode>(group);
5464*35238bceSAndroid Build Coastguard Worker }
5465*35238bceSAndroid Build Coastguard Worker
getName(void) const5466*35238bceSAndroid Build Coastguard Worker string getName(void) const
5467*35238bceSAndroid Build Coastguard Worker {
5468*35238bceSAndroid Build Coastguard Worker return m_name;
5469*35238bceSAndroid Build Coastguard Worker }
5470*35238bceSAndroid Build Coastguard Worker
getDesc(void) const5471*35238bceSAndroid Build Coastguard Worker string getDesc(void) const
5472*35238bceSAndroid Build Coastguard Worker {
5473*35238bceSAndroid Build Coastguard Worker return "Function '" + m_funcs.func.getName() + "'";
5474*35238bceSAndroid Build Coastguard Worker }
5475*35238bceSAndroid Build Coastguard Worker
5476*35238bceSAndroid Build Coastguard Worker private:
5477*35238bceSAndroid Build Coastguard Worker const GenFuncs<Sig> m_funcs;
5478*35238bceSAndroid Build Coastguard Worker string m_name;
5479*35238bceSAndroid Build Coastguard Worker };
5480*35238bceSAndroid Build Coastguard Worker
5481*35238bceSAndroid Build Coastguard Worker template <template <int> class GenF>
5482*35238bceSAndroid Build Coastguard Worker class TemplateFuncCaseFactory : public FuncCaseFactory
5483*35238bceSAndroid Build Coastguard Worker {
5484*35238bceSAndroid Build Coastguard Worker public:
createCase(const Context & ctx) const5485*35238bceSAndroid Build Coastguard Worker MovePtr<TestNode> createCase(const Context &ctx) const
5486*35238bceSAndroid Build Coastguard Worker {
5487*35238bceSAndroid Build Coastguard Worker TestCaseGroup *group = new TestCaseGroup(ctx.testContext, ctx.name.c_str(), ctx.name.c_str());
5488*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "scalar", instance<GenF<1>>()));
5489*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "vec2", instance<GenF<2>>()));
5490*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "vec3", instance<GenF<3>>()));
5491*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "vec4", instance<GenF<4>>()));
5492*35238bceSAndroid Build Coastguard Worker
5493*35238bceSAndroid Build Coastguard Worker return MovePtr<TestNode>(group);
5494*35238bceSAndroid Build Coastguard Worker }
5495*35238bceSAndroid Build Coastguard Worker
getFunc(void) const5496*35238bceSAndroid Build Coastguard Worker const FuncBase &getFunc(void) const
5497*35238bceSAndroid Build Coastguard Worker {
5498*35238bceSAndroid Build Coastguard Worker return instance<GenF<1>>();
5499*35238bceSAndroid Build Coastguard Worker }
5500*35238bceSAndroid Build Coastguard Worker };
5501*35238bceSAndroid Build Coastguard Worker
5502*35238bceSAndroid Build Coastguard Worker template <template <int> class GenF>
5503*35238bceSAndroid Build Coastguard Worker class SquareMatrixFuncCaseFactory : public FuncCaseFactory
5504*35238bceSAndroid Build Coastguard Worker {
5505*35238bceSAndroid Build Coastguard Worker public:
createCase(const Context & ctx) const5506*35238bceSAndroid Build Coastguard Worker MovePtr<TestNode> createCase(const Context &ctx) const
5507*35238bceSAndroid Build Coastguard Worker {
5508*35238bceSAndroid Build Coastguard Worker TestCaseGroup *group = new TestCaseGroup(ctx.testContext, ctx.name.c_str(), ctx.name.c_str());
5509*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "mat2", instance<GenF<2>>()));
5510*35238bceSAndroid Build Coastguard Worker #if 0
5511*35238bceSAndroid Build Coastguard Worker // disabled until we get reasonable results
5512*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "mat3", instance<GenF<3> >()));
5513*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, "mat4", instance<GenF<4> >()));
5514*35238bceSAndroid Build Coastguard Worker #endif
5515*35238bceSAndroid Build Coastguard Worker
5516*35238bceSAndroid Build Coastguard Worker return MovePtr<TestNode>(group);
5517*35238bceSAndroid Build Coastguard Worker }
5518*35238bceSAndroid Build Coastguard Worker
getFunc(void) const5519*35238bceSAndroid Build Coastguard Worker const FuncBase &getFunc(void) const
5520*35238bceSAndroid Build Coastguard Worker {
5521*35238bceSAndroid Build Coastguard Worker return instance<GenF<2>>();
5522*35238bceSAndroid Build Coastguard Worker }
5523*35238bceSAndroid Build Coastguard Worker };
5524*35238bceSAndroid Build Coastguard Worker
5525*35238bceSAndroid Build Coastguard Worker template <template <int, int> class GenF>
5526*35238bceSAndroid Build Coastguard Worker class MatrixFuncCaseFactory : public FuncCaseFactory
5527*35238bceSAndroid Build Coastguard Worker {
5528*35238bceSAndroid Build Coastguard Worker public:
createCase(const Context & ctx) const5529*35238bceSAndroid Build Coastguard Worker MovePtr<TestNode> createCase(const Context &ctx) const
5530*35238bceSAndroid Build Coastguard Worker {
5531*35238bceSAndroid Build Coastguard Worker TestCaseGroup *const group = new TestCaseGroup(ctx.testContext, ctx.name.c_str(), ctx.name.c_str());
5532*35238bceSAndroid Build Coastguard Worker
5533*35238bceSAndroid Build Coastguard Worker this->addCase<2, 2>(ctx, group);
5534*35238bceSAndroid Build Coastguard Worker this->addCase<3, 2>(ctx, group);
5535*35238bceSAndroid Build Coastguard Worker this->addCase<4, 2>(ctx, group);
5536*35238bceSAndroid Build Coastguard Worker this->addCase<2, 3>(ctx, group);
5537*35238bceSAndroid Build Coastguard Worker this->addCase<3, 3>(ctx, group);
5538*35238bceSAndroid Build Coastguard Worker this->addCase<4, 3>(ctx, group);
5539*35238bceSAndroid Build Coastguard Worker this->addCase<2, 4>(ctx, group);
5540*35238bceSAndroid Build Coastguard Worker this->addCase<3, 4>(ctx, group);
5541*35238bceSAndroid Build Coastguard Worker this->addCase<4, 4>(ctx, group);
5542*35238bceSAndroid Build Coastguard Worker
5543*35238bceSAndroid Build Coastguard Worker return MovePtr<TestNode>(group);
5544*35238bceSAndroid Build Coastguard Worker }
5545*35238bceSAndroid Build Coastguard Worker
getFunc(void) const5546*35238bceSAndroid Build Coastguard Worker const FuncBase &getFunc(void) const
5547*35238bceSAndroid Build Coastguard Worker {
5548*35238bceSAndroid Build Coastguard Worker return instance<GenF<2, 2>>();
5549*35238bceSAndroid Build Coastguard Worker }
5550*35238bceSAndroid Build Coastguard Worker
5551*35238bceSAndroid Build Coastguard Worker private:
5552*35238bceSAndroid Build Coastguard Worker template <int Rows, int Cols>
addCase(const Context & ctx,TestCaseGroup * group) const5553*35238bceSAndroid Build Coastguard Worker void addCase(const Context &ctx, TestCaseGroup *group) const
5554*35238bceSAndroid Build Coastguard Worker {
5555*35238bceSAndroid Build Coastguard Worker const char *const name = dataTypeNameOf<Matrix<float, Rows, Cols>>();
5556*35238bceSAndroid Build Coastguard Worker
5557*35238bceSAndroid Build Coastguard Worker group->addChild(createFuncCase(ctx, name, instance<GenF<Rows, Cols>>()));
5558*35238bceSAndroid Build Coastguard Worker }
5559*35238bceSAndroid Build Coastguard Worker };
5560*35238bceSAndroid Build Coastguard Worker
5561*35238bceSAndroid Build Coastguard Worker template <typename Sig>
5562*35238bceSAndroid Build Coastguard Worker class SimpleFuncCaseFactory : public CaseFactory
5563*35238bceSAndroid Build Coastguard Worker {
5564*35238bceSAndroid Build Coastguard Worker public:
SimpleFuncCaseFactory(const Func<Sig> & func)5565*35238bceSAndroid Build Coastguard Worker SimpleFuncCaseFactory(const Func<Sig> &func) : m_func(func)
5566*35238bceSAndroid Build Coastguard Worker {
5567*35238bceSAndroid Build Coastguard Worker }
5568*35238bceSAndroid Build Coastguard Worker
createCase(const Context & ctx) const5569*35238bceSAndroid Build Coastguard Worker MovePtr<TestNode> createCase(const Context &ctx) const
5570*35238bceSAndroid Build Coastguard Worker {
5571*35238bceSAndroid Build Coastguard Worker return MovePtr<TestNode>(createFuncCase(ctx, ctx.name.c_str(), m_func));
5572*35238bceSAndroid Build Coastguard Worker }
5573*35238bceSAndroid Build Coastguard Worker
getName(void) const5574*35238bceSAndroid Build Coastguard Worker string getName(void) const
5575*35238bceSAndroid Build Coastguard Worker {
5576*35238bceSAndroid Build Coastguard Worker return de::toLower(m_func.getName());
5577*35238bceSAndroid Build Coastguard Worker }
5578*35238bceSAndroid Build Coastguard Worker
getDesc(void) const5579*35238bceSAndroid Build Coastguard Worker string getDesc(void) const
5580*35238bceSAndroid Build Coastguard Worker {
5581*35238bceSAndroid Build Coastguard Worker return "Function '" + getName() + "'";
5582*35238bceSAndroid Build Coastguard Worker }
5583*35238bceSAndroid Build Coastguard Worker
5584*35238bceSAndroid Build Coastguard Worker private:
5585*35238bceSAndroid Build Coastguard Worker const Func<Sig> &m_func;
5586*35238bceSAndroid Build Coastguard Worker };
5587*35238bceSAndroid Build Coastguard Worker
5588*35238bceSAndroid Build Coastguard Worker template <typename F>
createSimpleFuncCaseFactory(void)5589*35238bceSAndroid Build Coastguard Worker SharedPtr<SimpleFuncCaseFactory<typename F::Sig>> createSimpleFuncCaseFactory(void)
5590*35238bceSAndroid Build Coastguard Worker {
5591*35238bceSAndroid Build Coastguard Worker return SharedPtr<SimpleFuncCaseFactory<typename F::Sig>>(new SimpleFuncCaseFactory<typename F::Sig>(instance<F>()));
5592*35238bceSAndroid Build Coastguard Worker }
5593*35238bceSAndroid Build Coastguard Worker
5594*35238bceSAndroid Build Coastguard Worker class BuiltinFuncs : public CaseFactories
5595*35238bceSAndroid Build Coastguard Worker {
5596*35238bceSAndroid Build Coastguard Worker public:
getFactories(void) const5597*35238bceSAndroid Build Coastguard Worker const vector<const CaseFactory *> getFactories(void) const
5598*35238bceSAndroid Build Coastguard Worker {
5599*35238bceSAndroid Build Coastguard Worker vector<const CaseFactory *> ret;
5600*35238bceSAndroid Build Coastguard Worker
5601*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < m_factories.size(); ++ndx)
5602*35238bceSAndroid Build Coastguard Worker ret.push_back(m_factories[ndx].get());
5603*35238bceSAndroid Build Coastguard Worker
5604*35238bceSAndroid Build Coastguard Worker return ret;
5605*35238bceSAndroid Build Coastguard Worker }
5606*35238bceSAndroid Build Coastguard Worker
addFactory(SharedPtr<const CaseFactory> fact)5607*35238bceSAndroid Build Coastguard Worker void addFactory(SharedPtr<const CaseFactory> fact)
5608*35238bceSAndroid Build Coastguard Worker {
5609*35238bceSAndroid Build Coastguard Worker m_factories.push_back(fact);
5610*35238bceSAndroid Build Coastguard Worker }
5611*35238bceSAndroid Build Coastguard Worker
5612*35238bceSAndroid Build Coastguard Worker private:
5613*35238bceSAndroid Build Coastguard Worker vector<SharedPtr<const CaseFactory>> m_factories;
5614*35238bceSAndroid Build Coastguard Worker };
5615*35238bceSAndroid Build Coastguard Worker
5616*35238bceSAndroid Build Coastguard Worker template <typename F>
addScalarFactory(BuiltinFuncs & funcs,string name="")5617*35238bceSAndroid Build Coastguard Worker void addScalarFactory(BuiltinFuncs &funcs, string name = "")
5618*35238bceSAndroid Build Coastguard Worker {
5619*35238bceSAndroid Build Coastguard Worker if (name.empty())
5620*35238bceSAndroid Build Coastguard Worker name = instance<F>().getName();
5621*35238bceSAndroid Build Coastguard Worker
5622*35238bceSAndroid Build Coastguard Worker funcs.addFactory(
5623*35238bceSAndroid Build Coastguard Worker SharedPtr<const CaseFactory>(new GenFuncCaseFactory<typename F::Sig>(makeVectorizedFuncs<F>(), name)));
5624*35238bceSAndroid Build Coastguard Worker }
5625*35238bceSAndroid Build Coastguard Worker
createES3BuiltinCases(void)5626*35238bceSAndroid Build Coastguard Worker MovePtr<const CaseFactories> createES3BuiltinCases(void)
5627*35238bceSAndroid Build Coastguard Worker {
5628*35238bceSAndroid Build Coastguard Worker MovePtr<BuiltinFuncs> funcs(new BuiltinFuncs());
5629*35238bceSAndroid Build Coastguard Worker
5630*35238bceSAndroid Build Coastguard Worker addScalarFactory<Add>(*funcs);
5631*35238bceSAndroid Build Coastguard Worker addScalarFactory<Sub>(*funcs);
5632*35238bceSAndroid Build Coastguard Worker addScalarFactory<Mul>(*funcs);
5633*35238bceSAndroid Build Coastguard Worker addScalarFactory<Div>(*funcs);
5634*35238bceSAndroid Build Coastguard Worker
5635*35238bceSAndroid Build Coastguard Worker addScalarFactory<Radians>(*funcs);
5636*35238bceSAndroid Build Coastguard Worker addScalarFactory<Degrees>(*funcs);
5637*35238bceSAndroid Build Coastguard Worker addScalarFactory<Sin>(*funcs);
5638*35238bceSAndroid Build Coastguard Worker addScalarFactory<Cos>(*funcs);
5639*35238bceSAndroid Build Coastguard Worker addScalarFactory<Tan>(*funcs);
5640*35238bceSAndroid Build Coastguard Worker addScalarFactory<ASin>(*funcs);
5641*35238bceSAndroid Build Coastguard Worker addScalarFactory<ACos>(*funcs);
5642*35238bceSAndroid Build Coastguard Worker addScalarFactory<ATan2>(*funcs, "atan2");
5643*35238bceSAndroid Build Coastguard Worker addScalarFactory<ATan>(*funcs);
5644*35238bceSAndroid Build Coastguard Worker addScalarFactory<Sinh>(*funcs);
5645*35238bceSAndroid Build Coastguard Worker addScalarFactory<Cosh>(*funcs);
5646*35238bceSAndroid Build Coastguard Worker addScalarFactory<Tanh>(*funcs);
5647*35238bceSAndroid Build Coastguard Worker addScalarFactory<ASinh>(*funcs);
5648*35238bceSAndroid Build Coastguard Worker addScalarFactory<ACosh>(*funcs);
5649*35238bceSAndroid Build Coastguard Worker addScalarFactory<ATanh>(*funcs);
5650*35238bceSAndroid Build Coastguard Worker
5651*35238bceSAndroid Build Coastguard Worker addScalarFactory<Pow>(*funcs);
5652*35238bceSAndroid Build Coastguard Worker addScalarFactory<Exp>(*funcs);
5653*35238bceSAndroid Build Coastguard Worker addScalarFactory<Log>(*funcs);
5654*35238bceSAndroid Build Coastguard Worker addScalarFactory<Exp2>(*funcs);
5655*35238bceSAndroid Build Coastguard Worker addScalarFactory<Log2>(*funcs);
5656*35238bceSAndroid Build Coastguard Worker addScalarFactory<Sqrt>(*funcs);
5657*35238bceSAndroid Build Coastguard Worker addScalarFactory<InverseSqrt>(*funcs);
5658*35238bceSAndroid Build Coastguard Worker
5659*35238bceSAndroid Build Coastguard Worker addScalarFactory<Abs>(*funcs);
5660*35238bceSAndroid Build Coastguard Worker addScalarFactory<Sign>(*funcs);
5661*35238bceSAndroid Build Coastguard Worker addScalarFactory<Floor>(*funcs);
5662*35238bceSAndroid Build Coastguard Worker addScalarFactory<Trunc>(*funcs);
5663*35238bceSAndroid Build Coastguard Worker addScalarFactory<Round>(*funcs);
5664*35238bceSAndroid Build Coastguard Worker addScalarFactory<RoundEven>(*funcs);
5665*35238bceSAndroid Build Coastguard Worker addScalarFactory<Ceil>(*funcs);
5666*35238bceSAndroid Build Coastguard Worker addScalarFactory<Fract>(*funcs);
5667*35238bceSAndroid Build Coastguard Worker addScalarFactory<Mod>(*funcs);
5668*35238bceSAndroid Build Coastguard Worker funcs->addFactory(createSimpleFuncCaseFactory<Modf>());
5669*35238bceSAndroid Build Coastguard Worker addScalarFactory<Min>(*funcs);
5670*35238bceSAndroid Build Coastguard Worker addScalarFactory<Max>(*funcs);
5671*35238bceSAndroid Build Coastguard Worker addScalarFactory<Clamp>(*funcs);
5672*35238bceSAndroid Build Coastguard Worker addScalarFactory<Mix>(*funcs);
5673*35238bceSAndroid Build Coastguard Worker addScalarFactory<Step>(*funcs);
5674*35238bceSAndroid Build Coastguard Worker addScalarFactory<SmoothStep>(*funcs);
5675*35238bceSAndroid Build Coastguard Worker
5676*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Length>()));
5677*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Distance>()));
5678*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Dot>()));
5679*35238bceSAndroid Build Coastguard Worker funcs->addFactory(createSimpleFuncCaseFactory<Cross>());
5680*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Normalize>()));
5681*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<FaceForward>()));
5682*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Reflect>()));
5683*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Refract>()));
5684*35238bceSAndroid Build Coastguard Worker
5685*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new MatrixFuncCaseFactory<MatrixCompMult>()));
5686*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new MatrixFuncCaseFactory<OuterProduct>()));
5687*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new MatrixFuncCaseFactory<Transpose>()));
5688*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new SquareMatrixFuncCaseFactory<Determinant>()));
5689*35238bceSAndroid Build Coastguard Worker funcs->addFactory(SharedPtr<const CaseFactory>(new SquareMatrixFuncCaseFactory<Inverse>()));
5690*35238bceSAndroid Build Coastguard Worker
5691*35238bceSAndroid Build Coastguard Worker return MovePtr<const CaseFactories>(funcs.release());
5692*35238bceSAndroid Build Coastguard Worker }
5693*35238bceSAndroid Build Coastguard Worker
createES31BuiltinCases(void)5694*35238bceSAndroid Build Coastguard Worker MovePtr<const CaseFactories> createES31BuiltinCases(void)
5695*35238bceSAndroid Build Coastguard Worker {
5696*35238bceSAndroid Build Coastguard Worker MovePtr<BuiltinFuncs> funcs(new BuiltinFuncs());
5697*35238bceSAndroid Build Coastguard Worker
5698*35238bceSAndroid Build Coastguard Worker addScalarFactory<FrExp>(*funcs);
5699*35238bceSAndroid Build Coastguard Worker addScalarFactory<LdExp>(*funcs);
5700*35238bceSAndroid Build Coastguard Worker addScalarFactory<Fma>(*funcs);
5701*35238bceSAndroid Build Coastguard Worker
5702*35238bceSAndroid Build Coastguard Worker return MovePtr<const CaseFactories>(funcs.release());
5703*35238bceSAndroid Build Coastguard Worker }
5704*35238bceSAndroid Build Coastguard Worker
5705*35238bceSAndroid Build Coastguard Worker struct PrecisionTestContext
5706*35238bceSAndroid Build Coastguard Worker {
PrecisionTestContextdeqp::gls::BuiltinPrecisionTests::PrecisionTestContext5707*35238bceSAndroid Build Coastguard Worker PrecisionTestContext(TestContext &testCtx_, RenderContext &renderCtx_, const FloatFormat &highp_,
5708*35238bceSAndroid Build Coastguard Worker const FloatFormat &mediump_, const FloatFormat &lowp_, const vector<ShaderType> &shaderTypes_,
5709*35238bceSAndroid Build Coastguard Worker int numRandoms_)
5710*35238bceSAndroid Build Coastguard Worker : testCtx(testCtx_)
5711*35238bceSAndroid Build Coastguard Worker , renderCtx(renderCtx_)
5712*35238bceSAndroid Build Coastguard Worker , shaderTypes(shaderTypes_)
5713*35238bceSAndroid Build Coastguard Worker , numRandoms(numRandoms_)
5714*35238bceSAndroid Build Coastguard Worker {
5715*35238bceSAndroid Build Coastguard Worker formats[glu::PRECISION_HIGHP] = &highp_;
5716*35238bceSAndroid Build Coastguard Worker formats[glu::PRECISION_MEDIUMP] = &mediump_;
5717*35238bceSAndroid Build Coastguard Worker formats[glu::PRECISION_LOWP] = &lowp_;
5718*35238bceSAndroid Build Coastguard Worker }
5719*35238bceSAndroid Build Coastguard Worker
5720*35238bceSAndroid Build Coastguard Worker TestContext &testCtx;
5721*35238bceSAndroid Build Coastguard Worker RenderContext &renderCtx;
5722*35238bceSAndroid Build Coastguard Worker const FloatFormat *formats[glu::PRECISION_LAST];
5723*35238bceSAndroid Build Coastguard Worker vector<ShaderType> shaderTypes;
5724*35238bceSAndroid Build Coastguard Worker int numRandoms;
5725*35238bceSAndroid Build Coastguard Worker };
5726*35238bceSAndroid Build Coastguard Worker
createFuncGroup(const PrecisionTestContext & ctx,const CaseFactory & factory)5727*35238bceSAndroid Build Coastguard Worker TestCaseGroup *createFuncGroup(const PrecisionTestContext &ctx, const CaseFactory &factory)
5728*35238bceSAndroid Build Coastguard Worker {
5729*35238bceSAndroid Build Coastguard Worker TestCaseGroup *const group = new TestCaseGroup(ctx.testCtx, factory.getName().c_str(), factory.getDesc().c_str());
5730*35238bceSAndroid Build Coastguard Worker
5731*35238bceSAndroid Build Coastguard Worker for (int precNdx = 0; precNdx < glu::PRECISION_LAST; ++precNdx)
5732*35238bceSAndroid Build Coastguard Worker {
5733*35238bceSAndroid Build Coastguard Worker const Precision precision = Precision(precNdx);
5734*35238bceSAndroid Build Coastguard Worker const string precName(glu::getPrecisionName(precision));
5735*35238bceSAndroid Build Coastguard Worker const FloatFormat &fmt = *de::getSizedArrayElement<glu::PRECISION_LAST>(ctx.formats, precNdx);
5736*35238bceSAndroid Build Coastguard Worker const FloatFormat &highpFmt = *de::getSizedArrayElement<glu::PRECISION_LAST>(ctx.formats, glu::PRECISION_HIGHP);
5737*35238bceSAndroid Build Coastguard Worker
5738*35238bceSAndroid Build Coastguard Worker for (size_t shaderNdx = 0; shaderNdx < ctx.shaderTypes.size(); ++shaderNdx)
5739*35238bceSAndroid Build Coastguard Worker {
5740*35238bceSAndroid Build Coastguard Worker const ShaderType shaderType = ctx.shaderTypes[shaderNdx];
5741*35238bceSAndroid Build Coastguard Worker const string shaderName(glu::getShaderTypeName(shaderType));
5742*35238bceSAndroid Build Coastguard Worker const string name = precName + "_" + shaderName;
5743*35238bceSAndroid Build Coastguard Worker const Context caseCtx(name, ctx.testCtx, ctx.renderCtx, fmt, highpFmt, precision, shaderType,
5744*35238bceSAndroid Build Coastguard Worker ctx.numRandoms);
5745*35238bceSAndroid Build Coastguard Worker
5746*35238bceSAndroid Build Coastguard Worker group->addChild(factory.createCase(caseCtx).release());
5747*35238bceSAndroid Build Coastguard Worker }
5748*35238bceSAndroid Build Coastguard Worker }
5749*35238bceSAndroid Build Coastguard Worker
5750*35238bceSAndroid Build Coastguard Worker return group;
5751*35238bceSAndroid Build Coastguard Worker }
5752*35238bceSAndroid Build Coastguard Worker
addBuiltinPrecisionTests(TestContext & testCtx,RenderContext & renderCtx,const CaseFactories & cases,const vector<ShaderType> & shaderTypes,TestCaseGroup & dstGroup)5753*35238bceSAndroid Build Coastguard Worker void addBuiltinPrecisionTests(TestContext &testCtx, RenderContext &renderCtx, const CaseFactories &cases,
5754*35238bceSAndroid Build Coastguard Worker const vector<ShaderType> &shaderTypes, TestCaseGroup &dstGroup)
5755*35238bceSAndroid Build Coastguard Worker {
5756*35238bceSAndroid Build Coastguard Worker const int userRandoms = testCtx.getCommandLine().getTestIterationCount();
5757*35238bceSAndroid Build Coastguard Worker const int defRandoms = 16384;
5758*35238bceSAndroid Build Coastguard Worker const int numRandoms = userRandoms > 0 ? userRandoms : defRandoms;
5759*35238bceSAndroid Build Coastguard Worker const FloatFormat highp(-126, 127, 23, true,
5760*35238bceSAndroid Build Coastguard Worker tcu::MAYBE, // subnormals
5761*35238bceSAndroid Build Coastguard Worker tcu::YES, // infinities
5762*35238bceSAndroid Build Coastguard Worker tcu::MAYBE); // NaN
5763*35238bceSAndroid Build Coastguard Worker // \todo [2014-04-01 lauri] Check these once Khronos bug 11840 is resolved.
5764*35238bceSAndroid Build Coastguard Worker const FloatFormat mediump(-13, 13, 9, false);
5765*35238bceSAndroid Build Coastguard Worker // A fixed-point format is just a floating point format with a fixed
5766*35238bceSAndroid Build Coastguard Worker // exponent and support for subnormals.
5767*35238bceSAndroid Build Coastguard Worker const FloatFormat lowp(0, 0, 7, false, tcu::YES);
5768*35238bceSAndroid Build Coastguard Worker const PrecisionTestContext ctx(testCtx, renderCtx, highp, mediump, lowp, shaderTypes, numRandoms);
5769*35238bceSAndroid Build Coastguard Worker
5770*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < cases.getFactories().size(); ++ndx)
5771*35238bceSAndroid Build Coastguard Worker dstGroup.addChild(createFuncGroup(ctx, *cases.getFactories()[ndx]));
5772*35238bceSAndroid Build Coastguard Worker }
5773*35238bceSAndroid Build Coastguard Worker
5774*35238bceSAndroid Build Coastguard Worker } // namespace BuiltinPrecisionTests
5775*35238bceSAndroid Build Coastguard Worker } // namespace gls
5776*35238bceSAndroid Build Coastguard Worker } // namespace deqp
5777