blob: fe579ab1c49789933676ead5082d254c205518f0 [file] [log] [blame]
#ifndef _RSGBINARYOPS_HPP
#define _RSGBINARYOPS_HPP
/*-------------------------------------------------------------------------
* drawElements Quality Program Random Shader Generator
* ----------------------------------------------------
*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Binary operators.
*//*--------------------------------------------------------------------*/
#include "rsgDefs.hpp"
#include "rsgExpression.hpp"
namespace rsg
{
enum Associativity
{
ASSOCIATIVITY_LEFT = 0,
ASSOCIATIVITY_RIGHT,
ASSOCIATIVITY_LAST
};
template <int Precedence, Associativity Assoc>
class BinaryOp : public Expression
{
public:
BinaryOp(Token::Type operatorToken);
virtual ~BinaryOp(void);
Expression *createNextChild(GeneratorState &state);
void tokenize(GeneratorState &state, TokenStream &str) const;
void evaluate(ExecutionContext &execCtx);
ExecConstValueAccess getValue(void) const
{
return m_value.getValue(m_type);
}
virtual void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b) = DE_NULL;
protected:
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
Token::Type m_operator;
VariableType m_type;
ExecValueStorage m_value;
ValueRange m_leftValueRange;
ValueRange m_rightValueRange;
Expression *m_leftValueExpr;
Expression *m_rightValueExpr;
};
template <int Precedence, bool Float, bool Int, bool Bool, class ComputeValueRange, class EvaluateComp>
class BinaryVecOp : public BinaryOp<Precedence, ASSOCIATIVITY_LEFT>
{
public:
BinaryVecOp(GeneratorState &state, Token::Type operatorToken, ConstValueRangeAccess valueRange);
virtual ~BinaryVecOp(void);
void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b);
};
struct ComputeMulRange
{
void operator()(de::Random &rnd, float dstMin, float dstMax, float &aMin, float &aMax, float &bMin,
float &bMax) const;
void operator()(de::Random &rnd, int dstMin, int dstMax, int &aMin, int &aMax, int &bMin, int &bMax) const;
void operator()(de::Random &, bool, bool, bool &, bool &, bool &, bool &) const
{
DE_ASSERT(false);
}
};
struct EvaluateMul
{
template <typename T>
inline T operator()(T a, T b) const
{
return a * b;
}
};
typedef BinaryVecOp<4, true, true, false, ComputeMulRange, EvaluateMul> MulBase;
class MulOp : public MulBase
{
public:
MulOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~MulOp(void)
{
}
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
struct ComputeAddRange
{
template <typename T>
void operator()(de::Random &rnd, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const;
};
struct EvaluateAdd
{
template <typename T>
inline T operator()(T a, T b) const
{
return a + b;
}
};
typedef BinaryVecOp<5, true, true, false, ComputeAddRange, EvaluateAdd> AddBase;
class AddOp : public AddBase
{
public:
AddOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~AddOp(void)
{
}
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
struct ComputeSubRange
{
template <typename T>
void operator()(de::Random &rnd, T dstMin, T dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const;
};
struct EvaluateSub
{
template <typename T>
inline T operator()(T a, T b) const
{
return a - b;
}
};
typedef BinaryVecOp<5, true, true, false, ComputeSubRange, EvaluateSub> SubBase;
class SubOp : public SubBase
{
public:
SubOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~SubOp(void)
{
}
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
/* Template for Relational Operators. */
template <class ComputeValueRange, class EvaluateComp>
class RelationalOp : public BinaryOp<7, ASSOCIATIVITY_LEFT>
{
public:
RelationalOp(GeneratorState &state, Token::Type operatorToken, ConstValueRangeAccess valueRange);
virtual ~RelationalOp(void);
void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b);
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
/* Less Than. */
struct ComputeLessThanRange
{
template <typename T>
void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const;
};
struct EvaluateLessThan
{
template <typename T>
inline bool operator()(T a, T b) const
{
return a < b;
}
};
typedef RelationalOp<ComputeLessThanRange, EvaluateLessThan> LessThanBase;
class LessThanOp : public LessThanBase
{
public:
LessThanOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~LessThanOp(void)
{
}
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
/* Less or Equal. */
struct ComputeLessOrEqualRange
{
template <typename T>
void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const;
};
struct EvaluateLessOrEqual
{
template <typename T>
inline bool operator()(T a, T b) const
{
return a <= b;
}
};
typedef RelationalOp<ComputeLessOrEqualRange, EvaluateLessOrEqual> LessOrEqualBase;
class LessOrEqualOp : public LessOrEqualBase
{
public:
LessOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~LessOrEqualOp(void)
{
}
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
/* Greater Than. */
struct ComputeGreaterThanRange
{
template <typename T>
void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const
{
ComputeLessThanRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax);
}
};
struct EvaluateGreaterThan
{
template <typename T>
inline bool operator()(T a, T b) const
{
return a > b;
}
};
typedef RelationalOp<ComputeGreaterThanRange, EvaluateGreaterThan> GreaterThanBase;
class GreaterThanOp : public GreaterThanBase
{
public:
GreaterThanOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~GreaterThanOp(void)
{
}
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
/* Greater or Equal. */
struct ComputeGreaterOrEqualRange
{
template <typename T>
void operator()(de::Random &rnd, bool dstMin, bool dstMax, T &aMin, T &aMax, T &bMin, T &bMax) const
{
ComputeLessOrEqualRange()(rnd, dstMin, dstMax, bMin, bMax, aMin, aMax);
}
};
struct EvaluateGreaterOrEqual
{
template <typename T>
inline bool operator()(T a, T b) const
{
return a >= b;
}
};
typedef RelationalOp<ComputeGreaterOrEqualRange, EvaluateGreaterOrEqual> GreaterOrEqualBase;
class GreaterOrEqualOp : public GreaterOrEqualBase
{
public:
GreaterOrEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~GreaterOrEqualOp(void)
{
}
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
/* Equality comparison. */
template <bool IsEqual>
class EqualityComparisonOp : public BinaryOp<8, ASSOCIATIVITY_LEFT>
{
public:
EqualityComparisonOp(GeneratorState &state, ConstValueRangeAccess valueRange);
virtual ~EqualityComparisonOp(void)
{
}
void evaluate(ExecValueAccess dst, ExecConstValueAccess a, ExecConstValueAccess b);
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
// \note Since template implementation is in .cpp we have to reference specialized constructor and static functions from there.
class EqualOp : public EqualityComparisonOp<true>
{
public:
EqualOp(GeneratorState &state, ConstValueRangeAccess valueRange);
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
class NotEqualOp : public EqualityComparisonOp<false>
{
public:
NotEqualOp(GeneratorState &state, ConstValueRangeAccess valueRange);
static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange);
};
} // namespace rsg
#endif // _RSGBINARYOPS_HPP