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