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> 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 } // anonymous 43 44 Function::Function (void) 45 { 46 } 47 48 Function::Function (const char* name) 49 : m_name(name) 50 { 51 } 52 53 Function::~Function (void) 54 { 55 deleteVectorElements(m_parameters); 56 } 57 58 ShaderInput::ShaderInput (const Variable* variable, ConstValueRangeAccess valueRange) 59 : m_variable (variable) 60 , m_min (variable->getType().getScalarSize()) 61 , m_max (variable->getType().getScalarSize()) 62 { 63 ValueAccess(variable->getType(), &m_min[0]) = valueRange.getMin().value(); 64 ValueAccess(variable->getType(), &m_max[0]) = valueRange.getMax().value(); 65 } 66 67 Shader::Shader (Type type) 68 : m_type (type) 69 , m_mainFunction ("main") 70 { 71 } 72 73 Shader::~Shader (void) 74 { 75 deleteVectorElements(m_functions); 76 deleteVectorElements(m_globalStatements); 77 deleteVectorElements(m_inputs); 78 deleteVectorElements(m_uniforms); 79 } 80 81 void Shader::getOutputs (vector<const Variable*>& outputs) const 82 { 83 outputs.clear(); 84 const vector<Variable*>& globalVars = m_globalScope.getDeclaredVariables(); 85 for (vector<Variable*>::const_iterator i = globalVars.begin(); i != globalVars.end(); i++) 86 { 87 const Variable* var = *i; 88 if (var->getStorage() == Variable::STORAGE_SHADER_OUT) 89 outputs.push_back(var); 90 } 91 } 92 93 void Shader::tokenize (GeneratorState& state, TokenStream& str) const 94 { 95 // Add default precision for float in fragment shaders \todo [pyry] Proper precision handling 96 if (state.getShader().getType() == Shader::TYPE_FRAGMENT) 97 str << Token::PRECISION << Token::MEDIUM_PRECISION << Token::FLOAT << Token::SEMICOLON << Token::NEWLINE; 98 99 // Tokenize global declaration statements 100 for (int ndx = (int)m_globalStatements.size()-1; ndx >= 0; ndx--) 101 m_globalStatements[ndx]->tokenize(state, str); 102 103 // Tokenize all functions 104 for (int ndx = (int)m_functions.size()-1; ndx >= 0; ndx--) 105 { 106 str << Token::NEWLINE; 107 m_functions[ndx]->tokenize(state, str); 108 } 109 110 // Tokenize main 111 str << Token::NEWLINE; 112 m_mainFunction.tokenize(state, str); 113 } 114 115 void Shader::execute (ExecutionContext& execCtx) const 116 { 117 // Execute global statements (declarations) 118 for (vector<Statement*>::const_reverse_iterator i = m_globalStatements.rbegin(); i != m_globalStatements.rend(); i++) 119 (*i)->execute(execCtx); 120 121 // \todo [2011-03-08 pyry] Proper function calls 122 m_mainFunction.getBody().execute(execCtx); 123 } 124 125 void Function::tokenize (GeneratorState& state, TokenStream& str) const 126 { 127 // Return type 128 m_returnType.tokenizeShortType(str); 129 130 // Function name 131 DE_ASSERT(m_name != ""); 132 str << Token(m_name.c_str()); 133 134 // Parameters 135 str << Token::LEFT_PAREN; 136 137 for (vector<Variable*>::const_iterator i = m_parameters.begin(); i != m_parameters.end(); i++) 138 { 139 if (i != m_parameters.begin()) 140 str << Token::COMMA; 141 (*i)->tokenizeDeclaration(state, str); 142 } 143 144 str << Token::RIGHT_PAREN << Token::NEWLINE; 145 146 // Tokenize body 147 m_functionBlock.tokenize(state, str); 148 } 149 150 } // rsg 151