13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL (ES) Module 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Precision and range tests for GLSL builtins and types. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsBuiltinPrecisionTests.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deDefs.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSTLUtil.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp" 35d6148171f88da1301f053e2e0236afc69416137cJarkko Pöyry#include "deArrayUtil.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloatFormat.hpp" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuInterval.hpp" 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestCase.hpp" 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp" 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrix.hpp" 44ab44fc6da25bb126919615ad2ded101695251161Jarkko Pöyry#include "tcuResultCollector.hpp" 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp" 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarType.hpp" 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwDefs.hpp" 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderExecUtil.hpp" 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cmath> 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string> 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream> 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iostream> 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map> 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <utility> 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Uncomment this to get evaluation trace dumps to std::cerr 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// #define GLS_ENABLE_TRACE 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// set this to true to dump even passing results 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define GLS_LOG_ALL_RESULTS false 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 669274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulosenum 679274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos{ 689274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos // Computing reference intervals can take a non-trivial amount of time, especially on 699274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos // platforms where toggling floating-point rounding mode is slow (emulated arm on x86). 709274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos // As a workaround watchdog is kept happy by touching it periodically during reference 719274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos // interval computation. 729274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos TOUCH_WATCHDOG_VALUE_FREQUENCY = 4096 739274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos}; 749274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gls 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace BuiltinPrecisionTests 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map; 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ostream; 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ostringstream; 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::pair; 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set; 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::MovePtr; 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random; 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::SharedPtr; 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::UniquePtr; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Interval; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::FloatFormat; 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::MessageBuilder; 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestCase; 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog; 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vector; 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Matrix; 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace matrix = tcu::matrix; 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::Precision; 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::RenderContext; 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::VarType; 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::DataType; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ShaderType; 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ContextInfo; 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::ShaderExecUtil::Symbol; 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef TestCase::IterateResult IterateResult; 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw; 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace tcu; 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Generic singleton creator. 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * instance<T>() returns a reference to a unique default-constructed instance 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * of T. This is mainly used for our GLSL function implementations: each 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * function is implemented by an object, and each of the objects has a 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distinct class. It would be extremely toilsome to maintain a separate 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * context object that contained individual instances of the function classes, 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * so we have to resort to global singleton instances. 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst T& instance (void) 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const T s_instance = T(); 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return s_instance; 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Dummy placeholder type for unused template parameters. 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * In the precision tests we are dealing with functions of different arities. 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * To minimize code duplication, we only define templates with the maximum 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * number of arguments, currently four. If a function's arity is less than the 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * maximum, Void us used as the type for unused arguments. 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Although Voids are not used at run-time, they still must be compilable, so 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * they must support all operations that other types do. 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Void 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Void Element; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SIZE = 0, 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template <typename T> 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit Void (const T&) {} 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Void (void) {} 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry operator double (void) const { return TCU_NAN; } 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // These are used to make Voids usable as containers in container-generic code. 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Void& operator[] (int) { return *this; } 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Void& operator[] (int) const { return *this; } 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryostream& operator<< (ostream& os, Void) { return os << "()"; } 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Returns true for all other types except Void 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> bool isTypeValid (void) { return true; } 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> bool isTypeValid<Void> (void) { return false; } 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Utility function for getting the name of a data type. 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! This is used in vector and matrix constructors. 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* dataTypeNameOf (void) 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::getDataTypeName(glu::dataTypeOf<T>()); 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* dataTypeNameOf<Void> (void) 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1801cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry DE_FATAL("Impossible"); 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! A hack to get Void support for VarType. 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 1863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVarType getVarTypeOf (Precision prec = glu::PRECISION_LAST) 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::varTypeOf<T>(prec); 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 1923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVarType getVarTypeOf<Void> (Precision) 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1941cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry DE_FATAL("Impossible"); 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return VarType(); 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Type traits for generalized interval types. 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * We are trying to compute sets of acceptable values not only for 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * float-valued expressions but also for compound values: vectors and 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * matrices. We approximate a set of vectors as a vector of intervals and 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * likewise for matrices. 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * We now need generalized operations for each type and its interval 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * approximation. These are given in the type Traits<T>. 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The type Traits<T>::IVal is the approximation of T: it is `Interval` for 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * scalar types, and a vector or matrix of intervals for container types. 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * To allow template inference to take place, there are function wrappers for 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the actual operations in Traits<T>. Hence we can just use: 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * makeIVal(someFloat) 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * instead of: 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Traits<float>::doMakeIVal(value) 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> struct Traits; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Create container from elementwise singleton values. 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename Traits<T>::IVal makeIVal (const T& value) 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Traits<T>::doMakeIVal(value); 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Elementwise union of intervals. 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename Traits<T>::IVal unionIVal (const typename Traits<T>::IVal& a, 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<T>::IVal& b) 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Traits<T>::doUnion(a, b); 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Returns true iff every element of `ival` contains the corresponding element of `value`. 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool contains (const typename Traits<T>::IVal& ival, const T& value) 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Traits<T>::doContains(ival, value); 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Print out an interval with the precision of `fmt`. 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid printIVal (const FloatFormat& fmt, const typename Traits<T>::IVal& ival, ostream& os) 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Traits<T>::doPrintIVal(fmt, ival, os); 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring intervalToString (const FloatFormat& fmt, const typename Traits<T>::IVal& ival) 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream oss; 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printIVal<T>(fmt, ival, oss); 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return oss.str(); 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Print out a value with the precision of `fmt`. 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid printValue (const FloatFormat& fmt, const T& value, ostream& os) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Traits<T>::doPrintValue(fmt, value, os); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring valueToString (const FloatFormat& fmt, const T& val) 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream oss; 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printValue(fmt, val, oss); 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return oss.str(); 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Approximate `value` elementwise to the float precision defined in `fmt`. 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! The resulting interval might not be a singleton if rounding in both 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! directions is allowed. 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename Traits<T>::IVal round (const FloatFormat& fmt, const T& value) 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Traits<T>::doRound(fmt, value); 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename Traits<T>::IVal convert (const FloatFormat& fmt, 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<T>::IVal& value) 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Traits<T>::doConvert(fmt, value); 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Common traits for scalar types. 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ScalarTraits 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 297653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef Interval IVal; 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static Interval doMakeIVal (const T& value) 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Thankfully all scalar types have a well-defined conversion to `double`, 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // hence Interval can represent their ranges without problems. 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(double(value)); 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static Interval doUnion (const Interval& a, const Interval& b) 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a | b; 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static bool doContains (const Interval& a, T value) 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a.contains(double(value)); 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static Interval doConvert (const FloatFormat& fmt, const IVal& ival) 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return fmt.convert(ival); 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static Interval doRound (const FloatFormat& fmt, T value) 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3232e751e3e77060f699c560104e82379d3ce54f67aPyry Haulos return fmt.roundOut(double(value), false); 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Traits<float> : ScalarTraits<float> 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintIVal (const FloatFormat& fmt, 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& ival, 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostream& os) 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << fmt.intervalToHex(ival); 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintValue (const FloatFormat& fmt, 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float& value, 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostream& os) 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << fmt.floatToHex(value); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Traits<bool> : ScalarTraits<bool> 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintValue (const FloatFormat&, 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float& value, 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostream& os) 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35224ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry os << (value != 0.0f ? "true" : "false"); 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintIVal (const FloatFormat&, 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& ival, 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostream& os) 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "{"; 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ival.contains(false)) 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "false"; 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ival.contains(false) && ival.contains(true)) 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", "; 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ival.contains(true)) 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "true"; 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "}"; 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Traits<int> : ScalarTraits<int> 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 373653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos static void doPrintValue (const FloatFormat&, 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int& value, 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostream& os) 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << value; 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintIVal (const FloatFormat&, 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& ival, 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostream& os) 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "[" << int(ival.lo()) << ", " << int(ival.hi()) << "]"; 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Common traits for containers, i.e. vectors and matrices. 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! T is the container type itself, I is the same type with interval elements. 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename I> 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ContainerTraits 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename T::Element Element; 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef I IVal; 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static IVal doMakeIVal (const T& value) 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal ret; 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < T::SIZE; ++ndx) 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[ndx] = makeIVal(value[ndx]); 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static IVal doUnion (const IVal& a, const IVal& b) 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal ret; 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < T::SIZE; ++ndx) 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[ndx] = unionIVal<Element>(a[ndx], b[ndx]); 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static bool doContains (const IVal& ival, const T& value) 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < T::SIZE; ++ndx) 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!contains(ival[ndx], value[ndx])) 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintIVal (const FloatFormat& fmt, const IVal ival, ostream& os) 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "("; 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < T::SIZE; ++ndx) 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ndx > 0) 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", "; 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printIVal<Element>(fmt, ival[ndx], os); 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ")"; 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintValue (const FloatFormat& fmt, const T& value, ostream& os) 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << dataTypeNameOf<T>() << "("; 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < T::SIZE; ++ndx) 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ndx > 0) 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", "; 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printValue<Element>(fmt, value[ndx], os); 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ")"; 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static IVal doConvert (const FloatFormat& fmt, const IVal& value) 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal ret; 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < T::SIZE; ++ndx) 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[ndx] = convert<Element>(fmt, value[ndx]); 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static IVal doRound (const FloatFormat& fmt, T value) 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal ret; 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < T::SIZE; ++ndx) 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[ndx] = round(fmt, value[ndx]); 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Traits<Vector<T, Size> > : 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ContainerTraits<Vector<T, Size>, Vector<typename Traits<T>::IVal, Size> > 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols> 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Traits<Matrix<T, Rows, Cols> > : 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ContainerTraits<Matrix<T, Rows, Cols>, Matrix<typename Traits<T>::IVal, Rows, Cols> > 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Void traits. These are just dummies, but technically valid: a Void is a 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! unit type with a single possible value. 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Traits<Void> 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Void IVal; 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 495653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos static Void doMakeIVal (const Void& value) { return value; } 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static Void doUnion (const Void&, const Void&) { return Void(); } 497653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos static bool doContains (const Void&, Void) { return true; } 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static Void doRound (const FloatFormat&, const Void& value) { return value; } 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static Void doConvert (const FloatFormat&, const Void& value) { return value; } 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 501653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos static void doPrintValue (const FloatFormat&, const Void&, ostream& os) 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "()"; 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static void doPrintIVal (const FloatFormat&, const Void&, ostream& os) 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "()"; 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! This is needed for container-generic operations. 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! We want a scalar type T to be its own "one-element vector". 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> struct ContainerOf { typedef Vector<T, Size> Container; }; 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> struct ContainerOf<T, 1> { typedef T Container; }; 517653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulostemplate <int Size> struct ContainerOf<Void, Size> { typedef Void Container; }; 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// This is a kludge that is only needed to get the ExprP::operator[] syntactic sugar to work. 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> struct ElementOf { typedef typename T::Element Element; }; 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct ElementOf<float> { typedef void Element; }; 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct ElementOf<bool> { typedef void Element; }; 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct ElementOf<int> { typedef void Element; }; 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \name Abstract syntax for expressions and statements. 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * We represent GLSL programs as syntax objects: an Expr<T> represents an 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * expression whose GLSL type corresponds to the C++ type T, and a Statement 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * represents a statement. 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * To ease memory management, we use shared pointers to refer to expressions 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and statements. ExprP<T> is a shared pointer to an Expr<T>, and StatementP 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is a shared pointer to a Statement. 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \{ 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExprBase; 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExpandContext; 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Statement; 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass StatementP; 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FuncBase; 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> class ExprP; 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> class Variable; 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> class VariableP; 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> class DefaultSampling; 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef set<const FuncBase*> FuncSet; 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 5543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableP<T> variable (const string& name); 5553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatementP compoundStatement (const vector<StatementP>& statements); 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief A variable environment. 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * An Environment object maintains the mapping between variables of the 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * abstract syntax tree and their values. 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2014-03-28 lauri] At least run-time type safety. 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Environment 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename T> 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void bind (const Variable<T>& variable, 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<T>::IVal& value) 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const data = new deUint8[sizeof(value)]; 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(data, &value, sizeof(value)); 5766801c0680107ff001b065db07b125d622926f311Mika Isojärvi de::insert(m_map, variable.getName(), SharedPtr<deUint8>(data, de::ArrayDeleter<deUint8>())); 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename T> 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename Traits<T>::IVal& lookup (const Variable<T>& variable) const 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const data = de::lookup(m_map, variable.getName()).get(); 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *reinterpret_cast<typename Traits<T>::IVal*>(data); 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 5886801c0680107ff001b065db07b125d622926f311Mika Isojärvi map<string, SharedPtr<deUint8> > m_map; 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Evaluation context. 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The evaluation context contains everything that separates one execution of 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * an expression from the next. Currently this means the desired floating 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * point precision and the current variable environment. 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct EvalContext 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry EvalContext (const FloatFormat& format_, 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Precision floatPrecision_, 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Environment& env_, 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int callDepth_ = 0) 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : format (format_) 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , floatPrecision (floatPrecision_) 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , env (env_) 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , callDepth (callDepth_) {} 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FloatFormat format; 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Precision floatPrecision; 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Environment& env; 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int callDepth; 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Simple incremental counter. 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is used to make sure that different ExpandContexts will not produce 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * overlapping temporary names. 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Counter 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Counter (int count = 0) : m_count(count) {} 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int operator() (void) { return m_count++; } 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_count; 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExpandContext 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExpandContext (Counter& symCounter) : m_symCounter(symCounter) {} 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExpandContext (const ExpandContext& parent) 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_symCounter(parent.m_symCounter) {} 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename T> 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<T> genSym (const string& baseName) 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return variable<T>(baseName + de::toString(m_symCounter())); 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void addStatement (const StatementP& stmt) 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_statements.push_back(stmt); 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<StatementP> getStatements (void) const 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_statements; 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Counter& m_symCounter; 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<StatementP> m_statements; 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief A statement or declaration. 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Statements have no values. Instead, they are executed for their side 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * effects only: the execute() method should modify at least one variable in 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the environment. 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * As a bit of a kludge, a Statement object can also represent a declaration: 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * when it is evaluated, it can add a variable binding to the environment 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * instead of modifying a current one. 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Statement 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 675653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos virtual ~Statement (void) { } 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry //! Execute the statement, modifying the environment of `ctx` 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void execute (EvalContext& ctx) const { this->doExecute(ctx); } 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void print (ostream& os) const { this->doPrint(os); } 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry //! Add the functions used in this statement to `dst`. 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getUsedFuncs (FuncSet& dst) const { this->doGetUsedFuncs(dst); } 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doPrint (ostream& os) const = 0; 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doExecute (EvalContext& ctx) const = 0; 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doGetUsedFuncs (FuncSet& dst) const = 0; 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryostream& operator<<(ostream& os, const Statement& stmt) 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stmt.print(os); 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return os; 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Smart pointer for statements (and declarations) 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass StatementP : public SharedPtr<const Statement> 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef SharedPtr<const Statement> Super; 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StatementP (void) {} 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit StatementP (const Statement* ptr) : Super(ptr) {} 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StatementP (const Super& ptr) : Super(ptr) {} 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A statement that modifies a variable or a declaration that binds a variable. 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VariableStatement : public Statement 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableStatement (const VariableP<T>& variable, const ExprP<T>& value, 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isDeclaration) 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_variable (variable) 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_value (value) 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isDeclaration (isDeclaration) {} 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os) const 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isDeclaration) 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << glu::declare(getVarTypeOf<T>(), m_variable->getName()); 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << m_variable->getName(); 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << " = " << *m_value << ";\n"; 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doExecute (EvalContext& ctx) const 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_isDeclaration) 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.env.bind(*m_variable, m_value->evaluate(ctx)); 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.env.lookup(*m_variable) = m_value->evaluate(ctx); 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doGetUsedFuncs (FuncSet& dst) const 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_value->getUsedFuncs(dst); 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<T> m_variable; 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<T> m_value; 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool m_isDeclaration; 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 7543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatementP variableStatement (const VariableP<T>& variable, 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<T>& value, 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isDeclaration) 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return StatementP(new VariableStatement<T>(variable, value, isDeclaration)); 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 7623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatementP variableDeclaration (const VariableP<T>& variable, const ExprP<T>& definiens) 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return variableStatement(variable, definiens, true); 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 7683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatementP variableAssignment (const VariableP<T>& variable, const ExprP<T>& value) 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return variableStatement(variable, value, false); 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief A compound statement, i.e. a block. 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A compound statement is executed by executing its constituent statements in 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * sequence. 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CompoundStatement : public Statement 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CompoundStatement (const vector<StatementP>& statements) 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_statements (statements) {} 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os) const 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "{\n"; 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_statements.size(); ++ndx) 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << *m_statements[ndx]; 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "}\n"; 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doExecute (EvalContext& ctx) const 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_statements.size(); ++ndx) 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_statements[ndx]->execute(ctx); 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doGetUsedFuncs (FuncSet& dst) const 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_statements.size(); ++ndx) 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_statements[ndx]->getUsedFuncs(dst); 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<StatementP> m_statements; 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStatementP compoundStatement(const vector<StatementP>& statements) 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return StatementP(new CompoundStatement(statements)); 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Common base class for all expressions regardless of their type. 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExprBase 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual ~ExprBase (void) {} 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void printExpr (ostream& os) const { this->doPrintExpr(os); } 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry //! Output the functions that this expression refers to 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getUsedFuncs (FuncSet& dst) const 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->doGetUsedFuncs(dst); 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doPrintExpr (ostream&) const {} 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doGetUsedFuncs (FuncSet&) const {} 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Type-specific operations for an expression representing type T. 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Expr : public ExprBase 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 840653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef T Val; 841653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef typename Traits<T>::IVal IVal; 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal evaluate (const EvalContext& ctx) const; 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual IVal doEvaluate (const EvalContext& ctx) const = 0; 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Evaluate an expression with the given context, optionally tracing the calls to stderr. 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename Traits<T>::IVal Expr<T>::evaluate (const EvalContext& ctx) const 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef GLS_ENABLE_TRACE 8548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry static const FloatFormat highpFmt (-126, 127, 23, true, 8558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry tcu::MAYBE, 8568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry tcu::YES, 8578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry tcu::MAYBE); 8588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry EvalContext newCtx (ctx.format, ctx.floatPrecision, 8598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ctx.env, ctx.callDepth + 1); 8608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const IVal ret = this->doEvaluate(newCtx); 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<T>()) 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::cerr << string(ctx.callDepth, ' '); 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->printExpr(std::cerr); 8668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::cerr << " -> " << intervalToString<T>(highpFmt, ret) << std::endl; 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#else 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->doEvaluate(ctx); 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExprPBase : public SharedPtr<const Expr<T> > 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryostream& operator<< (ostream& os, const ExprBase& expr) 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expr.printExpr(os); 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return os; 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shared pointer to an expression of a container type. 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Container types (i.e. vectors and matrices) support the subscription 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * operator. This class provides a bit of syntactic sugar to allow us to use 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the C++ subscription operator to create a subscription expression. 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ContainerExprPBase : public ExprPBase<T> 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<typename T::Element> operator[] (int i) const; 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExprP : public ExprPBase<T> {}; 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// We treat Voids as containers since the dummy parameters in generalized 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// vector functions are represented as Voids. 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExprP<Void> : public ContainerExprPBase<Void> {}; 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExprP<Vector<T, Size> > : public ContainerExprPBase<Vector<T, Size> > {}; 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols> 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExprP<Matrix<T, Rows, Cols> > : public ContainerExprPBase<Matrix<T, Rows, Cols> > {}; 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> ExprP<T> exprP (void) 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ExprP<T>(); 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 9203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<T> exprP (const SharedPtr<const Expr<T> >& ptr) 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<T> ret; 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static_cast<SharedPtr<const Expr<T> >&>(ret) = ptr; 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 9283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<T> exprP (const Expr<T>* ptr) 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exprP(SharedPtr<const Expr<T> >(ptr)); 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief A shared pointer to a variable expression. 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is just a narrowing of ExprP for the operations that require a variable 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * instead of an arbitrary expression. 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VariableP : public SharedPtr<const Variable<T> > 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef SharedPtr<const Variable<T> > Super; 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit VariableP (const Variable<T>* ptr) : Super(ptr) {} 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP (void) {} 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP (const Super& ptr) : Super(ptr) {} 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry operator ExprP<T> (void) const { return exprP(SharedPtr<const Expr<T> >(*this)); } 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \name Syntactic sugar operators for expressions. 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * @{ 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * These operators allow the use of C++ syntax to construct GLSL expressions 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * containing operators: e.g. "a+b" creates an addition expression with 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * operands a and b, and so on. 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 9623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator-(const ExprP<float>& arg0); 9633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator+(const ExprP<float>& arg0, 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& arg1); 9653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator-(const ExprP<float>& arg0, 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& arg1); 967653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry HaulosExprP<float> operator*(const ExprP<float>& arg0, 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& arg1); 969653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry HaulosExprP<float> operator/(const ExprP<float>& arg0, 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& arg1); 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 9723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator-(const ExprP<Vector<float, Size> >& arg0); 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 9743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator*(const ExprP<Vector<float, Size> >& arg0, 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& arg1); 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 9773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator*(const ExprP<Vector<float, Size> >& arg0, 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<float, Size> >& arg1); 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 9803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator-(const ExprP<Vector<float, Size> >& arg0, 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<float, Size> >& arg1); 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Left, int Mid, int Right> 9833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, Left, Right> > operator* (const ExprP<Matrix<float, Left, Mid> >& left, 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Matrix<float, Mid, Right> >& right); 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 9863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Rows> > operator* (const ExprP<Vector<float, Cols> >& left, 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Matrix<float, Rows, Cols> >& right); 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 9893c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Cols> > operator* (const ExprP<Matrix<float, Rows, Cols> >& left, 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<float, Rows> >& right); 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 9923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, Rows, Cols> > operator* (const ExprP<Matrix<float, Rows, Cols> >& left, 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& right); 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 995653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry HaulosExprP<Matrix<float, Rows, Cols> > operator+ (const ExprP<Matrix<float, Rows, Cols> >& left, 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Matrix<float, Rows, Cols> >& right); 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 998653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry HaulosExprP<Matrix<float, Rows, Cols> > operator- (const ExprP<Matrix<float, Rows, Cols> >& mat); 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! @} 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Variable expression. 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A variable is evaluated by looking up its range of possible values from an 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * environment. 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Variable : public Expr<T> 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Expr<T>::IVal IVal; 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Variable (const string& name) : m_name (name) {} 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return m_name; } 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrintExpr (ostream& os) const { os << m_name; } 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal doEvaluate (const EvalContext& ctx) const 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.env.lookup<T>(*this); 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string m_name; 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 10293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableP<T> variable (const string& name) 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return VariableP<T>(new Variable<T>(name)); 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 10353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableP<T> bindExpression (const string& name, ExpandContext& ctx, const ExprP<T>& expr) 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<T> var = ctx.genSym<T>(name); 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.addStatement(variableDeclaration(var, expr)); 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return var; 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Constant expression. 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A constant is evaluated by rounding it to a set of possible values allowed 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * by the current floating point precision. 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Constant : public Expr<T> 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Expr<T>::IVal IVal; 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Constant (const T& value) : m_value(value) {} 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 1057653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos void doPrintExpr (ostream& os) const { os << m_value; } 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal doEvaluate (const EvalContext&) const { return makeIVal(m_value); } 10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T m_value; 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 10653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<T> constant (const T& value) 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exprP(new Constant<T>(value)); 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Return a reference to a singleton void constant. 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst ExprP<Void>& voidP (void) 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const ExprP<Void> singleton = constant(Void()); 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return singleton; 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Four-element tuple. 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is used for various things where we need one thing for each possible 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * function parameter. Currently the maximum supported number of parameters is 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * four. 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T0 = Void, typename T1 = Void, typename T2 = Void, typename T3 = Void> 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Tuple4 10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1088dac35f616a6949e44c7b24b43287d397bee609cdPyry Haulos explicit Tuple4 (const T0 e0 = T0(), 1089dac35f616a6949e44c7b24b43287d397bee609cdPyry Haulos const T1 e1 = T1(), 1090dac35f616a6949e44c7b24b43287d397bee609cdPyry Haulos const T2 e2 = T2(), 1091dac35f616a6949e44c7b24b43287d397bee609cdPyry Haulos const T3 e3 = T3()) 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : a (e0) 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , b (e1) 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , c (e2) 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , d (e3) 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T0 a; 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T1 b; 11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T2 c; 11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T3 d; 11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Function signature. 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is a purely compile-time structure used to bundle all types in a 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * function signature together. This makes passing the signature around in 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * templates easier, since we only need to take and pass a single Sig instead 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * of a bunch of parameter types and a return type. 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename R, 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename P0 = Void, typename P1 = Void, 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename P2 = Void, typename P3 = Void> 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Signature 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef R Ret; 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef P0 Arg0; 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef P1 Arg1; 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef P2 Arg2; 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef P3 Arg3; 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Traits<Ret>::IVal IRet; 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Traits<Arg0>::IVal IArg0; 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Traits<Arg1>::IVal IArg1; 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Traits<Arg2>::IVal IArg2; 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Traits<Arg3>::IVal IArg3; 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Tuple4< const Arg0&, const Arg1&, const Arg2&, const Arg3&> Args; 1131653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef Tuple4< const IArg0&, const IArg1&, const IArg2&, const IArg3&> IArgs; 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Tuple4< ExprP<Arg0>, ExprP<Arg1>, ExprP<Arg2>, ExprP<Arg3> > ArgExprs; 11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef vector<const ExprBase*> BaseArgExprs; 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Type-independent operations for function objects. 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FuncBase 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual ~FuncBase (void) {} 1145653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos virtual string getName (void) const = 0; 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry //! Name of extension that this function requires, or empty. 1147653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos virtual string getRequiredExtension (void) const { return ""; } 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void print (ostream&, 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BaseArgExprs&) const = 0; 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry //! Index of output parameter, or -1 if none of the parameters is output. 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual int getOutParamIndex (void) const { return -1; } 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void printDefinition (ostream& os) const 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry doPrintDefinition(os); 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getUsedFuncs (FuncSet& dst) const 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->doGetUsedFuncs(dst); 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doPrintDefinition (ostream& os) const = 0; 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doGetUsedFuncs (FuncSet& dst) const = 0; 11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Tuple4<string, string, string, string> ParamNames; 11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Function objects. 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Each Func object represents a GLSL function. It can be applied to interval 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * arguments, and it returns the an interval that is a conservative 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * approximation of the image of the GLSL function over the argument 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * intervals. That is, it is given a set of possible arguments and it returns 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the set of possible values. 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig_> 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Func : public FuncBase 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Sig_ Sig; 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Ret Ret; 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg0 Arg0; 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg1 Arg1; 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg2 Arg2; 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg3 Arg3; 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::IRet IRet; 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::IArg0 IArg0; 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::IArg1 IArg1; 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::IArg2 IArg2; 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::IArg3 IArg3; 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Args Args; 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::IArgs IArgs; 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::ArgExprs ArgExprs; 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void print (ostream& os, 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BaseArgExprs& args) const 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->doPrint(os, args); 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet apply (const EvalContext& ctx, 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg0& arg0 = IArg0(), 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg1& arg1 = IArg1(), 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg2& arg2 = IArg2(), 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg3& arg3 = IArg3()) const 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->applyArgs(ctx, IArgs(arg0, arg1, arg2, arg3)); 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet applyArgs (const EvalContext& ctx, 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArgs& args) const 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->doApply(ctx, args); 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> operator() (const ExprP<Arg0>& arg0 = voidP(), 12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg1>& arg1 = voidP(), 12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg2>& arg2 = voidP(), 12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg3>& arg3 = voidP()) const; 12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ParamNames& getParamNames (void) const 12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->doGetParamNames(); 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual IRet doApply (const EvalContext&, 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArgs&) const = 0; 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void doPrint (ostream& os, const BaseArgExprs& args) const 12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << getName() << "("; 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg0>()) 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << *args[0]; 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg1>()) 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", " << *args[1]; 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg2>()) 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", " << *args[2]; 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg3>()) 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", " << *args[3]; 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ")"; 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual const ParamNames& doGetParamNames (void) const 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ParamNames names ("a", "b", "c", "d"); 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return names; 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Apply : public Expr<typename Sig::Ret> 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Ret Ret; 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg0 Arg0; 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg1 Arg1; 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg2 Arg2; 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg3 Arg3; 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Expr<Ret>::Val Val; 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Expr<Ret>::IVal IVal; 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Func<Sig> ApplyFunc; 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename ApplyFunc::ArgExprs ArgExprs; 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Apply (const ApplyFunc& func, 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg0>& arg0 = voidP(), 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg1>& arg1 = voidP(), 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg2>& arg2 = voidP(), 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg3>& arg3 = voidP()) 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_func (func), 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args (arg0, arg1, arg2, arg3) {} 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Apply (const ApplyFunc& func, 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ArgExprs& args) 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_func (func), 12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args (args) {} 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrintExpr (ostream& os) const 12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BaseArgExprs args; 12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.push_back(m_args.a.get()); 12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.push_back(m_args.b.get()); 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.push_back(m_args.c.get()); 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.push_back(m_args.d.get()); 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_func.print(os, args); 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal doEvaluate (const EvalContext& ctx) const 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_func.apply(ctx, 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args.a->evaluate(ctx), m_args.b->evaluate(ctx), 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args.c->evaluate(ctx), m_args.d->evaluate(ctx)); 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doGetUsedFuncs (FuncSet& dst) const 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_func.getUsedFuncs(dst); 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args.a->getUsedFuncs(dst); 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args.b->getUsedFuncs(dst); 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args.c->getUsedFuncs(dst); 13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_args.d->getUsedFuncs(dst); 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ApplyFunc& m_func; 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ArgExprs m_args; 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13140557a707716b8a8722fa509455badf81633ad83bPyry Haulostemplate<typename T> 13150557a707716b8a8722fa509455badf81633ad83bPyry Haulosclass Alternatives : public Func<Signature<T, T, T> > 13160557a707716b8a8722fa509455badf81633ad83bPyry Haulos{ 13170557a707716b8a8722fa509455badf81633ad83bPyry Haulospublic: 13180557a707716b8a8722fa509455badf81633ad83bPyry Haulos typedef typename Alternatives::Sig Sig; 13190557a707716b8a8722fa509455badf81633ad83bPyry Haulos 13200557a707716b8a8722fa509455badf81633ad83bPyry Haulosprotected: 13210557a707716b8a8722fa509455badf81633ad83bPyry Haulos typedef typename Alternatives::IRet IRet; 13220557a707716b8a8722fa509455badf81633ad83bPyry Haulos typedef typename Alternatives::IArgs IArgs; 13230557a707716b8a8722fa509455badf81633ad83bPyry Haulos 13240557a707716b8a8722fa509455badf81633ad83bPyry Haulos virtual string getName (void) const { return "alternatives"; } 13250557a707716b8a8722fa509455badf81633ad83bPyry Haulos virtual void doPrintDefinition (std::ostream&) const {} 13260557a707716b8a8722fa509455badf81633ad83bPyry Haulos void doGetUsedFuncs (FuncSet&) const {} 13270557a707716b8a8722fa509455badf81633ad83bPyry Haulos 13280557a707716b8a8722fa509455badf81633ad83bPyry Haulos virtual IRet doApply (const EvalContext&, const IArgs& args) const 13290557a707716b8a8722fa509455badf81633ad83bPyry Haulos { 13300557a707716b8a8722fa509455badf81633ad83bPyry Haulos return unionIVal<T>(args.a, args.b); 13310557a707716b8a8722fa509455badf81633ad83bPyry Haulos } 13320557a707716b8a8722fa509455badf81633ad83bPyry Haulos 13330557a707716b8a8722fa509455badf81633ad83bPyry Haulos virtual void doPrint (ostream& os, const BaseArgExprs& args) const 13340557a707716b8a8722fa509455badf81633ad83bPyry Haulos { 13350557a707716b8a8722fa509455badf81633ad83bPyry Haulos os << "{" << *args[0] << " | " << *args[1] << "}"; 13360557a707716b8a8722fa509455badf81633ad83bPyry Haulos } 13370557a707716b8a8722fa509455badf81633ad83bPyry Haulos}; 13380557a707716b8a8722fa509455badf81633ad83bPyry Haulos 13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 13403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename Sig::Ret> createApply (const Func<Sig>& func, 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Func<Sig>::ArgExprs& args) 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exprP(new Apply<Sig>(func, args)); 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 13473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename Sig::Ret> createApply ( 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Func<Sig>& func, 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename Sig::Arg0>& arg0 = voidP(), 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename Sig::Arg1>& arg1 = voidP(), 13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename Sig::Arg2>& arg2 = voidP(), 13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename Sig::Arg3>& arg3 = voidP()) 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exprP(new Apply<Sig>(func, arg0, arg1, arg2, arg3)); 13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 13583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename Sig::Ret> Func<Sig>::operator() (const ExprP<typename Sig::Arg0>& arg0, 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename Sig::Arg1>& arg1, 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename Sig::Arg2>& arg2, 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename Sig::Arg3>& arg3) const 13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return createApply(*this, arg0, arg1, arg2, arg3); 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F> 13673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename F::Ret> app (const ExprP<typename F::Arg0>& arg0 = voidP(), 13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename F::Arg1>& arg1 = voidP(), 13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename F::Arg2>& arg2 = voidP(), 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<typename F::Arg3>& arg3 = voidP()) 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return createApply(instance<F>(), arg0, arg1, arg2, arg3); 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F> 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename F::IRet call (const EvalContext& ctx, 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename F::IArg0& arg0 = Void(), 13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename F::IArg1& arg1 = Void(), 13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename F::IArg2& arg2 = Void(), 13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename F::IArg3& arg3 = Void()) 13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return instance<F>().apply(ctx, arg0, arg1, arg2, arg3); 13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13850557a707716b8a8722fa509455badf81633ad83bPyry Haulostemplate <typename T> 13860557a707716b8a8722fa509455badf81633ad83bPyry HaulosExprP<T> alternatives (const ExprP<T>& arg0, 13870557a707716b8a8722fa509455badf81633ad83bPyry Haulos const ExprP<T>& arg1) 13880557a707716b8a8722fa509455badf81633ad83bPyry Haulos{ 13890557a707716b8a8722fa509455badf81633ad83bPyry Haulos return createApply<typename Alternatives<T>::Sig>(instance<Alternatives<T> >(), arg0, arg1); 13900557a707716b8a8722fa509455badf81633ad83bPyry Haulos} 13910557a707716b8a8722fa509455badf81633ad83bPyry Haulos 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ApplyVar : public Apply<Sig> 13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Ret Ret; 13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg0 Arg0; 13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg1 Arg1; 13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg2 Arg2; 14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg3 Arg3; 14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Expr<Ret>::Val Val; 14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Expr<Ret>::IVal IVal; 14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Func<Sig> ApplyFunc; 14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename ApplyFunc::ArgExprs ArgExprs; 14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ApplyVar (const ApplyFunc& func, 14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<Arg0>& arg0, 14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<Arg1>& arg1, 14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<Arg2>& arg2, 14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<Arg3>& arg3) 14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : Apply<Sig> (func, arg0, arg1, arg2, arg3) {} 14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IVal doEvaluate (const EvalContext& ctx) const 14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Variable<Arg0>& var0 = static_cast<const Variable<Arg0>&>(*this->m_args.a); 14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Variable<Arg1>& var1 = static_cast<const Variable<Arg1>&>(*this->m_args.b); 14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Variable<Arg2>& var2 = static_cast<const Variable<Arg2>&>(*this->m_args.c); 14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Variable<Arg3>& var3 = static_cast<const Variable<Arg3>&>(*this->m_args.d); 14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->m_func.apply(ctx, 14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.env.lookup(var0), ctx.env.lookup(var1), 14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.env.lookup(var2), ctx.env.lookup(var3)); 14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 14263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename Sig::Ret> applyVar (const Func<Sig>& func, 14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<typename Sig::Arg0>& arg0, 14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<typename Sig::Arg1>& arg1, 14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<typename Sig::Arg2>& arg2, 14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableP<typename Sig::Arg3>& arg3) 14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exprP(new ApplyVar<Sig>(func, arg0, arg1, arg2, arg3)); 14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig_> 14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DerivedFunc : public Func<Sig_> 14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::ArgExprs ArgExprs; 14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::IRet IRet; 14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::IArgs IArgs; 14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::Ret Ret; 14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::Arg0 Arg0; 14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::Arg1 Arg1; 14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::Arg2 Arg2; 14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::Arg3 Arg3; 14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::IArg0 IArg0; 14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::IArg1 IArg1; 14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::IArg2 IArg2; 14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename DerivedFunc::IArg3 IArg3; 14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrintDefinition (ostream& os) const 14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ParamNames& paramNames = this->getParamNames(); 14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initialize(); 14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << dataTypeNameOf<Ret>() << " " << this->getName() 14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "("; 14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg0>()) 14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << dataTypeNameOf<Arg0>() << " " << paramNames.a; 14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg1>()) 14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", " << dataTypeNameOf<Arg1>() << " " << paramNames.b; 14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg2>()) 14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", " << dataTypeNameOf<Arg2>() << " " << paramNames.c; 14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTypeValid<Arg3>()) 14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ", " << dataTypeNameOf<Arg3>() << " " << paramNames.d; 14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << ")\n{\n"; 14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_body.size(); ++ndx) 14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << *m_body[ndx]; 14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "return " << *m_ret << ";\n"; 14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "}\n"; 14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, 14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArgs& args) const 14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Environment funEnv; 14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IArgs& mutArgs = const_cast<IArgs&>(args); 14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initialize(); 14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funEnv.bind(*m_var0, args.a); 14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funEnv.bind(*m_var1, args.b); 14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funEnv.bind(*m_var2, args.c); 14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funEnv.bind(*m_var3, args.d); 14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry EvalContext funCtx(ctx.format, ctx.floatPrecision, funEnv, ctx.callDepth); 14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_body.size(); ++ndx) 14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_body[ndx]->execute(funCtx); 14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = m_ret->evaluate(funCtx); 14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [lauri] Store references instead of values in environment 15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const_cast<IArg0&>(mutArgs.a) = funEnv.lookup(*m_var0); 15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const_cast<IArg1&>(mutArgs.b) = funEnv.lookup(*m_var1); 15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const_cast<IArg2&>(mutArgs.c) = funEnv.lookup(*m_var2); 15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const_cast<IArg3&>(mutArgs.d) = funEnv.lookup(*m_var3); 15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doGetUsedFuncs (FuncSet& dst) const 15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initialize(); 15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (dst.insert(this).second) 15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_body.size(); ++ndx) 15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_body[ndx]->getUsedFuncs(dst); 15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ret->getUsedFuncs(dst); 15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual ExprP<Ret> doExpand (ExpandContext& ctx, const ArgExprs& args_) const = 0; 15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // These are transparently initialized when first needed. They cannot be 15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // initialized in the constructor because they depend on the doExpand 15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // method of the subclass. 15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mutable VariableP<Arg0> m_var0; 15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mutable VariableP<Arg1> m_var1; 15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mutable VariableP<Arg2> m_var2; 15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mutable VariableP<Arg3> m_var3; 15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mutable vector<StatementP> m_body; 15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mutable ExprP<Ret> m_ret; 15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void initialize (void) const 15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_ret) 15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ParamNames& paramNames = this->getParamNames(); 15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Counter symCounter; 15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExpandContext ctx (symCounter); 15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ArgExprs args; 15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.a = m_var0 = variable<Arg0>(paramNames.a); 15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.b = m_var1 = variable<Arg1>(paramNames.b); 15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.c = m_var2 = variable<Arg2>(paramNames.c); 15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry args.d = m_var3 = variable<Arg3>(paramNames.d); 15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ret = this->doExpand(ctx, args); 15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_body = ctx.getStatements(); 15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PrimitiveFunc : public Func<Sig> 15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename PrimitiveFunc::Ret Ret; 15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename PrimitiveFunc::ArgExprs ArgExprs; 15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrintDefinition (ostream&) const {} 15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doGetUsedFuncs (FuncSet&) const {} 15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Cond : public PrimitiveFunc<Signature<T, bool, T, T> > 15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Cond::IArgs IArgs; 15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Cond::IRet IRet; 15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "_cond"; 15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "(" << *args[0] << " ? " << *args[1] << " : " << *args[2] << ")"; 15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs)const 15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iargs.a.contains(true)) 15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = unionIVal<T>(ret, iargs.b); 15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iargs.a.contains(false)) 15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = unionIVal<T>(ret, iargs.c); 15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CompareOperator : public PrimitiveFunc<Signature<bool, T, T> > 16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename CompareOperator::IArgs IArgs; 16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename CompareOperator::IArg0 IArg0; 16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename CompareOperator::IArg1 IArg1; 16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename CompareOperator::IRet IRet; 16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "(" << *args[0] << getSymbol() << *args[1] << ")"; 16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext&, const IArgs& iargs) const 16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg0& arg0 = iargs.a; 16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg1& arg1 = iargs.b; 16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (canSucceed(arg0, arg1)) 16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= true; 16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (canFail(arg0, arg1)) 16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= false; 16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string getSymbol (void) const = 0; 16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool canSucceed (const IArg0&, const IArg1&) const = 0; 16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool canFail (const IArg0&, const IArg1&) const = 0; 16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LessThan : public CompareOperator<T> 16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "lessThan"; } 16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getSymbol (void) const { return "<"; } 16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool canSucceed (const Interval& a, const Interval& b) const 16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (a.lo() < b.hi()); 16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool canFail (const Interval& a, const Interval& b) const 16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return !(a.hi() < b.lo()); 16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 16553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<bool> operator< (const ExprP<T>& a, const ExprP<T>& b) 16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<LessThan<T> >(a, b); 16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 16613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<T> cond (const ExprP<bool>& test, 16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<T>& consequent, 16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<T>& alternative) 16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Cond<T> >(test, consequent, alternative); 16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * @} 16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FloatFunc1 : public PrimitiveFunc<Signature<float, float> > 16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext& ctx, const IArgs& iargs) const 16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->applyMonotone(ctx, iargs.a); 16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval applyMonotone (const EvalContext& ctx, const Interval& iarg0) const 16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret; 16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_INTERVAL_APPLY_MONOTONE1(ret, arg0, iarg0, val, 16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_SET_INTERVAL(val, point, 16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry point = this->applyPoint(ctx, arg0))); 16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= innerExtrema(ctx, iarg0); 16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret &= (this->getCodomain() | TCU_NAN); 16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.convert(ret); 16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual Interval innerExtrema (const EvalContext&, const Interval&) const 16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(); // empty interval, i.e. no extrema 16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual Interval applyPoint (const EvalContext& ctx, double arg0) const 17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double exact = this->applyExact(arg0); 17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double prec = this->precision(ctx, exact, arg0); 17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exact + Interval(-prec, prec); 17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual double applyExact (double) const 17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_THROW(InternalError, "Cannot apply"); 17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual Interval getCodomain (void) const 17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval::unbounded(true); 17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual double precision (const EvalContext& ctx, double, double) const = 0; 17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CFloatFunc1 : public FloatFunc1 17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CFloatFunc1 (const string& name, DoubleFunc1& func) 17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_name(name), m_func(func) {} 17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return m_name; } 17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double applyExact (double x) const { return m_func(x); } 17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_name; 17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DoubleFunc1& m_func; 17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FloatFunc2 : public PrimitiveFunc<Signature<float, float, float> > 17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext& ctx, const IArgs& iargs) const 17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->applyMonotone(ctx, iargs.a, iargs.b); 17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval applyMonotone (const EvalContext& ctx, 17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& xi, 17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& yi) const 17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval reti; 17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_INTERVAL_APPLY_MONOTONE2(reti, x, xi, y, yi, ret, 17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_SET_INTERVAL(ret, point, 17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry point = this->applyPoint(ctx, x, y))); 17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reti |= innerExtrema(ctx, xi, yi); 17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reti &= (this->getCodomain() | TCU_NAN); 17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.convert(reti); 17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual Interval innerExtrema (const EvalContext&, 17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval&, 17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval&) const 17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(); // empty interval, i.e. no extrema 17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual Interval applyPoint (const EvalContext& ctx, 1768653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double x, 1769653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double y) const 17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double exact = this->applyExact(x, y); 17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double prec = this->precision(ctx, exact, x, y); 17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exact + Interval(-prec, prec); 17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual double applyExact (double, double) const 17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_THROW(InternalError, "Cannot apply"); 17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual Interval getCodomain (void) const 17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval::unbounded(true); 17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual double precision (const EvalContext& ctx, 17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double ret, 17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double x, 17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double y) const = 0; 17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CFloatFunc2 : public FloatFunc2 17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CFloatFunc2 (const string& name, 17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DoubleFunc2& func) 17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_name(name) 17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_func(func) 18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return m_name; } 18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double applyExact (double x, double y) const { return m_func(x, y); } 18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_name; 18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DoubleFunc2& m_func; 18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InfixOperator : public FloatFunc2 18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string getSymbol (void) const = 0; 18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "(" << *args[0] << " " << getSymbol() << " " << *args[1] << ")"; 18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval applyPoint (const EvalContext& ctx, 1823653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double x, 1824653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double y) const 18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double exact = this->applyExact(x, y); 18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Allow either representable number on both sides of the exact value, 18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // but require exactly representable values to be preserved. 18302e751e3e77060f699c560104e82379d3ce54f67aPyry Haulos return ctx.format.roundOut(exact, !deIsInf(x) && !deIsInf(y)); 18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext&, double, double, double) const 18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0.0; 18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FloatFunc3 : public PrimitiveFunc<Signature<float, float, float, float> > 18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext& ctx, const IArgs& iargs) const 18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->applyMonotone(ctx, iargs.a, iargs.b, iargs.c); 18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval applyMonotone (const EvalContext& ctx, 18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& xi, 18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& yi, 18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& zi) const 18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval reti; 18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_INTERVAL_APPLY_MONOTONE3(reti, x, xi, y, yi, z, zi, ret, 18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_SET_INTERVAL(ret, point, 18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry point = this->applyPoint(ctx, x, y, z))); 18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.convert(reti); 18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual Interval applyPoint (const EvalContext& ctx, 1860653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double x, 1861653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double y, 1862653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double z) const 18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double exact = this->applyExact(x, y, z); 18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double prec = this->precision(ctx, exact, x, y, z); 18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return exact + Interval(-prec, prec); 18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual double applyExact (double, double, double) const 18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_THROW(InternalError, "Cannot apply"); 18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual double precision (const EvalContext& ctx, 18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double result, 18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double x, 18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double y, 18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double z) const = 0; 18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// We define syntactic sugar functions for expression constructors. Since 18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// these have the same names as ordinary mathematical operations (sin, log 18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// etc.), it's better to give them a dedicated namespace. 18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functions 18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace tcu; 18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Add : public InfixOperator 18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1892653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getName (void) const { return "add"; } 1893653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getSymbol (void) const { return "+"; } 18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext& ctx, 18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArgs& iargs) const 18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Fast-path for common case 18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iargs.a.isOrdinary() && iargs.b.isOrdinary()) 19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret; 19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_SET_INTERVAL_BOUNDS(ret, sum, 19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sum = iargs.a.lo() + iargs.b.lo(), 19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sum = iargs.a.hi() + iargs.b.hi()); 19052e751e3e77060f699c560104e82379d3ce54f67aPyry Haulos return ctx.format.convert(ctx.format.roundOut(ret, true)); 19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->applyMonotone(ctx, iargs.a, iargs.b); 19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 1911653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos double applyExact (double x, double y) const { return x + y; } 19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Mul : public InfixOperator 19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1917653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getName (void) const { return "mul"; } 1918653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getSymbol (void) const { return "*"; } 19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext& ctx, const IArgs& iargs) const 19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval a = iargs.a; 19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval b = iargs.b; 19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Fast-path for common case 19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (a.isOrdinary() && b.isOrdinary()) 19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret; 19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (a.hi() < 0) 19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry a = -a; 19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry b = -b; 19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (a.lo() >= 0 && b.lo() >= 0) 19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_SET_INTERVAL_BOUNDS(ret, prod, 19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry prod = iargs.a.lo() * iargs.b.lo(), 19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry prod = iargs.a.hi() * iargs.b.hi()); 19392e751e3e77060f699c560104e82379d3ce54f67aPyry Haulos return ctx.format.convert(ctx.format.roundOut(ret, true)); 19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (a.lo() >= 0 && b.hi() <= 0) 19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_SET_INTERVAL_BOUNDS(ret, prod, 19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry prod = iargs.a.hi() * iargs.b.lo(), 19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry prod = iargs.a.lo() * iargs.b.hi()); 19462e751e3e77060f699c560104e82379d3ce54f67aPyry Haulos return ctx.format.convert(ctx.format.roundOut(ret, true)); 19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->applyMonotone(ctx, iargs.a, iargs.b); 19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double applyExact (double x, double y) const { return x * y; } 19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval innerExtrema(const EvalContext&, const Interval& xi, const Interval& yi) const 19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (((xi.contains(-TCU_INFINITY) || xi.contains(TCU_INFINITY)) && yi.contains(0.0)) || 19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ((yi.contains(-TCU_INFINITY) || yi.contains(TCU_INFINITY)) && xi.contains(0.0))) 19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(TCU_NAN); 19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(); 19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Sub : public InfixOperator 19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1968653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getName (void) const { return "sub"; } 1969653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getSymbol (void) const { return "-"; } 19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext& ctx, const IArgs& iargs) const 19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Fast-path for common case 19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iargs.a.isOrdinary() && iargs.b.isOrdinary()) 19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret; 19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_SET_INTERVAL_BOUNDS(ret, diff, 19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry diff = iargs.a.lo() - iargs.b.hi(), 19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry diff = iargs.a.hi() - iargs.b.lo()); 19812e751e3e77060f699c560104e82379d3ce54f67aPyry Haulos return ctx.format.convert(ctx.format.roundOut(ret, true)); 19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->applyMonotone(ctx, iargs.a, iargs.b); 19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double applyExact (double x, double y) const { return x - y; } 19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Negate : public FloatFunc1 19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "_negate"; } 19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const { os << "-" << *args[0]; } 19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext&, double, double) const { return 0.0; } 20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double applyExact (double x) const { return -x; } 20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Div : public InfixOperator 20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2008653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getName (void) const { return "div"; } 20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 2011653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getSymbol (void) const { return "/"; } 20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval innerExtrema (const EvalContext&, 20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& nom, 20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& den) const 20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret; 20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (den.contains(0.0)) 20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (nom.contains(0.0)) 20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= TCU_NAN; 20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (nom.lo() < 0.0 || nom.hi() > 0.0) 20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= Interval::unbounded(); 20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20314fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos double applyExact (double x, double y) const { return x / y; } 20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20334fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos Interval applyPoint (const EvalContext& ctx, double x, double y) const 20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20354fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos Interval ret = FloatFunc2::applyPoint(ctx, x, y); 20364fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos 20374fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos if (!deIsInf(x) && !deIsInf(y) && y != 0.0) 20384fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos { 20394fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos const Interval dst = ctx.format.convert(ret); 20404fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos if (dst.contains(-TCU_INFINITY)) ret |= -ctx.format.getMaxValue(); 20414fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos if (dst.contains(+TCU_INFINITY)) ret |= +ctx.format.getMaxValue(); 20424fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos } 20434fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos 20444fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos return ret; 20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20474fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos double precision (const EvalContext& ctx, double ret, double, double den) const 20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& fmt = ctx.format; 20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2014-03-05 lauri] Check that the limits in GLSL 3.10 are actually correct. 20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // For now, we assume that division's precision is 2.5 ULP when the value is within 20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // [2^MINEXP, 2^MAXEXP-1] 20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (den == 0.0) 20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0.0; // Result must be exactly inf 20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (de::inBounds(deAbs(den), 20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deLdExp(1.0, fmt.getMinExp()), 20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deLdExp(1.0, fmt.getMaxExp() - 1))) 20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return fmt.ulp(ret, 2.5); 20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return TCU_INFINITY; // Can be any number, but must be a number. 20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InverseSqrt : public FloatFunc1 20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "inversesqrt"; } 20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double applyExact (double x) const { return 1.0 / deSqrt(x); } 20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext& ctx, double ret, double x) const 20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return x <= 0 ? TCU_NAN : ctx.format.ulp(ret, 2.0); 20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval getCodomain (void) const 20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(0.0, TCU_INFINITY); 20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ExpFunc : public CFloatFunc1 20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExpFunc (const string& name, DoubleFunc1& func) 20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : CFloatFunc1(name, func) {} 20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext& ctx, double ret, double x) const 20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (ctx.floatPrecision) 20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::PRECISION_HIGHP: 20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, 3.0 + 2.0 * deAbs(x)); 20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::PRECISION_MEDIUMP: 20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, 2.0 + 2.0 * deAbs(x)); 20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::PRECISION_LOWP: 21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, 2.0); 21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 21021cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry DE_FATAL("Impossible"); 21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval getCodomain (void) const 21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(0.0, TCU_INFINITY); 21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Exp2 : public ExpFunc { public: Exp2 (void) : ExpFunc("exp2", deExp2) {} }; 21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Exp : public ExpFunc { public: Exp (void) : ExpFunc("exp", deExp) {} }; 21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> exp2 (const ExprP<float>& x) { return app<Exp2>(x); } 21173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> exp (const ExprP<float>& x) { return app<Exp>(x); } 21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LogFunc : public CFloatFunc1 21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LogFunc (const string& name, DoubleFunc1& func) 21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : CFloatFunc1(name, func) {} 21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext& ctx, double ret, double x) const 21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (x <= 0) 21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return TCU_NAN; 21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (ctx.floatPrecision) 21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::PRECISION_HIGHP: 21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (0.5 <= x && x <= 2.0) ? deLdExp(1.0, -21) : ctx.format.ulp(ret, 3.0); 21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::PRECISION_MEDIUMP: 21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (0.5 <= x && x <= 2.0) ? deLdExp(1.0, -7) : ctx.format.ulp(ret, 2.0); 21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::PRECISION_LOWP: 21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, 2.0); 21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 21401cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry DE_FATAL("Impossible"); 21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Log2 : public LogFunc { public: Log2 (void) : LogFunc("log2", deLog2) {} }; 21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Log : public LogFunc { public: Log (void) : LogFunc("log", deLog) {} }; 21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> log2 (const ExprP<float>& x) { return app<Log2>(x); } 21513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> log (const ExprP<float>& x) { return app<Log>(x); } 21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_CONSTRUCTOR1(CLASS, TRET, NAME, T0) \ 21543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<TRET> NAME (const ExprP<T0>& arg0) { return app<CLASS>(arg0); } 21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_DERIVED1(CLASS, TRET, NAME, T0, ARG0, EXPANSION) \ 2157dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsiehclass CLASS : public DerivedFunc<Signature<TRET, T0> > /* NOLINT(CLASS) */ \ 21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ \ 21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: \ 21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return #NAME; } \ 21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry \ 21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: \ 21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<TRET> doExpand (ExpandContext&, \ 21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CLASS::ArgExprs& args_) const \ 21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { \ 2166dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh const ExprP<float>& (ARG0) = args_.a; \ 21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return EXPANSION; \ 21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } \ 21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; \ 21703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_CONSTRUCTOR1(CLASS, TRET, NAME, T0) 21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_DERIVED_FLOAT1(CLASS, NAME, ARG0, EXPANSION) \ 21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DEFINE_DERIVED1(CLASS, float, NAME, float, ARG0, EXPANSION) 21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_CONSTRUCTOR2(CLASS, TRET, NAME, T0, T1) \ 21763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<TRET> NAME (const ExprP<T0>& arg0, const ExprP<T1>& arg1) \ 21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ \ 21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<CLASS>(arg0, arg1); \ 21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_DERIVED2(CLASS, TRET, NAME, T0, Arg0, T1, Arg1, EXPANSION) \ 2182dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsiehclass CLASS : public DerivedFunc<Signature<TRET, T0, T1> > /* NOLINT(CLASS) */ \ 21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ \ 21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: \ 21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return #NAME; } \ 21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry \ 21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: \ 21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<TRET> doExpand (ExpandContext&, const ArgExprs& args_) const \ 21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { \ 2190dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh const ExprP<T0>& (Arg0) = args_.a; \ 2191dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh const ExprP<T1>& (Arg1) = args_.b; \ 21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return EXPANSION; \ 21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } \ 21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; \ 21953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_CONSTRUCTOR2(CLASS, TRET, NAME, T0, T1) 21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_DERIVED_FLOAT2(CLASS, NAME, Arg0, Arg1, EXPANSION) \ 21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DEFINE_DERIVED2(CLASS, float, NAME, float, Arg0, float, Arg1, EXPANSION) 21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_CONSTRUCTOR3(CLASS, TRET, NAME, T0, T1, T2) \ 22013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<TRET> NAME (const ExprP<T0>& arg0, const ExprP<T1>& arg1, const ExprP<T2>& arg2) \ 22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ \ 22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<CLASS>(arg0, arg1, arg2); \ 22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_DERIVED3(CLASS, TRET, NAME, T0, ARG0, T1, ARG1, T2, ARG2, EXPANSION) \ 2207dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsiehclass CLASS : public DerivedFunc<Signature<TRET, T0, T1, T2> > /* NOLINT(CLASS) */ \ 22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ \ 22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: \ 22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return #NAME; } \ 22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry \ 22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: \ 22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<TRET> doExpand (ExpandContext&, const ArgExprs& args_) const \ 22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { \ 2215dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh const ExprP<T0>& (ARG0) = args_.a; \ 2216dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh const ExprP<T1>& (ARG1) = args_.b; \ 2217dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh const ExprP<T2>& (ARG2) = args_.c; \ 22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return EXPANSION; \ 22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } \ 22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; \ 22213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_CONSTRUCTOR3(CLASS, TRET, NAME, T0, T1, T2) 22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_DERIVED_FLOAT3(CLASS, NAME, ARG0, ARG1, ARG2, EXPANSION) \ 22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DEFINE_DERIVED3(CLASS, float, NAME, float, ARG0, float, ARG1, float, ARG2, EXPANSION) 22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DEFINE_CONSTRUCTOR4(CLASS, TRET, NAME, T0, T1, T2, T3) \ 22273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<TRET> NAME (const ExprP<T0>& arg0, const ExprP<T1>& arg1, \ 22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<T2>& arg2, const ExprP<T3>& arg3) \ 22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ \ 22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<CLASS>(arg0, arg1, arg2, arg3); \ 22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry HaulosDEFINE_DERIVED_FLOAT1(Sqrt, sqrt, x, constant(1.0f) / app<InverseSqrt>(x)); 22343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT2(Pow, pow, x, y, exp2(y * log2(x))); 2235653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry HaulosDEFINE_DERIVED_FLOAT1(Radians, radians, d, (constant(DE_PI) / constant(180.0f)) * d); 2236653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry HaulosDEFINE_DERIVED_FLOAT1(Degrees, degrees, r, (constant(180.0f) / constant(DE_PI)) * r); 22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TrigFunc : public CFloatFunc1 22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TrigFunc (const string& name, 22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DoubleFunc1& func, 22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& loEx, 22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& hiEx) 22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : CFloatFunc1 (name, func) 22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_loExtremum (loEx) 22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_hiExtremum (hiEx) {} 22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval innerExtrema (const EvalContext&, const Interval& angle) const 22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double lo = angle.lo(); 22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double hi = angle.hi(); 22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int loSlope = doGetSlope(lo); 22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int hiSlope = doGetSlope(hi); 22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Detect the high and low values the function can take between the 22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // interval endpoints. 22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (angle.length() >= 2.0 * DE_PI_DOUBLE) 22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // The interval is longer than a full cycle, so it must get all possible values. 22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_hiExtremum | m_loExtremum; 22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (loSlope == 1 && hiSlope == -1) 22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // The slope can change from positive to negative only at the maximum value. 22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_hiExtremum; 22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (loSlope == -1 && hiSlope == 1) 22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // The slope can change from negative to positive only at the maximum value. 22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_loExtremum; 22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (loSlope == hiSlope && 22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deIntSign(applyExact(hi) - applyExact(lo)) * loSlope == -1) 22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // The slope has changed twice between the endpoints, so both extrema are included. 22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_hiExtremum | m_loExtremum; 22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(); 22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval getCodomain (void) const 22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Ensure that result is always within [-1, 1], or NaN (for +-inf) 22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Interval(-1.0, 1.0) | TCU_NAN; 22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext& ctx, double ret, double arg) const 22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ctx.floatPrecision == glu::PRECISION_HIGHP) 22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Use precision from OpenCL fast relaxed math 22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (-DE_PI_DOUBLE <= arg && arg <= DE_PI_DOUBLE) 22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return deLdExp(1.0, -11); 22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // "larger otherwise", let's pick |x| * 2^-12 , which is slightly over 23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // 2^-11 at x == pi. 23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return deLdExp(deAbs(arg), -12); 23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23064fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos else if (ctx.floatPrecision == glu::PRECISION_MEDIUMP) 23074fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos { 23084fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos if (-DE_PI_DOUBLE <= arg && arg <= DE_PI_DOUBLE) 23094fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos { 23104fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos // from OpenCL half-float extension specification 23114fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos return ctx.format.ulp(ret, 2.0); 23124fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos } 23134fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos else 23144fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos { 23154fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos // |x| * 2^-10, slightly larger than 2 ULP at x == pi 2316b5d3366020ce9abfdbd6d10686d8c2fea7787ce9Pyry Haulos return deLdExp(deAbs(arg), -10); 23174fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos } 23184fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos } 23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23214fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos DE_ASSERT(ctx.floatPrecision == glu::PRECISION_LOWP); 23224fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos 23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // from OpenCL half-float extension specification 23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, 2.0); 23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual int doGetSlope (double angle) const = 0; 23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval m_loExtremum; 23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval m_hiExtremum; 23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Sin : public TrigFunc 23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Sin (void) : TrigFunc("sin", deSin, -1.0, 1.0) {} 23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int doGetSlope (double angle) const { return deIntSign(deCos(angle)); } 23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> sin (const ExprP<float>& x) { return app<Sin>(x); } 23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Cos : public TrigFunc 23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Cos (void) : TrigFunc("cos", deCos, -1.0, 1.0) {} 23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int doGetSlope (double angle) const { return -deIntSign(deSin(angle)); } 23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> cos (const ExprP<float>& x) { return app<Cos>(x); } 23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT1(Tan, tan, x, sin(x) * (constant(1.0f) / cos(x))); 23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2358e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulosclass ASin : public CFloatFunc1 2359e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos{ 2360e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulospublic: 2361e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos ASin (void) : CFloatFunc1("asin", deAsin) {} 2362e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos 2363e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulosprotected: 2364e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos double precision (const EvalContext& ctx, double, double x) const 2365e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos { 2366e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos if (!de::inBounds(x, -1.0, 1.0)) 2367e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos return TCU_NAN; 2368e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos 2369e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos if (ctx.floatPrecision == glu::PRECISION_HIGHP) 2370e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos { 2371e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos // Absolute error of 2^-11 2372e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos return deLdExp(1.0, -11); 2373e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos } 2374e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos else 2375e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos { 2376e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos // Absolute error of 2^-8 2377e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos return deLdExp(1.0, -8); 2378e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos } 2379e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos 2380e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos } 2381e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos}; 2382e8efb729845f35160e5ab692226a1394154ccb24Pyry Haulos 23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ArcTrigFunc : public CFloatFunc1 23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ArcTrigFunc (const string& name, 23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DoubleFunc1& func, 23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precisionULPs, 23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& domain, 23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& codomain) 23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : CFloatFunc1 (name, func) 23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_precision (precisionULPs) 23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_domain (domain) 23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_codomain (codomain) {} 23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext& ctx, double ret, double x) const 23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_domain.contains(x)) 24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return TCU_NAN; 24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ctx.floatPrecision == glu::PRECISION_HIGHP) 24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24044fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos // Use OpenCL's fast relaxed math precision 24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, m_precision); 24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Use OpenCL half-float spec 24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, 2.0); 24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // We could implement getCodomain with m_codomain, but choose not to, 24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // because it seems too strict with trascendental constants like pi. 24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double m_precision; 24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval m_domain; 24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval m_codomain; 24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ACos : public ArcTrigFunc 24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 24254fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos ACos (void) : ArcTrigFunc("acos", deAcos, 4096.0, 24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval(-1.0, 1.0), 24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval(0.0, DE_PI_DOUBLE)) {} 24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ATan : public ArcTrigFunc 24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 24334fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos ATan (void) : ArcTrigFunc("atan", deAtanOver, 4096.0, 24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval::unbounded(), 24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval(-DE_PI_DOUBLE * 0.5, DE_PI_DOUBLE * 0.5)) {} 24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ATan2 : public CFloatFunc2 24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ATan2 (void) : CFloatFunc2 ("atan", deAtan2) {} 24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 24444fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos Interval innerExtrema (const EvalContext& ctx, 24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Interval& yi, 2446653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos const Interval& xi) const 24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret; 24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (yi.contains(0.0)) 24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (xi.contains(0.0)) 24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= TCU_NAN; 24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (xi.intersects(Interval(-TCU_INFINITY, 0.0))) 24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= Interval(-DE_PI_DOUBLE, DE_PI_DOUBLE); 24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24584fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos if (ctx.format.hasInf() != YES && (!yi.isFinite() || !xi.isFinite())) 24594fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos { 24604fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos // Infinities may not be supported, allow anything, including NaN 24614fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos ret |= TCU_NAN; 24624fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos } 24634fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos 24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext& ctx, double ret, double, double) const 24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ctx.floatPrecision == glu::PRECISION_HIGHP) 24704fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos return ctx.format.ulp(ret, 4096.0); 24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ctx.format.ulp(ret, 2.0); 24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Codomain could be [-pi, pi], but that would probably be too strict. 24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT1(Sinh, sinh, x, (exp(x) - exp(-x)) / constant(2.0f)); 24793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT1(Cosh, cosh, x, (exp(x) + exp(-x)) / constant(2.0f)); 24803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT1(Tanh, tanh, x, sinh(x) / cosh(x)); 24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// These are not defined as derived forms in the GLSL ES spec, but 24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// that gives us a reasonable precision. 24843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT1(ASinh, asinh, x, log(x + sqrt(x * x + constant(1.0f)))); 2485efdc11737f4ca604e837bdfd8a0675e3c6c1c24fPyry HaulosDEFINE_DERIVED_FLOAT1(ACosh, acosh, x, log(x + sqrt(alternatives((x + constant(1.0f)) * (x - constant(1.0f)), 2486efdc11737f4ca604e837bdfd8a0675e3c6c1c24fPyry Haulos (x*x - constant(1.0f)))))); 24873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT1(ATanh, atanh, x, constant(0.5f) * log((constant(1.0f) + x) / 24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (constant(1.0f) - x))); 24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GetComponent : public PrimitiveFunc<Signature<typename T::Element, T, int> > 24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GetComponent::IRet IRet; 24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "_getComponent"; } 24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void print (ostream& os, 24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BaseArgExprs& args) const 25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << *args[0] << "[" << *args[1] << "]"; 25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 2505653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos IRet doApply (const EvalContext&, 25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename GetComponent::IArgs& iargs) const 25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int compNdx = 0; compNdx < T::SIZE; ++compNdx) 25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iargs.b.contains(compNdx)) 25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = unionIVal<typename T::Element>(ret, iargs.a[compNdx]); 25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 25223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename T::Element> getComponent (const ExprP<T>& container, int ndx) 25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(0 <= ndx && ndx < T::SIZE); 25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<GetComponent<T> >(container, constant(ndx)); 25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> string vecNamePrefix (void); 25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> string vecNamePrefix<float> (void) { return ""; } 25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> string vecNamePrefix<int> (void) { return "i"; } 25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> string vecNamePrefix<bool> (void) { return "b"; } 25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> 25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring vecName (void) { return vecNamePrefix<T>() + "vec" + de::toString(Size); } 25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> class GenVec; 25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenVec<T, 1> : public DerivedFunc<Signature<T, T> > 25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenVec<T, 1>::ArgExprs ArgExprs; 25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "_" + vecName<T, 1>(); 25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<T> doExpand (ExpandContext&, const ArgExprs& args) const { return args.a; } 25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenVec<T, 2> : public PrimitiveFunc<Signature<Vector<T, 2>, T, T> > 25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenVec::IRet IRet; 25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenVec::IArgs IArgs; 25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vecName<T, 2>(); 25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return IRet(iargs.a, iargs.b); 25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenVec<T, 3> : public PrimitiveFunc<Signature<Vector<T, 3>, T, T, T> > 25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenVec::IRet IRet; 25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenVec::IArgs IArgs; 25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vecName<T, 3>(); 25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return IRet(iargs.a, iargs.b, iargs.c); 25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenVec<T, 4> : public PrimitiveFunc<Signature<Vector<T, 4>, T, T, T, T> > 25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenVec::IRet IRet; 25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenVec::IArgs IArgs; 25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return vecName<T, 4>(); } 26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return IRet(iargs.a, iargs.b, iargs.c, iargs.d); 26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Columns> 26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenMat; 26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows> 26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenMat<T, Rows, 2> : public PrimitiveFunc< 26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<Matrix<T, Rows, 2>, Vector<T, Rows>, Vector<T, Rows> > > 26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::Ret Ret; 26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::IRet IRet; 26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::IArgs IArgs; 26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return dataTypeNameOf<Ret>(); 26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[0] = iargs.a; 26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[1] = iargs.b; 26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows> 26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenMat<T, Rows, 3> : public PrimitiveFunc< 26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<Matrix<T, Rows, 3>, Vector<T, Rows>, Vector<T, Rows>, Vector<T, Rows> > > 26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::Ret Ret; 26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::IRet IRet; 26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::IArgs IArgs; 26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return dataTypeNameOf<Ret>(); 26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[0] = iargs.a; 26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[1] = iargs.b; 26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[2] = iargs.c; 26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows> 26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenMat<T, Rows, 4> : public PrimitiveFunc< 26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<Matrix<T, Rows, 4>, 26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vector<T, Rows>, Vector<T, Rows>, Vector<T, Rows>, Vector<T, Rows> > > 26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::Ret Ret; 26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::IRet IRet; 26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenMat::IArgs IArgs; 26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return dataTypeNameOf<Ret>(); 26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[0] = iargs.a; 26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[1] = iargs.b; 26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[2] = iargs.c; 26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[3] = iargs.d; 26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows> 26923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<T, Rows, 2> > mat2 (const ExprP<Vector<T, Rows> >& arg0, 26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<T, Rows> >& arg1) 26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<GenMat<T, Rows, 2> >(arg0, arg1); 26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows> 26993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<T, Rows, 3> > mat3 (const ExprP<Vector<T, Rows> >& arg0, 27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<T, Rows> >& arg1, 27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<T, Rows> >& arg2) 27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<GenMat<T, Rows, 3> >(arg0, arg1, arg2); 27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows> 27073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<T, Rows, 4> > mat4 (const ExprP<Vector<T, Rows> >& arg0, 27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<T, Rows> >& arg1, 27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<T, Rows> >& arg2, 27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<T, Rows> >& arg3) 27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<GenMat<T, Rows, 4> >(arg0, arg1, arg2, arg3); 27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Rows, int Cols> 27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MatNeg : public PrimitiveFunc<Signature<Matrix<float, Rows, Cols>, 27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Rows, Cols> > > 27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatNeg::IRet IRet; 27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatNeg::IArgs IArgs; 27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "_matNeg"; 27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "-(" << *args[0] << ")"; 27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < Cols; ++col) 27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < Rows; ++row) 27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[col][row] = -iargs.a[col][row]; 27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename Sig> 27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CompWiseFunc : public PrimitiveFunc<Sig> 27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Func<Signature<T, T, T> > ScalarFunc; 27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return doGetScalarFunc().getName(); 27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, 27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BaseArgExprs& args) const 27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry doGetScalarFunc().print(os, args); 27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual 27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ScalarFunc& doGetScalarFunc (void) const = 0; 27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Rows, int Cols> 27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CompMatFuncBase : public CompWiseFunc<float, Signature<Matrix<float, Rows, Cols>, 27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Rows, Cols>, 27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Rows, Cols> > > 27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename CompMatFuncBase::IRet IRet; 27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename CompMatFuncBase::IArgs IArgs; 27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, const IArgs& iargs) const 27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < Cols; ++col) 27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < Rows; ++row) 27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[col][row] = this->doGetScalarFunc().apply(ctx, 27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iargs.a[col][row], 27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iargs.b[col][row]); 27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F, int Rows, int Cols> 27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CompMatFunc : public CompMatFuncBase<Rows, Cols> 27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename CompMatFunc::ScalarFunc& doGetScalarFunc (void) const 28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return instance<F>(); 28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ScalarMatrixCompMult : public Mul 28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "matrixCompMult"; 28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Func<Sig>::doPrint(os, args); 28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Rows, int Cols> 28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MatrixCompMult : public CompMatFunc<ScalarMatrixCompMult, Rows, Cols> 28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Rows, int Cols> 28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ScalarMatFuncBase : public CompWiseFunc<float, Signature<Matrix<float, Rows, Cols>, 28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Rows, Cols>, 28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float> > 28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename ScalarMatFuncBase::IRet IRet; 28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename ScalarMatFuncBase::IArgs IArgs; 28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, const IArgs& iargs) const 28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < Cols; ++col) 28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < Rows; ++row) 28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[col][row] = this->doGetScalarFunc().apply(ctx, iargs.a[col][row], iargs.b); 28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F, int Rows, int Cols> 28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ScalarMatFunc : public ScalarMatFuncBase<Rows, Cols> 28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename ScalarMatFunc::ScalarFunc& doGetScalarFunc (void) const 28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return instance<F>(); 28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, int Size> struct GenXType; 28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T> 28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct GenXType<T, 1> 28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ExprP<T> genXType (const ExprP<T>& x) { return x; } 28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T> 28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct GenXType<T, 2> 28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ExprP<Vector<T, 2> > genXType (const ExprP<T>& x) 28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<GenVec<T, 2> >(x, x); 28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T> 28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct GenXType<T, 3> 28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ExprP<Vector<T, 3> > genXType (const ExprP<T>& x) 28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<GenVec<T, 3> >(x, x, x); 28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T> 28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct GenXType<T, 4> 28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ExprP<Vector<T, 4> > genXType (const ExprP<T>& x) 28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<GenVec<T, 4> >(x, x, x, x); 28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Returns an expression of vector of size `Size` (or scalar if Size == 1), 28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! with each element initialized with the expression `x`. 28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, int Size> 28993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename ContainerOf<T, Size>::Container> genXType (const ExprP<T>& x) 29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return GenXType<T, Size>::genXType(x); 29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef GenVec<float, 2> FloatVec2; 29053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_CONSTRUCTOR2(FloatVec2, Vec2, vec2, float, float) 29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef GenVec<float, 3> FloatVec3; 29083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_CONSTRUCTOR3(FloatVec3, Vec3, vec3, float, float, float) 29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef GenVec<float, 4> FloatVec4; 29113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_CONSTRUCTOR4(FloatVec4, Vec4, vec4, float, float, float, float) 29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Dot : public DerivedFunc<Signature<float, Vector<float, Size>, Vector<float, Size> > > 29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Dot::ArgExprs ArgExprs; 29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "dot"; 29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 2925653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<float> doExpand (ExpandContext&, const ArgExprs& args) const 29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<float> val = args.a[0] * args.b[0]; 29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 1; ndx < Size; ++ndx) 29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry val = val + args.a[ndx] * args.b[ndx]; 29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return val; 29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Dot<1> : public DerivedFunc<Signature<float, float, float> > 29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "dot"; 29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2945653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<float> doExpand (ExpandContext&, const ArgExprs& args) const 29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return args.a * args.b; 29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 29523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> dot (const ExprP<Vector<float, Size> >& x, const ExprP<Vector<float, Size> >& y) 29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Dot<Size> >(x, y); 29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> dot (const ExprP<float>& x, const ExprP<float>& y) 29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Dot<1> >(x, y); 29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Length : public DerivedFunc< 29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<float, typename ContainerOf<float, Size>::Container> > 29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Length::ArgExprs ArgExprs; 29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "length"; 29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<float> doExpand (ExpandContext&, const ArgExprs& args) const 29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sqrt(dot(args.a, args.a)); 29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 29823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> length (const ExprP<typename ContainerOf<float, Size>::Container>& x) 29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Length<Size> >(x); 29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Distance : public DerivedFunc< 29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<float, 29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container, 29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container> > 29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Distance::Ret Ret; 29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Distance::ArgExprs ArgExprs; 29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "distance"; 30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 3003653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<Ret> doExpand (ExpandContext&, const ArgExprs& args) const 30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return length<Size>(args.a - args.b); 30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// cross 30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Cross : public DerivedFunc<Signature<Vec3, Vec3, Vec3> > 30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "cross"; 30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 3020653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<Vec3> doExpand (ExpandContext&, const ArgExprs& x) const 30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vec3(x.a[1] * x.b[2] - x.b[1] * x.a[2], 30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry x.a[2] * x.b[0] - x.b[2] * x.a[0], 30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry x.a[0] * x.b[1] - x.b[0] * x.a[1]); 30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_CONSTRUCTOR2(Cross, Vec3, cross, Vec3, Vec3) 30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Normalize : public DerivedFunc< 30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<typename ContainerOf<float, Size>::Container, 30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container> > 30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Normalize::Ret Ret; 30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Normalize::ArgExprs ArgExprs; 30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "normalize"; 30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> doExpand (ExpandContext&, const ArgExprs& args) const 30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return args.a / length<Size>(args.a); 30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FaceForward : public DerivedFunc< 30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<typename ContainerOf<float, Size>::Container, 30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container, 30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container, 30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container> > 30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename FaceForward::Ret Ret; 30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename FaceForward::ArgExprs ArgExprs; 30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "faceforward"; 30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> doExpand (ExpandContext&, const ArgExprs& args) const 30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return cond(dot(args.c, args.b) < constant(0.0f), args.a, -args.a); 30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3076919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvitemplate<int Size, typename Ret, typename Arg0, typename Arg1> 3077919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvistruct ApplyReflect 3078919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi{ 3079919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi static ExprP<Ret> apply (ExpandContext& ctx, 3080919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi const ExprP<Arg0>& i, 3081919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi const ExprP<Arg1>& n) 3082919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi { 3083919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi const ExprP<float> dotNI = bindExpression("dotNI", ctx, dot(n, i)); 3084919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi 3085919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi return i - alternatives((n * dotNI) * constant(2.0f), 3086919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi n * (dotNI * constant(2.0f))); 3087919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi }; 3088919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi}; 3089919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi 3090919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvitemplate<typename Ret, typename Arg0, typename Arg1> 3091919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvistruct ApplyReflect<1, Ret, Arg0, Arg1> 3092919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi{ 309381134a02ea7237b1130228f52f0572c0d9369199Pyry Haulos static ExprP<Ret> apply (ExpandContext&, 3094919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi const ExprP<Arg0>& i, 3095919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi const ExprP<Arg1>& n) 3096919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi { 3097919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi return i - alternatives(alternatives((n * (n*i)) * constant(2.0f), 3098919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi n * ((n*i) * constant(2.0f))), 3099919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi (n * n) * (i * constant(2.0f))); 3100919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi }; 3101919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi}; 3102919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi 31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Reflect : public DerivedFunc< 31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<typename ContainerOf<float, Size>::Container, 31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container, 31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container> > 31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Reflect::Ret Ret; 3111123c801f106dd1157fc889eaec934272ac6be937Pyry Haulos typedef typename Reflect::Arg0 Arg0; 3112123c801f106dd1157fc889eaec934272ac6be937Pyry Haulos typedef typename Reflect::Arg1 Arg1; 31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Reflect::ArgExprs ArgExprs; 31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "reflect"; 31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 3121123c801f106dd1157fc889eaec934272ac6be937Pyry Haulos ExprP<Ret> doExpand (ExpandContext& ctx, const ArgExprs& args) const 31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3123123c801f106dd1157fc889eaec934272ac6be937Pyry Haulos const ExprP<Arg0>& i = args.a; 3124123c801f106dd1157fc889eaec934272ac6be937Pyry Haulos const ExprP<Arg1>& n = args.b; 3125123c801f106dd1157fc889eaec934272ac6be937Pyry Haulos 3126919e0bc33b7fa8a27131967a02c6ceca3c8d1009Mika Isojärvi return ApplyReflect<Size, Ret, Arg0, Arg1>::apply(ctx, i, n); 31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Refract : public DerivedFunc< 31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Signature<typename ContainerOf<float, Size>::Container, 31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container, 31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<float, Size>::Container, 31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float> > 31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Refract::Ret Ret; 31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Refract::Arg0 Arg0; 31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Refract::Arg1 Arg1; 31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Refract::ArgExprs ArgExprs; 31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "refract"; 31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> doExpand (ExpandContext& ctx, const ArgExprs& args) const 31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg0>& i = args.a; 31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Arg1>& n = args.b; 31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& eta = args.c; 31542992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi const ExprP<float> dotNI = bindExpression("dotNI", ctx, dot(n, i)); 31552992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi const ExprP<float> k1 = bindExpression("k1", ctx, constant(1.0f) - eta * eta * 31562992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi (constant(1.0f) - dotNI * dotNI)); 31572992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi 31582992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi const ExprP<float> k2 = bindExpression("k2", ctx, 31592992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi (((dotNI * (-dotNI)) + constant(1.0f)) * eta) 31602992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi * (-eta) + constant(1.0f)); 31612992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi const ExprP<float> k = bindExpression("k", ctx, alternatives(k1, k2)); 31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31632992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi return cond(k < constant(0.0f), 31642992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi genXType<float, Size>(constant(0.0f)), 31652992eb5165ed88d61466f19d1608f6b4bbd14427Mika Isojärvi i * eta - n * (eta * dotNI + sqrt(k))); 31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PreciseFunc1 : public CFloatFunc1 31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PreciseFunc1 (const string& name, DoubleFunc1& func) : CFloatFunc1(name, func) {} 31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext&, double, double) const { return 0.0; } 31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Abs : public PreciseFunc1 31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Abs (void) : PreciseFunc1("abs", deAbs) {} 31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Sign : public PreciseFunc1 31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Sign (void) : PreciseFunc1("sign", deSign) {} 31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Floor : public PreciseFunc1 31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Floor (void) : PreciseFunc1("floor", deFloor) {} 31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Trunc : public PreciseFunc1 31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Trunc (void) : PreciseFunc1("trunc", deTrunc) {} 31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Round : public FloatFunc1 32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "round"; } 32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval applyPoint (const EvalContext&, double x) const 32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double truncated = 0.0; 32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double fract = deModf(x, &truncated); 32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret; 32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (fabs(fract) <= 0.5) 32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= truncated; 32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (fabs(fract) >= 0.5) 32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= truncated + deSign(fract); 32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext&, double, double) const { return 0.0; } 32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RoundEven : public PreciseFunc1 32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RoundEven (void) : PreciseFunc1("roundEven", deRoundEven) {} 32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Ceil : public PreciseFunc1 32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Ceil (void) : PreciseFunc1("ceil", deCeil) {} 32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT1(Fract, fract, x, x - app<Floor>(x)); 32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PreciseFunc2 : public CFloatFunc2 32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PreciseFunc2 (const string& name, DoubleFunc2& func) : CFloatFunc2(name, func) {} 32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext&, double, double, double) const { return 0.0; } 32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDEFINE_DERIVED_FLOAT2(Mod, mod, x, y, x - y * app<Floor>(x / y)); 32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Modf : public PrimitiveFunc<Signature<float, float, float> > 32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "modf"; 32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 325731805e60533f21575d584aa2a8c1d738b7fda56ePyry Haulos IRet doApply (const EvalContext&, const IArgs& iargs) const 32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval fracIV; 32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval& wholeIV = const_cast<Interval&>(iargs.b); 32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double intPart = 0; 32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_INTERVAL_APPLY_MONOTONE1(fracIV, x, iargs.a, frac, frac = deModf(x, &intPart)); 32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_INTERVAL_APPLY_MONOTONE1(wholeIV, x, iargs.a, whole, 32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deModf(x, &intPart); whole = intPart); 32664fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos 326718243b3e2d961ecbd5f00139a2ed1a5e777da562Pyry Haulos if (!iargs.a.isFinite()) 32684fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos { 32694fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos // Behavior on modf(Inf) not well-defined, allow anything as a fractional part 327018243b3e2d961ecbd5f00139a2ed1a5e777da562Pyry Haulos // See Khronos bug 13907 32714fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos fracIV |= TCU_NAN; 32724fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos } 32734fdcdd50d72a1317dbab9f75738e5bb9ccd30634Pyry Haulos 32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return fracIV; 32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getOutParamIndex (void) const 32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Min : public PreciseFunc2 { public: Min (void) : PreciseFunc2("min", deMin) {} }; 32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Max : public PreciseFunc2 { public: Max (void) : PreciseFunc2("max", deMax) {} }; 32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Clamp : public FloatFunc3 32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "clamp"; } 32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double applyExact (double x, double minVal, double maxVal) const 32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::min(de::max(x, minVal), maxVal); 32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double precision (const EvalContext&, double, double, double minVal, double maxVal) const 32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return minVal > maxVal ? TCU_NAN : 0.0; 32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> clamp(const ExprP<float>& x, const ExprP<float>& minVal, const ExprP<float>& maxVal) 33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Clamp>(x, minVal, maxVal); 33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33076c1b3db5fb439806b9b67442f1042615ffa32816Pyry HaulosDEFINE_DERIVED_FLOAT3(Mix, mix, x, y, a, alternatives((x * (constant(1.0f) - a)) + y * a, 33086c1b3db5fb439806b9b67442f1042615ffa32816Pyry Haulos x + (y - x) * a)); 33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic double step (double edge, double x) 33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return x < edge ? 0.0 : 1.0; 33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Step : public PreciseFunc2 { public: Step (void) : PreciseFunc2("step", step) {} }; 33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SmoothStep : public DerivedFunc<Signature<float, float, float, float> > 33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "smoothstep"; 33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3327653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<Ret> doExpand (ExpandContext& ctx, const ArgExprs& args) const 33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& edge0 = args.a; 33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& edge1 = args.b; 33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& x = args.c; 33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float> tExpr = clamp((x - edge0) / (edge1 - edge0), 33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry constant(0.0f), constant(1.0f)); 33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float> t = bindExpression("t", ctx, tExpr); 33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (t * t * (constant(3.0f) - constant(2.0f) * t)); 33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FrExp : public PrimitiveFunc<Signature<float, float, int> > 33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "frexp"; 33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg0& x = iargs.a; 33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IArg1& exponent = const_cast<IArg1&>(iargs.b); 33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (x.hasNaN() || x.contains(TCU_INFINITY) || x.contains(-TCU_INFINITY)) 33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // GLSL (in contrast to IEEE) says that result of applying frexp 33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // to infinity is undefined 33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = Interval::unbounded() | TCU_NAN; 33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry exponent = Interval(-deLdExp(1.0, 31), deLdExp(1.0, 31)-1); 33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (!x.empty()) 33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int loExp = 0; 33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double loFrac = deFrExp(x.lo(), &loExp); 33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int hiExp = 0; 33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double hiFrac = deFrExp(x.hi(), &hiExp); 33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deSign(loFrac) != deSign(hiFrac)) 33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry exponent = Interval(-TCU_INFINITY, de::max(loExp, hiExp)); 33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = Interval(); 33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deSign(loFrac) < 0) 33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= Interval(-1.0 + DBL_EPSILON*0.5, 0.0); 33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deSign(hiFrac) > 0) 33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= Interval(0.0, 1.0 - DBL_EPSILON*0.5); 33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry exponent = Interval(loExp, hiExp); 33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (loExp == hiExp) 33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = Interval(loFrac, hiFrac); 33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = deSign(loFrac) * Interval(0.5, 1.0 - DBL_EPSILON*0.5); 33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getOutParamIndex (void) const 33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LdExp : public PrimitiveFunc<Signature<float, float, int> > 33983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 33993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 34003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "ldexp"; 34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval doApply (const EvalContext& ctx, const IArgs& iargs) const 34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval ret = call<Exp2>(ctx, iargs.b); 34093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Khronos bug 11180 consensus: if exp2(exponent) cannot be represented, 34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // the result is undefined. 34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ret.contains(TCU_INFINITY) | ret.contains(-TCU_INFINITY)) 34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret |= TCU_NAN; 34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return call<Mul>(ctx, iargs.a, ret); 34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Columns> 34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Transpose : public PrimitiveFunc<Signature<Matrix<float, Rows, Columns>, 34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Columns, Rows> > > 34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 34243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Transpose::IRet IRet; 34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Transpose::IArgs IArgs; 34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "transpose"; 34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext&, const IArgs& iargs) const 34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int rowNdx = 0; rowNdx < Rows; ++rowNdx) 34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int colNdx = 0; colNdx < Columns; ++colNdx) 34403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret(rowNdx, colNdx) = iargs.a(colNdx, rowNdx); 34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 34463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Ret, typename Arg0, typename Arg1> 34483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MulFunc : public PrimitiveFunc<Signature<Ret, Arg0, Arg1> > 34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 34503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 3451653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos string getName (void) const { return "mul"; } 34523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 34553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "(" << *args[0] << " * " << *args[1] << ")"; 34573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 34593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int LeftRows, int Middle, int RightCols> 34613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MatMul : public MulFunc<Matrix<float, LeftRows, RightCols>, 34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, LeftRows, Middle>, 34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Middle, RightCols> > 34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 34663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatMul::IRet IRet; 34673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatMul::IArgs IArgs; 34683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatMul::IArg0 IArg0; 34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatMul::IArg1 IArg1; 34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, const IArgs& iargs) const 34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg0& left = iargs.a; 34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg1& right = iargs.b; 34753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < LeftRows; ++row) 34783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < RightCols; ++col) 34803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval element (0.0); 34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < Middle; ++ndx) 34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry element = call<Add>(ctx, element, 34853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry call<Mul>(ctx, left[ndx][row], right[col][ndx])); 34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[col][row] = element; 34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VecMatMul : public MulFunc<Vector<float, Cols>, 34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vector<float, Rows>, 34983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Rows, Cols> > 34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename VecMatMul::IRet IRet; 35023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename VecMatMul::IArgs IArgs; 35033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename VecMatMul::IArg0 IArg0; 35043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename VecMatMul::IArg1 IArg1; 35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, const IArgs& iargs) const 35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg0& left = iargs.a; 35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg1& right = iargs.b; 35113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < Cols; ++col) 35143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Interval element (0.0); 35163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < Rows; ++row) 35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry element = call<Add>(ctx, element, call<Mul>(ctx, left[row], right[col][row])); 35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[col] = element; 35213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 35243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 35283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MatVecMul : public MulFunc<Vector<float, Rows>, 35293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Matrix<float, Rows, Cols>, 35303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vector<float, Cols> > 35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatVecMul::IRet IRet; 35343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatVecMul::IArgs IArgs; 35353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatVecMul::IArg0 IArg0; 35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename MatVecMul::IArg1 IArg1; 35373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 35393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, const IArgs& iargs) const 35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg0& left = iargs.a; 35423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArg1& right = iargs.b; 35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return call<VecMatMul<Cols, Rows> >(ctx, right, 35453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry call<Transpose<Rows, Cols> >(ctx, left)); 35463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 35483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OuterProduct : public PrimitiveFunc<Signature<Matrix<float, Rows, Cols>, 35513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vector<float, Rows>, 35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vector<float, Cols> > > 35533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename OuterProduct::IRet IRet; 35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename OuterProduct::IArgs IArgs; 35573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "outerProduct"; 35613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, const IArgs& iargs) const 35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 35673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int row = 0; row < Rows; ++row) 35693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < Cols; ++col) 35713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[col][row] = call<Mul>(ctx, iargs.a[row], iargs.b[col]); 35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 35793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, Rows, Cols> > outerProduct (const ExprP<Vector<float, Rows> >& left, 35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<float, Cols> >& right) 35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<OuterProduct<Rows, Cols> >(left, right); 35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 35843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 35863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DeterminantBase : public DerivedFunc<Signature<float, Matrix<float, Size, Size> > > 35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "determinant"; } 35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 35913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 35933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Determinant; 35943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 35963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> determinant (ExprP<Matrix<float, Size, Size> > mat) 35973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Determinant<Size> >(mat); 35993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 36003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 36023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Determinant<2> : public DeterminantBase<2> 36033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 36053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> doExpand (ExpandContext&, const ArgExprs& args) const 36063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> mat = args.a; 36083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1]; 36103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 36123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 36143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Determinant<3> : public DeterminantBase<3> 36153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 36173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> doExpand (ExpandContext&, const ArgExprs& args) const 36183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat3> mat = args.a; 36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (mat[0][0] * (mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]) + 36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat[0][1] * (mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2]) + 36233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat[0][2] * (mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0])); 36243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 36263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 36283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Determinant<4> : public DeterminantBase<4> 36293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 36313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> doExpand (ExpandContext& ctx, const ArgExprs& args) const 36323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat4> mat = args.a; 36343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat3> minors[4]; 36353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < 4; ++ndx) 36373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec4> minorColumns[3]; 36393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec3> columns[3]; 36403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < 3; ++col) 36423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minorColumns[col] = mat[col < ndx ? col : col + 1]; 36433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < 3; ++col) 36453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry columns[col] = vec3(minorColumns[0][col+1], 36463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minorColumns[1][col+1], 36473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minorColumns[2][col+1]); 36483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minors[ndx] = bindExpression("minor", ctx, 36503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat3(columns[0], columns[1], columns[2])); 36513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (mat[0][0] * determinant(minors[0]) - 36543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat[1][0] * determinant(minors[1]) + 36553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat[2][0] * determinant(minors[2]) - 36563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat[3][0] * determinant(minors[3])); 36573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 36593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> class Inverse; 36613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 36633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, Size, Size> > inverse (ExprP<Matrix<float, Size, Size> > mat) 36643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Inverse<Size> >(mat); 36663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 36673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Inverse<2> : public DerivedFunc<Signature<Mat2, Mat2> > 36703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 36733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "inverse"; 36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> doExpand (ExpandContext& ctx, const ArgExprs& args) const 36793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> mat = args.a; 36813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<float> det = bindExpression("det", ctx, determinant(mat)); 36823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return mat2(vec2(mat[1][1] / det, -mat[0][1] / det), 36843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec2(-mat[1][0] / det, mat[0][0] / det)); 36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 36893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Inverse<3> : public DerivedFunc<Signature<Mat3, Mat3> > 36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 36923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "inverse"; 36953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 3698653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<Ret> doExpand (ExpandContext& ctx, const ArgExprs& args) const 36993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat3> mat = args.a; 37013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> invA = bindExpression("invA", ctx, 37023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inverse(mat2(vec2(mat[0][0], mat[0][1]), 37033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec2(mat[1][0], mat[1][1])))); 37043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec2> matB = bindExpression("matB", ctx, vec2(mat[2][0], mat[2][1])); 37063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec2> matC = bindExpression("matC", ctx, vec2(mat[0][2], mat[1][2])); 37073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<float> matD = bindExpression("matD", ctx, mat[2][2]); 37083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<float> schur = bindExpression("schur", ctx, 37103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry constant(1.0f) / 37113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (matD - dot(matC * invA, matB))); 37123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec2> t1 = invA * matB; 37143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec2> t2 = t1 * schur; 37153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> t3 = outerProduct(t2, matC); 37163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> t4 = t3 * invA; 37173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> t5 = invA + t4; 37183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> blockA = bindExpression("blockA", ctx, t5); 37193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec2> blockB = bindExpression("blockB", ctx, 37203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (invA * matB) * -schur); 37213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Vec2> blockC = bindExpression("blockC", ctx, 37223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (matC * invA) * -schur); 37233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return mat3(vec3(blockA[0][0], blockA[0][1], blockC[0]), 37253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec3(blockA[1][0], blockA[1][1], blockC[1]), 37263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec3(blockB[0], blockB[1], schur)); 37273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 37293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> 37313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Inverse<4> : public DerivedFunc<Signature<Mat4, Mat4> > 37323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 37333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 37343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const { return "inverse"; } 37353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 3737653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<Ret> doExpand (ExpandContext& ctx, 37383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ArgExprs& args) const 37393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat4> mat = args.a; 37413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> invA = bindExpression("invA", ctx, 37423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inverse(mat2(vec2(mat[0][0], mat[0][1]), 37433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec2(mat[1][0], mat[1][1])))); 37443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> matB = bindExpression("matB", ctx, 37453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat2(vec2(mat[2][0], mat[2][1]), 37463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec2(mat[3][0], mat[3][1]))); 37473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> matC = bindExpression("matC", ctx, 37483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat2(vec2(mat[0][2], mat[0][3]), 37493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec2(mat[1][2], mat[1][3]))); 37503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> matD = bindExpression("matD", ctx, 37513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat2(vec2(mat[2][2], mat[2][3]), 37523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec2(mat[3][2], mat[3][3]))); 37533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> schur = bindExpression("schur", ctx, 37543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inverse(matD + -(matC * invA * matB))); 37553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> blockA = bindExpression("blockA", ctx, 37563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invA + (invA * matB * schur * matC * invA)); 37573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> blockB = bindExpression("blockB", ctx, 37583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (-invA) * matB * schur); 37593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Mat2> blockC = bindExpression("blockC", ctx, 37603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (-schur) * matC * invA); 37613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return mat4(vec4(blockA[0][0], blockA[0][1], blockC[0][0], blockC[0][1]), 37633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec4(blockA[1][0], blockA[1][1], blockC[1][0], blockC[1][1]), 37643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec4(blockB[0][0], blockB[0][1], schur[0][0], schur[0][1]), 37653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vec4(blockB[1][0], blockB[1][1], schur[1][0], schur[1][1])); 37663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 37683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Fma : public DerivedFunc<Signature<float, float, float, float> > 37703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 37713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 37723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 37733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "fma"; 37753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getRequiredExtension (void) const 37783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return "GL_EXT_gpu_shader5"; 37803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 3783653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos ExprP<float> doExpand (ExpandContext&, const ArgExprs& x) const 37843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return x.a * x.b + x.c; 37863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 37883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functions 37903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace Functions; 37923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 37943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<typename T::Element> ContainerExprPBase<T>::operator[] (int i) const 37953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 37963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Functions::getComponent(exprP<T>(*this), i); 37973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 37983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator+ (const ExprP<float>& arg0, const ExprP<float>& arg1) 38003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Add>(arg0, arg1); 38023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 38033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator- (const ExprP<float>& arg0, const ExprP<float>& arg1) 38053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Sub>(arg0, arg1); 38073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 38083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator- (const ExprP<float>& arg0) 38103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Negate>(arg0); 38123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 38133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator* (const ExprP<float>& arg0, const ExprP<float>& arg1) 38153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Mul>(arg0, arg1); 38173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 38183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<float> operator/ (const ExprP<float>& arg0, const ExprP<float>& arg1) 38203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<Div>(arg0, arg1); 38223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 38233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig_, int Size> 38253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenFunc : public PrimitiveFunc<Signature< 38263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Ret, Size>::Container, 38273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Arg0, Size>::Container, 38283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Arg1, Size>::Container, 38293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Arg2, Size>::Container, 38303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Arg3, Size>::Container> > 38313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 38333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenFunc::IArgs IArgs; 38343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename GenFunc::IRet IRet; 38353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GenFunc (const Func<Sig_>& scalarFunc) : m_func (scalarFunc) {} 38373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 38393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_func.getName(); 38413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getOutParamIndex (void) const 38443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_func.getOutParamIndex(); 38463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getRequiredExtension (void) const 38493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_func.getRequiredExtension(); 38513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 38543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 38553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_func.print(os, args); 38573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, const IArgs& iargs) const 38603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 38623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < Size; ++ndx) 38643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[ndx] = 38663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_func.apply(ctx, iargs.a[ndx], iargs.b[ndx], iargs.c[ndx], iargs.d[ndx]); 38673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 38703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doGetUsedFuncs (FuncSet& dst) const 38733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_func.getUsedFuncs(dst); 38753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Func<Sig_>& m_func; 38783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 38793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F, int Size> 38813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VectorizedFunc : public GenFunc<typename F::Sig, Size> 38823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 38843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VectorizedFunc (void) : GenFunc<typename F::Sig, Size>(instance<F>()) {} 38853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 38863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig_, int Size> 38903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FixedGenFunc : public PrimitiveFunc <Signature< 38913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Ret, Size>::Container, 38923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Arg0, Size>::Container, 38933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename Sig_::Arg1, 38943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Arg2, Size>::Container, 38953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ContainerOf<typename Sig_::Arg3, Size>::Container> > 38963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 38983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename FixedGenFunc::IArgs IArgs; 38993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename FixedGenFunc::IRet IRet; 39003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 39023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 39033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return this->doGetScalarFunc().getName(); 39043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 39053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 39073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void doPrint (ostream& os, const BaseArgExprs& args) const 39083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 39093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->doGetScalarFunc().print(os, args); 39103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 39113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet doApply (const EvalContext& ctx, 39133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IArgs& iargs) const 39143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 39153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IRet ret; 39163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Func<Sig_>& func = this->doGetScalarFunc(); 39173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < Size; ++ndx) 39193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret[ndx] = func.apply(ctx, iargs.a[ndx], iargs.b, iargs.c[ndx], iargs.d[ndx]); 39203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 39223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 39233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual const Func<Sig_>& doGetScalarFunc (void) const = 0; 39253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 39263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F, int Size> 39283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FixedVecFunc : public FixedGenFunc<typename F::Sig, Size> 39293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 39313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Func<typename F::Sig>& doGetScalarFunc (void) const { return instance<F>(); } 39323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 39333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Sig> 39353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct GenFuncs 39363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GenFuncs (const Func<Sig>& func_, 39383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenFunc<Sig, 2>& func2_, 39393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenFunc<Sig, 3>& func3_, 39403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenFunc<Sig, 4>& func4_) 39413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : func (func_) 39423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , func2 (func2_) 39433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , func3 (func3_) 39443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , func4 (func4_) 39453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry {} 39463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Func<Sig>& func; 39483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenFunc<Sig, 2>& func2; 39493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenFunc<Sig, 3>& func3; 39503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenFunc<Sig, 4>& func4; 39513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 39523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename F> 39543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGenFuncs<typename F::Sig> makeVectorizedFuncs (void) 39553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return GenFuncs<typename F::Sig>(instance<F>(), 39573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<VectorizedFunc<F, 2> >(), 39583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<VectorizedFunc<F, 3> >(), 39593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<VectorizedFunc<F, 4> >()); 39603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 39633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator*(const ExprP<Vector<float, Size> >& arg0, 39643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<float, Size> >& arg1) 39653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<VectorizedFunc<Mul, Size> >(arg0, arg1); 39673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 39703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator*(const ExprP<Vector<float, Size> >& arg0, 39713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& arg1) 39723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<FixedVecFunc<Mul, Size> >(arg0, arg1); 39743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 39773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator/(const ExprP<Vector<float, Size> >& arg0, 39783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& arg1) 39793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<FixedVecFunc<Div, Size> >(arg0, arg1); 39813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 39843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator-(const ExprP<Vector<float, Size> >& arg0) 39853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<VectorizedFunc<Negate, Size> >(arg0); 39873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Size> 39903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Size> > operator-(const ExprP<Vector<float, Size> >& arg0, 39913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<float, Size> >& arg1) 39923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<VectorizedFunc<Sub, Size> >(arg0, arg1); 39943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int LeftRows, int Middle, int RightCols> 39973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, LeftRows, RightCols> > 39983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryoperator* (const ExprP<Matrix<float, LeftRows, Middle> >& left, 39993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Matrix<float, Middle, RightCols> >& right) 40003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<MatMul<LeftRows, Middle, RightCols> >(left, right); 40023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 40033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 40053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Rows> > operator* (const ExprP<Vector<float, Cols> >& left, 40063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Matrix<float, Rows, Cols> >& right) 40073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<VecMatMul<Rows, Cols> >(left, right); 40093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 40103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 40123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Vector<float, Cols> > operator* (const ExprP<Matrix<float, Rows, Cols> >& left, 40133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Vector<float, Rows> >& right) 40143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<MatVecMul<Rows, Cols> >(left, right); 40163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 40173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 40193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, Rows, Cols> > operator* (const ExprP<Matrix<float, Rows, Cols> >& left, 40203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<float>& right) 40213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<ScalarMatFunc<Mul, Rows, Cols> >(left, right); 40233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 40243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 40263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, Rows, Cols> > operator+ (const ExprP<Matrix<float, Rows, Cols> >& left, 40273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ExprP<Matrix<float, Rows, Cols> >& right) 40283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<CompMatFunc<Add, Rows, Cols> >(left, right); 40303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 40313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int Rows, int Cols> 40333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExprP<Matrix<float, Rows, Cols> > operator- (const ExprP<Matrix<float, Rows, Cols> >& mat) 40343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return app<MatNeg<Rows, Cols> >(mat); 40363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 40373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 40393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Sampling 40403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 40428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry virtual void genFixeds (const FloatFormat&, vector<T>&) const {} 40438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry virtual T genRandom (const FloatFormat&, Precision, Random&) const { return T(); } 40448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry virtual double getWeight (void) const { return 0.0; } 40453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 40463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 40483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultSampling<Void> : public Sampling<Void> 40493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 40513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void genFixeds (const FloatFormat&, vector<Void>& dst) const { dst.push_back(Void()); } 40523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 40533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 40553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultSampling<bool> : public Sampling<bool> 40563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 40583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void genFixeds (const FloatFormat&, vector<bool>& dst) const 40593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(true); 40613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(false); 40623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 40643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 40663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultSampling<int> : public Sampling<int> 40673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 40683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 40698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry int genRandom (const FloatFormat&, Precision prec, Random& rnd) const 40703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int exp = rnd.getInt(0, getNumBits(prec)-2); 40723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int sign = rnd.getBool() ? -1 : 1; 40733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4074c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry return sign * rnd.getInt(0, (deInt32)1 << exp); 40753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void genFixeds (const FloatFormat&, vector<int>& dst) const 40783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(0); 40803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(-1); 40813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(1); 40823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double getWeight (void) const { return 1.0; } 40848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 40858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprivate: 40868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry static inline int getNumBits (Precision prec) 40878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 40888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry switch (prec) 40898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 40908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry case glu::PRECISION_LOWP: return 8; 40918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry case glu::PRECISION_MEDIUMP: return 16; 40928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry case glu::PRECISION_HIGHP: return 32; 40938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry default: 40948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_ASSERT(false); 40958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return 0; 40968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 40978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 40983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 40993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 41013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultSampling<float> : public Sampling<float> 41023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 41033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 41048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry float genRandom (const FloatFormat& format, Precision prec, Random& rnd) const; 41053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void genFixeds (const FloatFormat& format, vector<float>& dst) const; 41063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double getWeight (void) const { return 1.0; } 41073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 41083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Generate a random float from a reasonable general-purpose distribution. 41103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat DefaultSampling<float>::genRandom (const FloatFormat& format, 41118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Precision, 41123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Random& rnd) const 41133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 41143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int minExp = format.getMinExp(); 41153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxExp = format.getMaxExp(); 41163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool haveSubnormal = format.hasSubnormal() != tcu::NO; 41173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Choose exponent so that the cumulative distribution is cubic. 41193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // This makes the probability distribution quadratic, with the peak centered on zero. 41203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double minRoot = deCbrt(minExp - 0.5 - (haveSubnormal ? 1.0 : 0.0)); 41213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double maxRoot = deCbrt(maxExp + 0.5); 41223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int fractionBits = format.getFractionBits(); 41233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int exp = int(deRoundEven(dePow(rnd.getDouble(minRoot, maxRoot), 41243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3.0))); 41253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float base = 0.0f; // integral power of two 41263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float quantum = 0.0f; // smallest representable difference in the binade 41273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float significand = 0.0f; // Significand. 41283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(fractionBits < std::numeric_limits<float>::digits); 41303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Generate some occasional special numbers 41323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (rnd.getInt(0, 64)) 41333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4134653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos case 0: return 0; 41353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: return TCU_INFINITY; 41363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 2: return -TCU_INFINITY; 41373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 3: return TCU_NAN; 41383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: break; 41393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (exp >= minExp) 41423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 41433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Normal number 41443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry base = deFloatLdExp(1.0f, exp); 41453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry quantum = deFloatLdExp(1.0f, exp - fractionBits); 41463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 41483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 41493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Subnormal 41503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry base = 0.0f; 41513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry quantum = deFloatLdExp(1.0f, minExp - fractionBits); 41523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (rnd.getInt(0, 16)) 41553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 41563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 0: // The highest number in this binade, significand is all bits one. 41573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry significand = base - quantum; 41583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 41593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: // Significand is one. 41603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry significand = quantum; 41613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 41623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 2: // Significand is zero. 41633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry significand = 0.0; 41643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 41653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: // Random (evenly distributed) significand. 41663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 41673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint64 intFraction = rnd.getUint64() & ((1 << fractionBits) - 1); 41683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry significand = float(intFraction) * quantum; 41693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Produce positive numbers more often than negative. 41733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (rnd.getInt(0,3) == 0 ? -1.0f : 1.0f) * (base + significand); 41743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 41753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Generate a standard set of floats that should always be tested. 41773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DefaultSampling<float>::genFixeds (const FloatFormat& format, vector<float>& dst) const 41783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 41793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int minExp = format.getMinExp(); 41803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxExp = format.getMaxExp(); 41813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int fractionBits = format.getFractionBits(); 41823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float minQuantum = deFloatLdExp(1.0f, minExp - fractionBits); 41833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float minNormalized = deFloatLdExp(1.0f, minExp); 41843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float maxQuantum = deFloatLdExp(1.0f, maxExp - fractionBits); 41853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // NaN 41873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(TCU_NAN); 41883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Zero 41893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(0.0f); 41903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int sign = -1; sign <= 1; sign += 2) 41923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 41933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Smallest subnormal 4194c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * minQuantum); 41953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Largest subnormal 4197c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * (minNormalized - minQuantum)); 41983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Smallest normalized 4200c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * minNormalized); 42013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Next smallest normalized 4203c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * (minNormalized + minQuantum)); 42043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4205c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * 0.5f); 4206c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * 1.0f); 4207c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * 2.0f); 42083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Largest number 4210c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * (deFloatLdExp(1.0f, maxExp) + 4211c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry (deFloatLdExp(1.0f, maxExp) - maxQuantum))); 42123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4213c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry dst.push_back((float)sign * TCU_INFINITY); 42143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 42163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> 42183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultSampling<Vector<T, Size> > : public Sampling<Vector<T, Size> > 42193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 42203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 42213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Vector<T, Size> Value; 42223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Value genRandom (const FloatFormat& fmt, Precision prec, Random& rnd) const 42243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Value ret; 42263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < Size; ++ndx) 42288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ret[ndx] = instance<DefaultSampling<T> >().genRandom(fmt, prec, rnd); 42293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 42313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void genFixeds (const FloatFormat& fmt, vector<Value>& dst) const 42343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<T> scalars; 42363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<DefaultSampling<T> >().genFixeds(fmt, scalars); 42383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t scalarNdx = 0; scalarNdx < scalars.size(); ++scalarNdx) 42403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(Value(scalars[scalarNdx])); 42413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double getWeight (void) const 42443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return dePow(instance<DefaultSampling<T> >().getWeight(), Size); 42463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 42483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Columns> 42503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DefaultSampling<Matrix<T, Rows, Columns> > : public Sampling<Matrix<T, Rows, Columns> > 42513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 42523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 42533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Matrix<T, Rows, Columns> Value; 42543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Value genRandom (const FloatFormat& fmt, Precision prec, Random& rnd) const 42563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Value ret; 42583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int rowNdx = 0; rowNdx < Rows; ++rowNdx) 42603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int colNdx = 0; colNdx < Columns; ++colNdx) 42618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ret(rowNdx, colNdx) = instance<DefaultSampling<T> >().genRandom(fmt, prec, rnd); 42623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 42643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void genFixeds (const FloatFormat& fmt, vector<Value>& dst) const 42673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<T> scalars; 42693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<DefaultSampling<T> >().genFixeds(fmt, scalars); 42713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t scalarNdx = 0; scalarNdx < scalars.size(); ++scalarNdx) 42733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(Value(scalars[scalarNdx])); 42743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (Columns == Rows) 42763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Value mat (0.0); 42783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T x = T(1.0f); 42793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat[0][0] = x; 42803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < Columns; ++ndx) 42813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mat[Columns-1-ndx][ndx] = x; 42833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry x *= T(2.0f); 42843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(mat); 42863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry double getWeight (void) const 42903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return dePow(instance<DefaultSampling<T> >().getWeight(), Rows * Columns); 42923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 42943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Context 42963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 42973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Context (const string& name_, 42983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestContext& testContext_, 42993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RenderContext& renderContext_, 43003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& floatFormat_, 43013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& highpFormat_, 43023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Precision precision_, 43033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderType shaderType_, 43043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t numRandoms_) 43053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : name (name_) 43063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , testContext (testContext_) 43073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , renderContext (renderContext_) 43083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , floatFormat (floatFormat_) 43093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , highpFormat (highpFormat_) 43103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , precision (precision_) 43113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , shaderType (shaderType_) 43123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , numRandoms (numRandoms_) {} 43133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string name; 43153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestContext& testContext; 43163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RenderContext& renderContext; 43173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FloatFormat floatFormat; 43183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FloatFormat highpFormat; 43193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Precision precision; 43203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderType shaderType; 43213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t numRandoms; 43223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 43233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename In0_ = Void, typename In1_ = Void, typename In2_ = Void, typename In3_ = Void> 43253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct InTypes 43263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef In0_ In0; 43283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef In1_ In1; 43293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef In2_ In2; 43303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef In3_ In3; 43313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 43323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename In> 43343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint numInputs (void) 43353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (!isTypeValid<typename In::In0>() ? 0 : 43373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !isTypeValid<typename In::In1>() ? 1 : 43383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !isTypeValid<typename In::In2>() ? 2 : 43393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !isTypeValid<typename In::In3>() ? 3 : 43403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4); 43413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 43423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Out0_, typename Out1_ = Void> 43443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct OutTypes 43453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Out0_ Out0; 43473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Out1_ Out1; 43483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 43493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Out> 43513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint numOutputs (void) 43523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (!isTypeValid<typename Out::Out0>() ? 0 : 43543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !isTypeValid<typename Out::Out1>() ? 1 : 43553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2); 43563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 43573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename In> 43593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Inputs 43603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<typename In::In0> in0; 43623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<typename In::In1> in1; 43633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<typename In::In2> in2; 43643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<typename In::In3> in3; 43653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 43663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Out> 43683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Outputs 43693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Outputs (size_t size) : out0(size), out1(size) {} 43713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<typename Out::Out0> out0; 43733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<typename Out::Out1> out1; 43743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 43753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename In, typename Out> 43773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Variables 43783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<typename In::In0> in0; 43803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<typename In::In1> in1; 43813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<typename In::In2> in2; 43823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<typename In::In3> in3; 43833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<typename Out::Out0> out0; 43843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableP<typename Out::Out1> out1; 43853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 43863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename In> 43883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Samplings 43893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 43903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Samplings (const Sampling<typename In::In0>& in0_, 43913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Sampling<typename In::In1>& in1_, 43923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Sampling<typename In::In2>& in2_, 43933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Sampling<typename In::In3>& in3_) 43943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : in0 (in0_), in1 (in1_), in2 (in2_), in3 (in3_) {} 43953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Sampling<typename In::In0>& in0; 43973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Sampling<typename In::In1>& in1; 43983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Sampling<typename In::In2>& in2; 43993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Sampling<typename In::In3>& in3; 44003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 44013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename In> 44033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DefaultSamplings : Samplings<In> 44043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 44053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DefaultSamplings (void) 44063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : Samplings<In>(instance<DefaultSampling<typename In::In0> >(), 44073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<DefaultSampling<typename In::In1> >(), 44083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<DefaultSampling<typename In::In2> >(), 44093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instance<DefaultSampling<typename In::In3> >()) {} 44103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 44113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PrecisionCase : public TestCase 44133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 44143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 44153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 44163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 44183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PrecisionCase (const Context& context, 44198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const string& name, 44208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const string& extension = "") 44218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry : TestCase (context.testContext, 44228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry name.c_str(), 44238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry name.c_str()) 44248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry , m_ctx (context) 44258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry , m_status () 44268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry , m_rnd (0xdeadbeefu + 44278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry context.testContext.getCommandLine().getBaseSeed()) 44288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry , m_extension (extension) 44293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 44303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 44313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4432653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos RenderContext& getRenderContext(void) const { return m_ctx.renderContext; } 44333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4434653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos const FloatFormat& getFormat (void) const { return m_ctx.floatFormat; } 44353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4436653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos TestLog& log (void) const { return m_testCtx.getLog(); } 44373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void runTest (void) = 0; 44393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template <typename In, typename Out> 44413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void testStatement (const Variables<In, Out>& variables, 44423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Inputs<In>& inputs, 44433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Statement& stmt); 44443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename T> 44463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Symbol makeSymbol (const Variable<T>& variable) 44473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 44483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Symbol(variable.getName(), getVarTypeOf<T>(m_ctx.precision)); 44493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 44503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Context m_ctx; 44523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ResultCollector m_status; 44533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Random m_rnd; 44548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const string m_extension; 44553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 44563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult PrecisionCase::iterate (void) 44583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 44593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry runTest(); 44603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_status.setTestContextResult(m_testCtx); 44613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 44623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 44633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename In, typename Out> 44653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PrecisionCase::testStatement (const Variables<In, Out>& variables, 44663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Inputs<In>& inputs, 44673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Statement& stmt) 44683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 44693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using namespace ShaderExecUtil; 44703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4471653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef typename In::In0 In0; 4472653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef typename In::In1 In1; 4473653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef typename In::In2 In2; 4474653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef typename In::In3 In3; 4475653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef typename Out::Out0 Out0; 4476653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos typedef typename Out::Out1 Out1; 44773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& fmt = getFormat(); 44793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int inCount = numInputs<In>(); 44803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int outCount = numOutputs<Out>(); 44813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const size_t numValues = (inCount > 0) ? inputs.in0.size() : 1; 44823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Outputs<Out> outputs (numValues); 44833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderSpec spec; 44843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat highpFmt = m_ctx.highpFormat; 44853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxMsgs = 100; 44863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numErrors = 0; 4487653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos Environment env; // Hoisted out of the inner loop for optimization. 44883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (inCount) 44903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 44913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 4: DE_ASSERT(inputs.in3.size() == numValues); 44923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 3: DE_ASSERT(inputs.in2.size() == numValues); 44933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 2: DE_ASSERT(inputs.in1.size() == numValues); 44943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: DE_ASSERT(inputs.in0.size() == numValues); 44953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: break; 44963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 44973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Print out the statement and its definitions 44993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log() << TestLog::Message << "Statement: " << stmt << TestLog::EndMessage; 45003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream oss; 45023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FuncSet funcs; 45033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stmt.getUsedFuncs(funcs); 45053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (FuncSet::const_iterator it = funcs.begin(); it != funcs.end(); ++it) 45063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (*it)->printDefinition(oss); 45083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!funcs.empty()) 45103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log() << TestLog::Message << "Reference definitions:\n" << oss.str() 45113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 45123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize ShaderSpec from precision, variables and statement. 45153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream os; 45173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os << "precision " << glu::getPrecisionName(m_ctx.precision) << " float;\n"; 45183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry spec.globalDeclarations = os.str(); 45193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry spec.version = getContextTypeGLSLVersion(getRenderContext().getType()); 45228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 45238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!m_extension.empty()) 45248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry spec.globalDeclarations = "#extension " + m_extension + " : require\n"; 45258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 45263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry spec.inputs.resize(inCount); 45273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (inCount) 45293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 4: spec.inputs[3] = makeSymbol(*variables.in3); 45313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 3: spec.inputs[2] = makeSymbol(*variables.in2); 45323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 2: spec.inputs[1] = makeSymbol(*variables.in1); 45333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: spec.inputs[0] = makeSymbol(*variables.in0); 45343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: break; 45353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry spec.outputs.resize(outCount); 45383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (outCount) 45403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 2: spec.outputs[1] = makeSymbol(*variables.out1); 45423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: spec.outputs[0] = makeSymbol(*variables.out0); 45433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: break; 45443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry spec.source = de::toString(stmt); 45473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Run the shader with inputs. 45493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry UniquePtr<ShaderExecutor> executor (createExecutor(getRenderContext(), 45513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ctx.shaderType, 45523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry spec)); 45533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* inputArr[] = 45543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry &inputs.in0.front(), &inputs.in1.front(), &inputs.in2.front(), &inputs.in3.front(), 45563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 45573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* outputArr[] = 45583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry &outputs.out0.front(), &outputs.out1.front(), 45603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 45613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry executor->log(log()); 45633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!executor->isOk()) 45643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Shader compilation failed"); 45653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry executor->useProgram(); 45673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry executor->execute(int(numValues), inputArr, outputArr); 45683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize environment with dummy values so we don't need to bind in inner loop. 45713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<In0>::IVal in0; 45733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<In1>::IVal in1; 45743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<In2>::IVal in2; 45753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<In3>::IVal in3; 45763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<Out0>::IVal reference0; 45773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename Traits<Out1>::IVal reference1; 45783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.bind(*variables.in0, in0); 45803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.bind(*variables.in1, in1); 45813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.bind(*variables.in2, in2); 45823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.bind(*variables.in3, in3); 45833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.bind(*variables.out0, reference0); 45843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.bind(*variables.out1, reference1); 45853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // For each input tuple, compute output reference interval and compare 45883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // shader output to the reference. 45893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t valueNdx = 0; valueNdx < numValues; valueNdx++) 45903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool result = true; 45923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename Traits<Out0>::IVal reference0; 45933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename Traits<Out1>::IVal reference1; 45943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45959274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos if (valueNdx % (size_t)TOUCH_WATCHDOG_VALUE_FREQUENCY == 0) 45969274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos m_testCtx.touchWatchdog(); 45979274773cc74d8b63d0ea91bb7392d5e501302511Pyry Haulos 45983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.lookup(*variables.in0) = convert<In0>(fmt, round(fmt, inputs.in0[valueNdx])); 45993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.lookup(*variables.in1) = convert<In1>(fmt, round(fmt, inputs.in1[valueNdx])); 46003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.lookup(*variables.in2) = convert<In2>(fmt, round(fmt, inputs.in2[valueNdx])); 46013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry env.lookup(*variables.in3) = convert<In3>(fmt, round(fmt, inputs.in3[valueNdx])); 46023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry EvalContext ctx (fmt, m_ctx.precision, env); 46053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stmt.execute(ctx); 46063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (outCount) 46093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 2: 46113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reference1 = convert<Out1>(highpFmt, env.lookup(*variables.out1)); 46123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_status.check(contains(reference1, outputs.out1[valueNdx]), 46133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Shader output 1 is outside acceptable range")) 46143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result = false; 46153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: 46163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reference0 = convert<Out0>(highpFmt, env.lookup(*variables.out0)); 46173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_status.check(contains(reference0, outputs.out0[valueNdx]), 46183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Shader output 0 is outside acceptable range")) 46193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result = false; 46203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: break; 46213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!result) 46243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++numErrors; 46253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((!result && numErrors <= maxMsgs) || GLS_LOG_ALL_RESULTS) 46273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MessageBuilder builder = log().message(); 46293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << (result ? "Passed" : "Failed") << " sample:\n"; 46313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inCount > 0) 46333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "\t" << variables.in0->getName() << " = " 46353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << valueToString(highpFmt, inputs.in0[valueNdx]) << "\n"; 46363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inCount > 1) 46393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "\t" << variables.in1->getName() << " = " 46413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << valueToString(highpFmt, inputs.in1[valueNdx]) << "\n"; 46423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inCount > 2) 46453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "\t" << variables.in2->getName() << " = " 46473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << valueToString(highpFmt, inputs.in2[valueNdx]) << "\n"; 46483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inCount > 3) 46513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "\t" << variables.in3->getName() << " = " 46533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << valueToString(highpFmt, inputs.in3[valueNdx]) << "\n"; 46543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outCount > 0) 46573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "\t" << variables.out0->getName() << " = " 46593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << valueToString(highpFmt, outputs.out0[valueNdx]) << "\n" 46603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tExpected range: " 46613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << intervalToString<typename Out::Out0>(highpFmt, reference0) << "\n"; 46623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outCount > 1) 46653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "\t" << variables.out1->getName() << " = " 46673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << valueToString(highpFmt, outputs.out1[valueNdx]) << "\n" 46683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tExpected range: " 46693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << intervalToString<typename Out::Out1>(highpFmt, reference1) << "\n"; 46703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << TestLog::EndMessage; 46733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrors > maxMsgs) 46773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log() << TestLog::Message << "(Skipped " << (numErrors - maxMsgs) << " messages.)" 46793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 46803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrors == 0) 46833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log() << TestLog::Message << "All " << numValues << " inputs passed." 46853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 46863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 46883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log() << TestLog::Message << numErrors << "/" << numValues << " inputs failed." 46903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 46913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 46933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 46973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct InputLess 46983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 46993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const T& val1, const T& val2) const 47003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return val1 < val2; 47023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 47043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 47063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool inputLess (const T& val1, const T& val2) 47073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 47083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return InputLess<T>()(val1, val2); 47093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 47103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> 47123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct InputLess<float> 47133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 47143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const float& val1, const float& val2) const 47153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deIsNaN(val1)) 47173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deIsNaN(val2)) 47193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return val1 < val2; 47213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 47233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size> 47253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct InputLess<Vector<T, Size> > 47263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 47273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const Vector<T, Size>& vec1, const Vector<T, Size>& vec2) const 47283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < Size; ++ndx) 47303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(vec1[ndx], vec2[ndx])) 47323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(vec2[ndx], vec1[ndx])) 47343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 47403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols> 47423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct InputLess<Matrix<T, Rows, Cols> > 47433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 47443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const Matrix<T, Rows, Cols>& mat1, 47453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Matrix<T, Rows, Cols>& mat2) const 47463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int col = 0; col < Cols; ++col) 47483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(mat1[col], mat2[col])) 47503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(mat2[col], mat1[col])) 47523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 47583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename In> 47603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct InTuple : 47613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public Tuple4<typename In::In0, typename In::In1, typename In::In2, typename In::In3> 47623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 47633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InTuple (const typename In::In0& in0, 47643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename In::In1& in1, 47653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename In::In2& in2, 47663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const typename In::In3& in3) 47673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : Tuple4<typename In::In0, typename In::In1, typename In::In2, typename In::In3> 47683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (in0, in1, in2, in3) {} 47693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 47703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename In> 47723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct InputLess<InTuple<In> > 47733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 47743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const InTuple<In>& in1, const InTuple<In>& in2) const 47753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(in1.a, in2.a)) 47773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(in2.a, in1.a)) 47793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(in1.b, in2.b)) 47813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(in2.b, in1.b)) 47833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(in1.c, in2.c)) 47853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(in2.c, in1.c)) 47873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputLess(in1.d, in2.d)) 47893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 47923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 47933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename In> 47953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInputs<In> generateInputs (const Samplings<In>& samplings, 47963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& floatFormat, 47978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Precision intPrecision, 47983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t numSamples, 47993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Random& rnd) 48003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 48013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Inputs<In> ret; 48023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Inputs<In> fixedInputs; 48033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry set<InTuple<In>, InputLess<InTuple<In> > > seenInputs; 48043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry samplings.in0.genFixeds(floatFormat, fixedInputs.in0); 48063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry samplings.in1.genFixeds(floatFormat, fixedInputs.in1); 48073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry samplings.in2.genFixeds(floatFormat, fixedInputs.in2); 48083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry samplings.in3.genFixeds(floatFormat, fixedInputs.in3); 48093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx0 = 0; ndx0 < fixedInputs.in0.size(); ++ndx0) 48113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx1 = 0; ndx1 < fixedInputs.in1.size(); ++ndx1) 48133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx2 = 0; ndx2 < fixedInputs.in2.size(); ++ndx2) 48153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx3 = 0; ndx3 < fixedInputs.in3.size(); ++ndx3) 48173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InTuple<In> tuple (fixedInputs.in0[ndx0], 48193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fixedInputs.in1[ndx1], 48203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fixedInputs.in2[ndx2], 48213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fixedInputs.in3[ndx3]); 48223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry seenInputs.insert(tuple); 48243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in0.push_back(tuple.a); 48253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in1.push_back(tuple.b); 48263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in2.push_back(tuple.c); 48273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in3.push_back(tuple.d); 48283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < numSamples; ++ndx) 48343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const typename In::In0 in0 = samplings.in0.genRandom(floatFormat, intPrecision, rnd); 48368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const typename In::In1 in1 = samplings.in1.genRandom(floatFormat, intPrecision, rnd); 48378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const typename In::In2 in2 = samplings.in2.genRandom(floatFormat, intPrecision, rnd); 48388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const typename In::In3 in3 = samplings.in3.genRandom(floatFormat, intPrecision, rnd); 48393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InTuple<In> tuple (in0, in1, in2, in3); 48403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::contains(seenInputs, tuple)) 48423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 48433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry seenInputs.insert(tuple); 48453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in0.push_back(in0); 48463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in1.push_back(in1); 48473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in2.push_back(in2); 48483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.in3.push_back(in3); 48493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 48523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 48533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FuncCaseBase : public PrecisionCase 48553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 48563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 48573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 48583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 48603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FuncCaseBase (const Context& context, 48613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string& name, 48623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FuncBase& func) 48638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry : PrecisionCase (context, name, func.getRequiredExtension()) {} 48643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 48653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIterateResult FuncCaseBase::iterate (void) 48673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 48683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<ContextInfo> info (ContextInfo::create(getRenderContext())); 48693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_extension.empty() && !info->isExtensionSupported(m_extension.c_str())) 48713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw NotSupportedError("Unsupported extension: " + m_extension); 48723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry runTest(); 48743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_status.setTestContextResult(m_testCtx); 48763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 48773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 48783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 48803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FuncCase : public FuncCaseBase 48813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 48823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 48833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Func<Sig> CaseFunc; 48843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Ret Ret; 48853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg0 Arg0; 48863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg1 Arg1; 48873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg2 Arg2; 48883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg3 Arg3; 48893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef InTypes<Arg0, Arg1, Arg2, Arg3> In; 48903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef OutTypes<Ret> Out; 48913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FuncCase (const Context& context, 48933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string& name, 48943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseFunc& func) 48953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : FuncCaseBase (context, name, func) 48963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_func (func) {} 48973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 48993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runTest (void); 49003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual const Samplings<In>& getSamplings (void) 49023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 49033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return instance<DefaultSamplings<In> >(); 49043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 49053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 49073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseFunc& m_func; 49083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 49093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 49113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FuncCase<Sig>::runTest (void) 49123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 49133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Inputs<In> inputs (generateInputs(getSamplings(), 49143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ctx.floatFormat, 49158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_ctx.precision, 49163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ctx.numRandoms, 49173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_rnd)); 49183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Variables<In, Out> variables; 49193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.out0 = variable<Ret>("out0"); 49213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.out1 = variable<Void>("out1"); 49223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in0 = variable<Arg0>("in0"); 49233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in1 = variable<Arg1>("in1"); 49243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in2 = variable<Arg2>("in2"); 49253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in3 = variable<Arg3>("in3"); 49263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 49283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> expr = applyVar(m_func, 49293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in0, variables.in1, 49303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in2, variables.in3); 49313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StatementP stmt = variableAssignment(variables.out0, expr); 49323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->testStatement(variables, inputs, *stmt); 49343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 49353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 49363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 49383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InOutFuncCase : public FuncCaseBase 49393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 49403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 49413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef Func<Sig> CaseFunc; 49423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Ret Ret; 49433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg0 Arg0; 49443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg1 Arg1; 49453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg2 Arg2; 49463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef typename Sig::Arg3 Arg3; 49473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef InTypes<Arg0, Arg2, Arg3> In; 49483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef OutTypes<Ret, Arg1> Out; 49493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InOutFuncCase (const Context& context, 49513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string& name, 49523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseFunc& func) 49533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : FuncCaseBase (context, name, func) 49543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_func (func) {} 49553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 49573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runTest (void); 49583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual const Samplings<In>& getSamplings (void) 49603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 49613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return instance<DefaultSamplings<In> >(); 49623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 49633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 49653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseFunc& m_func; 49663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 49673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 49693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InOutFuncCase<Sig>::runTest (void) 49703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 49713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Inputs<In> inputs (generateInputs(getSamplings(), 49723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ctx.floatFormat, 49738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_ctx.precision, 49743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ctx.numRandoms, 49753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_rnd)); 49763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Variables<In, Out> variables; 49773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.out0 = variable<Ret>("out0"); 49793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.out1 = variable<Arg1>("out1"); 49803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in0 = variable<Arg0>("in0"); 49813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in1 = variable<Arg2>("in1"); 49823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in2 = variable<Arg3>("in2"); 49833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in3 = variable<Void>("in3"); 49843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 49863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ExprP<Ret> expr = applyVar(m_func, 49873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in0, variables.out1, 49883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry variables.in1, variables.in2); 49893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StatementP stmt = variableAssignment(variables.out0, expr); 49903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->testStatement(variables, inputs, *stmt); 49923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 49933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 49943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 49963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPrecisionCase* createFuncCase (const Context& context, 49973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string& name, 49983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Func<Sig>& func) 49993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (func.getOutParamIndex()) 50013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case -1: 50033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new FuncCase<Sig>(context, name, func); 50043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: 50053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new InOutFuncCase<Sig>(context, name, func); 50063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 50071cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry DE_FATAL("Impossible"); 50083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 50103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 50113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CaseFactory 50133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 50153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual ~CaseFactory (void) {} 50163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual MovePtr<TestNode> createCase (const Context& ctx) const = 0; 50173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string getName (void) const = 0; 50183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string getDesc (void) const = 0; 50193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 50203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FuncCaseFactory : public CaseFactory 50223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 50243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual const FuncBase& getFunc (void) const = 0; 50253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 50273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::toLower(getFunc().getName()); 50293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getDesc (void) const 50323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "Function '" + getFunc().getName() + "'"; 50343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 50363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 50383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GenFuncCaseFactory : public CaseFactory 50393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 50413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GenFuncCaseFactory (const GenFuncs<Sig>& funcs, 50433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string& name) 50443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_funcs (funcs) 50453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_name (de::toLower(name)) {} 50463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<TestNode> createCase (const Context& ctx) const 50483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* group = new TestCaseGroup(ctx.testContext, 50503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.name.c_str(), ctx.name.c_str()); 50513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "scalar", m_funcs.func)); 50533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "vec2", m_funcs.func2)); 50543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "vec3", m_funcs.func3)); 50553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "vec4", m_funcs.func4)); 50563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return MovePtr<TestNode>(group); 50583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 50613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_name; 50633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getDesc (void) const 50663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "Function '" + m_funcs.func.getName() + "'"; 50683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 50713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GenFuncs<Sig> m_funcs; 50723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string m_name; 50733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 50743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <template <int> class GenF> 50763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TemplateFuncCaseFactory : public FuncCaseFactory 50773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 50793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<TestNode> createCase (const Context& ctx) const 50803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* group = new TestCaseGroup(ctx.testContext, 50823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.name.c_str(), ctx.name.c_str()); 50833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "scalar", instance<GenF<1> >())); 50843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "vec2", instance<GenF<2> >())); 50853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "vec3", instance<GenF<3> >())); 50863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "vec4", instance<GenF<4> >())); 50873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return MovePtr<TestNode>(group); 50893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FuncBase& getFunc (void) const { return instance<GenF<1> >(); } 50923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 50933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <template <int> class GenF> 50953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SquareMatrixFuncCaseFactory : public FuncCaseFactory 50963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 50983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<TestNode> createCase (const Context& ctx) const 50993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* group = new TestCaseGroup(ctx.testContext, 51013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.name.c_str(), ctx.name.c_str()); 51023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "mat2", instance<GenF<2> >())); 51033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if 0 51043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // disabled until we get reasonable results 51053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "mat3", instance<GenF<3> >())); 51063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, "mat4", instance<GenF<4> >())); 51073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 51083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return MovePtr<TestNode>(group); 51103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FuncBase& getFunc (void) const { return instance<GenF<2> >(); } 51133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 51143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <template <int, int> class GenF> 51163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MatrixFuncCaseFactory : public FuncCaseFactory 51173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 51183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 51193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<TestNode> createCase (const Context& ctx) const 51203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const group = new TestCaseGroup(ctx.testContext, 51223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ctx.name.c_str(), ctx.name.c_str()); 51233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<2, 2>(ctx, group); 51253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<3, 2>(ctx, group); 51263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<4, 2>(ctx, group); 51273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<2, 3>(ctx, group); 51283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<3, 3>(ctx, group); 51293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<4, 3>(ctx, group); 51303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<2, 4>(ctx, group); 51313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<3, 4>(ctx, group); 51323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry this->addCase<4, 4>(ctx, group); 51333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return MovePtr<TestNode>(group); 51353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FuncBase& getFunc (void) const { return instance<GenF<2,2> >(); } 51383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 51403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template <int Rows, int Cols> 51413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void addCase (const Context& ctx, TestCaseGroup* group) const 51423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const name = dataTypeNameOf<Matrix<float, Rows, Cols> >(); 51443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(createFuncCase(ctx, name, instance<GenF<Rows, Cols> >())); 51463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 51483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Sig> 51503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SimpleFuncCaseFactory : public CaseFactory 51513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 51523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 51533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SimpleFuncCaseFactory (const Func<Sig>& func) : m_func(func) {} 51543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<TestNode> createCase (const Context& ctx) const 51563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return MovePtr<TestNode>(createFuncCase(ctx, ctx.name.c_str(), m_func)); 51583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getName (void) const 51613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::toLower(m_func.getName()); 51633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string getDesc (void) const 51663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "Function '" + getName() + "'"; 51683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 51713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Func<Sig>& m_func; 51723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 51733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F> 51753c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySharedPtr<SimpleFuncCaseFactory<typename F::Sig> > createSimpleFuncCaseFactory (void) 51763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 51773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return SharedPtr<SimpleFuncCaseFactory<typename F::Sig> >( 51783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry new SimpleFuncCaseFactory<typename F::Sig>(instance<F>())); 51793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 51803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BuiltinFuncs : public CaseFactories 51823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 51833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 51843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<const CaseFactory*> getFactories (void) const 51853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<const CaseFactory*> ret; 51873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < m_factories.size(); ++ndx) 51893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret.push_back(m_factories[ndx].get()); 51903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 51923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void addFactory (SharedPtr<const CaseFactory> fact) 51953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_factories.push_back(fact); 51973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 52003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<SharedPtr<const CaseFactory> > m_factories; 52013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 52023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename F> 52043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid addScalarFactory(BuiltinFuncs& funcs, string name = "") 52053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 52063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (name.empty()) 52073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name = instance<F>().getName(); 52083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs.addFactory(SharedPtr<const CaseFactory>(new GenFuncCaseFactory<typename F::Sig>( 52103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry makeVectorizedFuncs<F>(), name))); 52113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 52123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMovePtr<const CaseFactories> createES3BuiltinCases (void) 52143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 52153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<BuiltinFuncs> funcs (new BuiltinFuncs()); 52163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Add>(*funcs); 52183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Sub>(*funcs); 52193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Mul>(*funcs); 52203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Div>(*funcs); 52213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Radians>(*funcs); 52233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Degrees>(*funcs); 52243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Sin>(*funcs); 52253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Cos>(*funcs); 52263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Tan>(*funcs); 52273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<ASin>(*funcs); 52283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<ACos>(*funcs); 52293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<ATan2>(*funcs, "atan2"); 52303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<ATan>(*funcs); 52313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Sinh>(*funcs); 52323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Cosh>(*funcs); 52333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Tanh>(*funcs); 52343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<ASinh>(*funcs); 52353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<ACosh>(*funcs); 52363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<ATanh>(*funcs); 52373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Pow>(*funcs); 52393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Exp>(*funcs); 52403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Log>(*funcs); 52413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Exp2>(*funcs); 52423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Log2>(*funcs); 52433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Sqrt>(*funcs); 52443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<InverseSqrt>(*funcs); 52453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Abs>(*funcs); 52473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Sign>(*funcs); 52483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Floor>(*funcs); 52493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Trunc>(*funcs); 52503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Round>(*funcs); 52513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<RoundEven>(*funcs); 52523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Ceil>(*funcs); 52533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Fract>(*funcs); 52543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Mod>(*funcs); 52553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(createSimpleFuncCaseFactory<Modf>()); 52563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Min>(*funcs); 52573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Max>(*funcs); 52583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Clamp>(*funcs); 52593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Mix>(*funcs); 52603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Step>(*funcs); 52613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<SmoothStep>(*funcs); 52623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Length>())); 52643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Distance>())); 52653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Dot>())); 52663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(createSimpleFuncCaseFactory<Cross>()); 52673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Normalize>())); 52683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<FaceForward>())); 52693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Reflect>())); 52703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new TemplateFuncCaseFactory<Refract>())); 52713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new MatrixFuncCaseFactory<MatrixCompMult>())); 52743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new MatrixFuncCaseFactory<OuterProduct>())); 52753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new MatrixFuncCaseFactory<Transpose>())); 52763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new SquareMatrixFuncCaseFactory<Determinant>())); 52773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry funcs->addFactory(SharedPtr<const CaseFactory>(new SquareMatrixFuncCaseFactory<Inverse>())); 52783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return MovePtr<const CaseFactories>(funcs.release()); 52803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 52813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMovePtr<const CaseFactories> createES31BuiltinCases (void) 52833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 52843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MovePtr<BuiltinFuncs> funcs (new BuiltinFuncs()); 52853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<FrExp>(*funcs); 52873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<LdExp>(*funcs); 52883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addScalarFactory<Fma>(*funcs); 52893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return MovePtr<const CaseFactories>(funcs.release()); 52913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 52923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct PrecisionTestContext 52943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 52953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PrecisionTestContext (TestContext& testCtx_, 52963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RenderContext& renderCtx_, 52973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& highp_, 52983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& mediump_, 52993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat& lowp_, 53003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<ShaderType>& shaderTypes_, 53013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRandoms_) 53023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : testCtx (testCtx_) 53033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , renderCtx (renderCtx_) 53043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , shaderTypes (shaderTypes_) 53053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , numRandoms (numRandoms_) 53063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry formats[glu::PRECISION_HIGHP] = &highp_; 53083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry formats[glu::PRECISION_MEDIUMP] = &mediump_; 53093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry formats[glu::PRECISION_LOWP] = &lowp_; 53103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestContext& testCtx; 53133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RenderContext& renderCtx; 53143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat* formats[glu::PRECISION_LAST]; 53153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<ShaderType> shaderTypes; 53163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRandoms; 53173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 53183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCaseGroup* createFuncGroup (const PrecisionTestContext& ctx, 53203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseFactory& factory) 53213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5322653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos TestCaseGroup* const group = new TestCaseGroup(ctx.testCtx, 53233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry factory.getName().c_str(), 53243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry factory.getDesc().c_str()); 53253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int precNdx = 0; precNdx < glu::PRECISION_LAST; ++precNdx) 53273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Precision precision = Precision(precNdx); 53293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string precName (glu::getPrecisionName(precision)); 53305730719a54e92e0816ef2b4217a2277907d67bccJarkko Pöyry const FloatFormat& fmt = *de::getSizedArrayElement<glu::PRECISION_LAST>(ctx.formats, precNdx); 53315730719a54e92e0816ef2b4217a2277907d67bccJarkko Pöyry const FloatFormat& highpFmt = *de::getSizedArrayElement<glu::PRECISION_LAST>(ctx.formats, 53325730719a54e92e0816ef2b4217a2277907d67bccJarkko Pöyry glu::PRECISION_HIGHP); 53333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t shaderNdx = 0; shaderNdx < ctx.shaderTypes.size(); ++shaderNdx) 53353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ShaderType shaderType = ctx.shaderTypes[shaderNdx]; 5337653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos const string shaderName (glu::getShaderTypeName(shaderType)); 53383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string name = precName + "_" + shaderName; 53393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Context caseCtx (name, ctx.testCtx, ctx.renderCtx, fmt, highpFmt, 53403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry precision, shaderType, ctx.numRandoms); 53413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(factory.createCase(caseCtx).release()); 53433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return group; 53473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 53483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid addBuiltinPrecisionTests (TestContext& testCtx, 53503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RenderContext& renderCtx, 53513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseFactories& cases, 53523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<ShaderType>& shaderTypes, 53533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup& dstGroup) 53543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 53552fe928514327a48b70de83c293881347797da3e2Pyry Haulos const int userRandoms = testCtx.getCommandLine().getTestIterationCount(); 53562fe928514327a48b70de83c293881347797da3e2Pyry Haulos const int defRandoms = 16384; 53572fe928514327a48b70de83c293881347797da3e2Pyry Haulos const int numRandoms = userRandoms > 0 ? userRandoms : defRandoms; 53583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat highp (-126, 127, 23, true, 53593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::MAYBE, // subnormals 53603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::YES, // infinities 53613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::MAYBE); // NaN 53623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2014-04-01 lauri] Check these once Khronos bug 11840 is resolved. 53633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat mediump (-13, 13, 9, false); 53643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // A fixed-point format is just a floating point format with a fixed 53653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // exponent and support for subnormals. 53663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const FloatFormat lowp (0, 0, 7, false, tcu::YES); 53673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const PrecisionTestContext ctx (testCtx, renderCtx, highp, mediump, lowp, 53682fe928514327a48b70de83c293881347797da3e2Pyry Haulos shaderTypes, numRandoms); 53693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (size_t ndx = 0; ndx < cases.getFactories().size(); ++ndx) 53713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dstGroup.addChild(createFuncGroup(ctx, *cases.getFactories()[ndx])); 53723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 53733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // BuiltinPrecisionTests 53753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gls 53763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 5377