blob: cca81adf90eb405478394be77544f5b7ddf344f2 [file] [log] [blame]
#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<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;
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