You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
3.9 KiB
151 lines
3.9 KiB
4 months ago
|
/*-------------------------------------------------------------------------
|
||
|
* 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 Shader Class.
|
||
|
*//*--------------------------------------------------------------------*/
|
||
|
|
||
|
#include "rsgShader.hpp"
|
||
|
|
||
|
using std::vector;
|
||
|
|
||
|
namespace rsg
|
||
|
{
|
||
|
|
||
|
namespace
|
||
|
{
|
||
|
|
||
|
template <typename T>
|
||
|
void deleteVectorElements (std::vector<T*>& vec)
|
||
|
{
|
||
|
for (typename std::vector<T*>::iterator i = vec.begin(); i != vec.end(); i++)
|
||
|
delete *i;
|
||
|
vec.clear();
|
||
|
}
|
||
|
|
||
|
} // anonymous
|
||
|
|
||
|
Function::Function (void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Function::Function (const char* name)
|
||
|
: m_name(name)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Function::~Function (void)
|
||
|
{
|
||
|
deleteVectorElements(m_parameters);
|
||
|
}
|
||
|
|
||
|
ShaderInput::ShaderInput (const Variable* variable, ConstValueRangeAccess valueRange)
|
||
|
: m_variable (variable)
|
||
|
, m_min (variable->getType().getScalarSize())
|
||
|
, m_max (variable->getType().getScalarSize())
|
||
|
{
|
||
|
ValueAccess(variable->getType(), &m_min[0]) = valueRange.getMin().value();
|
||
|
ValueAccess(variable->getType(), &m_max[0]) = valueRange.getMax().value();
|
||
|
}
|
||
|
|
||
|
Shader::Shader (Type type)
|
||
|
: m_type (type)
|
||
|
, m_mainFunction ("main")
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Shader::~Shader (void)
|
||
|
{
|
||
|
deleteVectorElements(m_functions);
|
||
|
deleteVectorElements(m_globalStatements);
|
||
|
deleteVectorElements(m_inputs);
|
||
|
deleteVectorElements(m_uniforms);
|
||
|
}
|
||
|
|
||
|
void Shader::getOutputs (vector<const Variable*>& outputs) const
|
||
|
{
|
||
|
outputs.clear();
|
||
|
const vector<Variable*>& globalVars = m_globalScope.getDeclaredVariables();
|
||
|
for (vector<Variable*>::const_iterator i = globalVars.begin(); i != globalVars.end(); i++)
|
||
|
{
|
||
|
const Variable* var = *i;
|
||
|
if (var->getStorage() == Variable::STORAGE_SHADER_OUT)
|
||
|
outputs.push_back(var);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Shader::tokenize (GeneratorState& state, TokenStream& str) const
|
||
|
{
|
||
|
// Add default precision for float in fragment shaders \todo [pyry] Proper precision handling
|
||
|
if (state.getShader().getType() == Shader::TYPE_FRAGMENT)
|
||
|
str << Token::PRECISION << Token::MEDIUM_PRECISION << Token::FLOAT << Token::SEMICOLON << Token::NEWLINE;
|
||
|
|
||
|
// Tokenize global declaration statements
|
||
|
for (int ndx = (int)m_globalStatements.size()-1; ndx >= 0; ndx--)
|
||
|
m_globalStatements[ndx]->tokenize(state, str);
|
||
|
|
||
|
// Tokenize all functions
|
||
|
for (int ndx = (int)m_functions.size()-1; ndx >= 0; ndx--)
|
||
|
{
|
||
|
str << Token::NEWLINE;
|
||
|
m_functions[ndx]->tokenize(state, str);
|
||
|
}
|
||
|
|
||
|
// Tokenize main
|
||
|
str << Token::NEWLINE;
|
||
|
m_mainFunction.tokenize(state, str);
|
||
|
}
|
||
|
|
||
|
void Shader::execute (ExecutionContext& execCtx) const
|
||
|
{
|
||
|
// Execute global statements (declarations)
|
||
|
for (vector<Statement*>::const_reverse_iterator i = m_globalStatements.rbegin(); i != m_globalStatements.rend(); i++)
|
||
|
(*i)->execute(execCtx);
|
||
|
|
||
|
// \todo [2011-03-08 pyry] Proper function calls
|
||
|
m_mainFunction.getBody().execute(execCtx);
|
||
|
}
|
||
|
|
||
|
void Function::tokenize (GeneratorState& state, TokenStream& str) const
|
||
|
{
|
||
|
// Return type
|
||
|
m_returnType.tokenizeShortType(str);
|
||
|
|
||
|
// Function name
|
||
|
DE_ASSERT(m_name != "");
|
||
|
str << Token(m_name.c_str());
|
||
|
|
||
|
// Parameters
|
||
|
str << Token::LEFT_PAREN;
|
||
|
|
||
|
for (vector<Variable*>::const_iterator i = m_parameters.begin(); i != m_parameters.end(); i++)
|
||
|
{
|
||
|
if (i != m_parameters.begin())
|
||
|
str << Token::COMMA;
|
||
|
(*i)->tokenizeDeclaration(state, str);
|
||
|
}
|
||
|
|
||
|
str << Token::RIGHT_PAREN << Token::NEWLINE;
|
||
|
|
||
|
// Tokenize body
|
||
|
m_functionBlock.tokenize(state, str);
|
||
|
}
|
||
|
|
||
|
} // rsg
|