| #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<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; |
| 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 |