Home | History | Annotate | Download | only in randomshaders
      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