Renderer/ShaderAst: Add input and outputs variables

This commit is contained in:
Lynix 2017-01-05 15:17:34 +01:00
parent f7c4c86934
commit 3ed661f387
4 changed files with 58 additions and 32 deletions

View File

@ -44,20 +44,24 @@ namespace Nz
private: private:
struct Function; struct Function;
using VariableContainer = std::set<std::pair<ShaderAst::ExpressionType, String>>;
void Append(ShaderAst::Builtin builtin); void Append(ShaderAst::Builtin builtin);
void Append(ShaderAst::ExpressionType type); void Append(ShaderAst::ExpressionType type);
void Append(const String& txt); void Append(const String& txt);
void AppendCommentSection(const String& section); void AppendCommentSection(const String& section);
void AppendFunction(Function& func); void AppendFunction(Function& func);
void AppendLine(const Nz::String& txt = Nz::String()); void AppendLine(const String& txt = String());
void DeclareVariables(const VariableContainer& variables, const String& keyword = String(), const String& section = String());
void EnterScope(); void EnterScope();
void LeaveScope(); void LeaveScope();
struct Function struct Function
{ {
std::set<std::pair<ShaderAst::ExpressionType, String>> variables; VariableContainer variables;
std::vector<ShaderAst::NamedVariablePtr> parameters; std::vector<ShaderAst::NamedVariablePtr> parameters;
ShaderAst::ExpressionType retType; ShaderAst::ExpressionType retType;
ShaderAst::StatementPtr node; ShaderAst::StatementPtr node;
@ -66,7 +70,9 @@ namespace Nz
struct State struct State
{ {
std::set<std::pair<ShaderAst::ExpressionType, String>> m_uniforms; VariableContainer inputs;
VariableContainer outputs;
VariableContainer uniforms;
StringStream stream; StringStream stream;
unsigned int indentLevel = 0; unsigned int indentLevel = 0;
}; };

View File

@ -55,9 +55,11 @@ namespace Nz
enum class VariableType enum class VariableType
{ {
Builtin, Builtin,
Input,
Output,
Parameter, Parameter,
Variable, Uniform,
Uniform Variable
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -50,6 +50,8 @@ namespace Nz { namespace ShaderBuilder
constexpr GenBuilder<ShaderAst::Branch> Branch; constexpr GenBuilder<ShaderAst::Branch> Branch;
constexpr GenBuilder<ShaderAst::Constant> Constant; constexpr GenBuilder<ShaderAst::Constant> Constant;
constexpr GenBuilder<ShaderAst::ExpressionStatement> ExprStatement; constexpr GenBuilder<ShaderAst::ExpressionStatement> ExprStatement;
constexpr VarBuilder<ShaderAst::VariableType::Input> Input;
constexpr VarBuilder<ShaderAst::VariableType::Output> Output;
constexpr VarBuilder<ShaderAst::VariableType::Parameter> Parameter; constexpr VarBuilder<ShaderAst::VariableType::Parameter> Parameter;
constexpr VarBuilder<ShaderAst::VariableType::Uniform> Uniform; constexpr VarBuilder<ShaderAst::VariableType::Uniform> Uniform;
constexpr VarBuilder<ShaderAst::VariableType::Variable> Variable; constexpr VarBuilder<ShaderAst::VariableType::Variable> Variable;

View File

@ -31,23 +31,10 @@ namespace Nz
AppendLine(String::Number(m_glslVersion)); AppendLine(String::Number(m_glslVersion));
AppendLine(); AppendLine();
// Uniforms // Global variables (uniforms, input and outputs)
if (!state.m_uniforms.empty()) DeclareVariables(state.uniforms, "uniform", "Uniforms");
{ DeclareVariables(state.inputs, "in", "Inputs");
AppendCommentSection("Uniforms"); DeclareVariables(state.outputs, "out", "Outputs");
AppendLine();
for (const auto& pair : state.m_uniforms)
{
Append("uniform ");
Append(pair.first);
Append(" ");
Append(pair.second);
AppendLine(";");
}
AppendLine();
}
Function entryPoint; Function entryPoint;
entryPoint.name = "main"; //< GLSL has only one entry point name possible entryPoint.name = "main"; //< GLSL has only one entry point name possible
@ -73,9 +60,18 @@ namespace Nz
void GlslWriter::RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type) void GlslWriter::RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type)
{ {
NazaraAssert(m_currentState, "This function should only be called while processing an AST"); NazaraAssert(m_currentState, "This function should only be called while processing an AST");
NazaraAssert(kind != ShaderAst::VariableType::Builtin, "Builtin variables should not be registered");
switch (kind) switch (kind)
{ {
case ShaderAst::VariableType::Input:
m_currentState->inputs.insert(std::make_pair(type, name));
break;
case ShaderAst::VariableType::Output:
m_currentState->outputs.insert(std::make_pair(type, name));
break;
case ShaderAst::VariableType::Parameter: case ShaderAst::VariableType::Parameter:
{ {
if (m_currentFunction) if (m_currentFunction)
@ -105,7 +101,7 @@ namespace Nz
} }
case ShaderAst::VariableType::Uniform: case ShaderAst::VariableType::Uniform:
m_currentState->m_uniforms.insert(std::make_pair(type, name)); m_currentState->uniforms.insert(std::make_pair(type, name));
break; break;
case ShaderAst::VariableType::Variable: case ShaderAst::VariableType::Variable:
@ -320,15 +316,7 @@ namespace Nz
EnterScope(); EnterScope();
{ {
for (const auto& pair : func.variables) DeclareVariables(func.variables);
{
Append(pair.first);
Append(" ");
Append(pair.second);
AppendLine(";");
}
AppendLine();
Write(func.node); Write(func.node);
} }
@ -342,6 +330,34 @@ namespace Nz
m_currentState->stream << txt << '\n' << String(m_currentState->indentLevel, '\t'); m_currentState->stream << txt << '\n' << String(m_currentState->indentLevel, '\t');
} }
void GlslWriter::DeclareVariables(const VariableContainer& variables, const String& keyword, const String& section)
{
if (!variables.empty())
{
if (!section.IsEmpty())
{
AppendCommentSection("Uniforms");
AppendLine();
}
for (const auto& pair : variables)
{
if (!keyword.IsEmpty())
{
Append(keyword);
Append(" ");
}
Append(pair.first);
Append(" ");
Append(pair.second);
AppendLine(";");
}
AppendLine();
}
}
void GlslWriter::EnterScope() void GlslWriter::EnterScope()
{ {
NazaraAssert(m_currentState, "This function should only be called while processing an AST"); NazaraAssert(m_currentState, "This function should only be called while processing an AST");