| #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); |
| 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<ValueRange> m_inputValueRanges; |
| std::vector<Expression*> 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; |
| 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 |