#ifndef _RSGEXPRESSION_HPP #define _RSGEXPRESSION_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 Expressions. * * Creating expressions: * + Children must be created in in reverse evaluation order. * - Must be tokenized / evaluated taking that order in account. * * Evaluation: * + Done recursively. (Do we have enough stack?) * + R-values: Nodes must implement getValue() in some way. Value * must be valid after evaluate(). * + L-values: Valid writable value access proxy must be returned after * evaluate(). *//*--------------------------------------------------------------------*/ #include "rsgDefs.hpp" #include "rsgGeneratorState.hpp" #include "rsgVariableValue.hpp" #include "rsgVariable.hpp" #include "rsgVariableManager.hpp" #include "rsgExecutionContext.hpp" namespace rsg { // \todo [2011-06-10 pyry] Declare in ShaderParameters? const float unusedValueWeight = 0.05f; class Expression { public: virtual ~Expression(void); // Shader generation API virtual Expression *createNextChild(GeneratorState &state) = DE_NULL; virtual void tokenize(GeneratorState &state, TokenStream &str) const = DE_NULL; // Execution API virtual void evaluate(ExecutionContext &ctx) = DE_NULL; virtual ExecConstValueAccess getValue(void) const = DE_NULL; virtual ExecValueAccess getLValue(void) const { DE_ASSERT(false); throw Exception("Expression::getLValue(): not L-value node"); } static Expression *createRandom(GeneratorState &state, ConstValueRangeAccess valueRange); static Expression *createRandomLValue(GeneratorState &state, ConstValueRangeAccess valueRange); }; class VariableAccess : public Expression { public: virtual ~VariableAccess(void) { } Expression *createNextChild(GeneratorState &state) { DE_UNREF(state); return DE_NULL; } void tokenize(GeneratorState &state, TokenStream &str) const { DE_UNREF(state); str << Token(m_variable->getName()); } void evaluate(ExecutionContext &ctx); ExecConstValueAccess getValue(void) const { return m_valueAccess; } ExecValueAccess getLValue(void) const { return m_valueAccess; } protected: VariableAccess(void) : m_variable(DE_NULL) { } const Variable *m_variable; ExecValueAccess m_valueAccess; }; class VariableRead : public VariableAccess { public: VariableRead(GeneratorState &state, ConstValueRangeAccess valueRange); VariableRead(const Variable *variable); virtual ~VariableRead(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; class VariableWrite : public VariableAccess { public: VariableWrite(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~VariableWrite(void) { } static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); }; class FloatLiteral : public Expression { public: FloatLiteral(GeneratorState &state, ConstValueRangeAccess valueRange); FloatLiteral(float customValue); virtual ~FloatLiteral(void) { } Expression *createNextChild(GeneratorState &state) { DE_UNREF(state); return DE_NULL; } void tokenize(GeneratorState &state, TokenStream &str) const; static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &ctx) { DE_UNREF(ctx); } ExecConstValueAccess getValue(void) const { return m_value.getValue(VariableType::getScalarType(VariableType::TYPE_FLOAT)); } private: ExecValueStorage m_value; }; class IntLiteral : public Expression { public: IntLiteral(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~IntLiteral(void) { } Expression *createNextChild(GeneratorState &state) { DE_UNREF(state); return DE_NULL; } void tokenize(GeneratorState &state, TokenStream &str) const; static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &ctx) { DE_UNREF(ctx); } ExecConstValueAccess getValue(void) const { return m_value.getValue(VariableType::getScalarType(VariableType::TYPE_INT)); } private: ExecValueStorage m_value; }; class BoolLiteral : public Expression { public: BoolLiteral(GeneratorState &state, ConstValueRangeAccess valueRange); BoolLiteral(bool customValue); virtual ~BoolLiteral(void) { } Expression *createNextChild(GeneratorState &state) { DE_UNREF(state); return DE_NULL; } void tokenize(GeneratorState &state, TokenStream &str) const; static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &ctx) { DE_UNREF(ctx); } ExecConstValueAccess getValue(void) const { return m_value.getValue(VariableType::getScalarType(VariableType::TYPE_BOOL)); } private: ExecValueStorage m_value; }; class ConstructorOp : public Expression { public: ConstructorOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~ConstructorOp(void); Expression *createNextChild(GeneratorState &state); void tokenize(GeneratorState &state, TokenStream &str) const; static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &ctx); ExecConstValueAccess getValue(void) const { return m_value.getValue(m_valueRange.getType()); } private: ValueRange m_valueRange; ExecValueStorage m_value; std::vector m_inputValueRanges; std::vector m_inputExpressions; }; class AssignOp : public Expression { public: AssignOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~AssignOp(void); Expression *createNextChild(GeneratorState &state); void tokenize(GeneratorState &state, TokenStream &str) const; static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); // \todo [2011-02-28 pyry] LValue variant of AssignOp // static float getLValueWeight (const GeneratorState& state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &ctx); ExecConstValueAccess getValue(void) const { return m_value.getValue(m_valueRange.getType()); } private: ValueRange m_valueRange; ExecValueStorage m_value; Expression *m_lvalueExpr; Expression *m_rvalueExpr; }; class ParenOp : public Expression { public: ParenOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~ParenOp(void); Expression *createNextChild(GeneratorState &state); void tokenize(GeneratorState &state, TokenStream &str) const; void setChild(Expression *expression); static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &execCtx) { m_child->evaluate(execCtx); } ExecConstValueAccess getValue(void) const { return m_child->getValue(); } private: ValueRange m_valueRange; Expression *m_child; }; class SwizzleOp : public Expression { public: SwizzleOp(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~SwizzleOp(void); Expression *createNextChild(GeneratorState &state); void tokenize(GeneratorState &state, TokenStream &str) const; static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &execCtx); ExecConstValueAccess getValue(void) const { return m_value.getValue(m_outValueRange.getType()); } private: ValueRange m_outValueRange; int m_numInputElements; uint8_t m_swizzle[4]; Expression *m_child; ExecValueStorage m_value; }; class TexLookup : public Expression { public: TexLookup(GeneratorState &state, ConstValueRangeAccess valueRange); virtual ~TexLookup(void); Expression *createNextChild(GeneratorState &state); void tokenize(GeneratorState &state, TokenStream &str) const; static float getWeight(const GeneratorState &state, ConstValueRangeAccess valueRange); void evaluate(ExecutionContext &execCtx); ExecConstValueAccess getValue(void) const { return m_value.getValue(m_valueType); } private: enum Type { TYPE_TEXTURE2D, TYPE_TEXTURE2D_LOD, TYPE_TEXTURE2D_PROJ, TYPE_TEXTURE2D_PROJ_LOD, TYPE_TEXTURECUBE, TYPE_TEXTURECUBE_LOD, TYPE_LAST }; Type m_type; const Variable *m_sampler; Expression *m_coordExpr; Expression *m_lodBiasExpr; VariableType m_valueType; ExecValueStorage m_value; }; } // namespace rsg #endif // _RSGEXPRESSION_HPP