#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(DE_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); 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); 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; 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; deUint8 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; }; } // rsg #endif // _RSGEXPRESSION_HPP