1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Random Shader Generator
3*35238bceSAndroid Build Coastguard Worker * ----------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Shader Class.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "rsgShader.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker using std::vector;
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker namespace rsg
29*35238bceSAndroid Build Coastguard Worker {
30*35238bceSAndroid Build Coastguard Worker
31*35238bceSAndroid Build Coastguard Worker namespace
32*35238bceSAndroid Build Coastguard Worker {
33*35238bceSAndroid Build Coastguard Worker
34*35238bceSAndroid Build Coastguard Worker template <typename T>
deleteVectorElements(std::vector<T * > & vec)35*35238bceSAndroid Build Coastguard Worker void deleteVectorElements(std::vector<T *> &vec)
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker for (typename std::vector<T *>::iterator i = vec.begin(); i != vec.end(); i++)
38*35238bceSAndroid Build Coastguard Worker delete *i;
39*35238bceSAndroid Build Coastguard Worker vec.clear();
40*35238bceSAndroid Build Coastguard Worker }
41*35238bceSAndroid Build Coastguard Worker
42*35238bceSAndroid Build Coastguard Worker } // namespace
43*35238bceSAndroid Build Coastguard Worker
Function(void)44*35238bceSAndroid Build Coastguard Worker Function::Function(void)
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker }
47*35238bceSAndroid Build Coastguard Worker
Function(const char * name)48*35238bceSAndroid Build Coastguard Worker Function::Function(const char *name) : m_name(name)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker }
51*35238bceSAndroid Build Coastguard Worker
~Function(void)52*35238bceSAndroid Build Coastguard Worker Function::~Function(void)
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker deleteVectorElements(m_parameters);
55*35238bceSAndroid Build Coastguard Worker }
56*35238bceSAndroid Build Coastguard Worker
ShaderInput(const Variable * variable,ConstValueRangeAccess valueRange)57*35238bceSAndroid Build Coastguard Worker ShaderInput::ShaderInput(const Variable *variable, ConstValueRangeAccess valueRange)
58*35238bceSAndroid Build Coastguard Worker : m_variable(variable)
59*35238bceSAndroid Build Coastguard Worker , m_min(variable->getType().getScalarSize())
60*35238bceSAndroid Build Coastguard Worker , m_max(variable->getType().getScalarSize())
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker ValueAccess(variable->getType(), &m_min[0]) = valueRange.getMin().value();
63*35238bceSAndroid Build Coastguard Worker ValueAccess(variable->getType(), &m_max[0]) = valueRange.getMax().value();
64*35238bceSAndroid Build Coastguard Worker }
65*35238bceSAndroid Build Coastguard Worker
Shader(Type type)66*35238bceSAndroid Build Coastguard Worker Shader::Shader(Type type) : m_type(type), m_mainFunction("main")
67*35238bceSAndroid Build Coastguard Worker {
68*35238bceSAndroid Build Coastguard Worker }
69*35238bceSAndroid Build Coastguard Worker
~Shader(void)70*35238bceSAndroid Build Coastguard Worker Shader::~Shader(void)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker deleteVectorElements(m_functions);
73*35238bceSAndroid Build Coastguard Worker deleteVectorElements(m_globalStatements);
74*35238bceSAndroid Build Coastguard Worker deleteVectorElements(m_inputs);
75*35238bceSAndroid Build Coastguard Worker deleteVectorElements(m_uniforms);
76*35238bceSAndroid Build Coastguard Worker }
77*35238bceSAndroid Build Coastguard Worker
getOutputs(vector<const Variable * > & outputs) const78*35238bceSAndroid Build Coastguard Worker void Shader::getOutputs(vector<const Variable *> &outputs) const
79*35238bceSAndroid Build Coastguard Worker {
80*35238bceSAndroid Build Coastguard Worker outputs.clear();
81*35238bceSAndroid Build Coastguard Worker const vector<Variable *> &globalVars = m_globalScope.getDeclaredVariables();
82*35238bceSAndroid Build Coastguard Worker for (vector<Variable *>::const_iterator i = globalVars.begin(); i != globalVars.end(); i++)
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker const Variable *var = *i;
85*35238bceSAndroid Build Coastguard Worker if (var->getStorage() == Variable::STORAGE_SHADER_OUT)
86*35238bceSAndroid Build Coastguard Worker outputs.push_back(var);
87*35238bceSAndroid Build Coastguard Worker }
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker
tokenize(GeneratorState & state,TokenStream & str) const90*35238bceSAndroid Build Coastguard Worker void Shader::tokenize(GeneratorState &state, TokenStream &str) const
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker // Add default precision for float in fragment shaders \todo [pyry] Proper precision handling
93*35238bceSAndroid Build Coastguard Worker if (state.getShader().getType() == Shader::TYPE_FRAGMENT)
94*35238bceSAndroid Build Coastguard Worker str << Token::PRECISION << Token::MEDIUM_PRECISION << Token::FLOAT << Token::SEMICOLON << Token::NEWLINE;
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker // Tokenize global declaration statements
97*35238bceSAndroid Build Coastguard Worker for (int ndx = (int)m_globalStatements.size() - 1; ndx >= 0; ndx--)
98*35238bceSAndroid Build Coastguard Worker m_globalStatements[ndx]->tokenize(state, str);
99*35238bceSAndroid Build Coastguard Worker
100*35238bceSAndroid Build Coastguard Worker // Tokenize all functions
101*35238bceSAndroid Build Coastguard Worker for (int ndx = (int)m_functions.size() - 1; ndx >= 0; ndx--)
102*35238bceSAndroid Build Coastguard Worker {
103*35238bceSAndroid Build Coastguard Worker str << Token::NEWLINE;
104*35238bceSAndroid Build Coastguard Worker m_functions[ndx]->tokenize(state, str);
105*35238bceSAndroid Build Coastguard Worker }
106*35238bceSAndroid Build Coastguard Worker
107*35238bceSAndroid Build Coastguard Worker // Tokenize main
108*35238bceSAndroid Build Coastguard Worker str << Token::NEWLINE;
109*35238bceSAndroid Build Coastguard Worker m_mainFunction.tokenize(state, str);
110*35238bceSAndroid Build Coastguard Worker }
111*35238bceSAndroid Build Coastguard Worker
execute(ExecutionContext & execCtx) const112*35238bceSAndroid Build Coastguard Worker void Shader::execute(ExecutionContext &execCtx) const
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker // Execute global statements (declarations)
115*35238bceSAndroid Build Coastguard Worker for (vector<Statement *>::const_reverse_iterator i = m_globalStatements.rbegin(); i != m_globalStatements.rend();
116*35238bceSAndroid Build Coastguard Worker i++)
117*35238bceSAndroid Build Coastguard Worker (*i)->execute(execCtx);
118*35238bceSAndroid Build Coastguard Worker
119*35238bceSAndroid Build Coastguard Worker // \todo [2011-03-08 pyry] Proper function calls
120*35238bceSAndroid Build Coastguard Worker m_mainFunction.getBody().execute(execCtx);
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker
tokenize(GeneratorState & state,TokenStream & str) const123*35238bceSAndroid Build Coastguard Worker void Function::tokenize(GeneratorState &state, TokenStream &str) const
124*35238bceSAndroid Build Coastguard Worker {
125*35238bceSAndroid Build Coastguard Worker // Return type
126*35238bceSAndroid Build Coastguard Worker m_returnType.tokenizeShortType(str);
127*35238bceSAndroid Build Coastguard Worker
128*35238bceSAndroid Build Coastguard Worker // Function name
129*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_name != "");
130*35238bceSAndroid Build Coastguard Worker str << Token(m_name.c_str());
131*35238bceSAndroid Build Coastguard Worker
132*35238bceSAndroid Build Coastguard Worker // Parameters
133*35238bceSAndroid Build Coastguard Worker str << Token::LEFT_PAREN;
134*35238bceSAndroid Build Coastguard Worker
135*35238bceSAndroid Build Coastguard Worker for (vector<Variable *>::const_iterator i = m_parameters.begin(); i != m_parameters.end(); i++)
136*35238bceSAndroid Build Coastguard Worker {
137*35238bceSAndroid Build Coastguard Worker if (i != m_parameters.begin())
138*35238bceSAndroid Build Coastguard Worker str << Token::COMMA;
139*35238bceSAndroid Build Coastguard Worker (*i)->tokenizeDeclaration(state, str);
140*35238bceSAndroid Build Coastguard Worker }
141*35238bceSAndroid Build Coastguard Worker
142*35238bceSAndroid Build Coastguard Worker str << Token::RIGHT_PAREN << Token::NEWLINE;
143*35238bceSAndroid Build Coastguard Worker
144*35238bceSAndroid Build Coastguard Worker // Tokenize body
145*35238bceSAndroid Build Coastguard Worker m_functionBlock.tokenize(state, str);
146*35238bceSAndroid Build Coastguard Worker }
147*35238bceSAndroid Build Coastguard Worker
148*35238bceSAndroid Build Coastguard Worker } // namespace rsg
149