From c1b0303f65ee966a973197cbdbf177c571478674 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 14 Feb 2021 14:13:56 +0200 Subject: [PATCH] Move the GLSL compiler entirely in its own namespace --- Build | 4 +- source/core/program.cpp | 4 +- .../{programcompiler.cpp => compiler.cpp} | 326 +++++++------- source/glsl/compiler.h | 417 ++++++++++++++++++ source/glsl/{programparser.cpp => parser.cpp} | 106 ++--- source/glsl/{programparser.h => parser.h} | 58 +-- source/glsl/programcompiler.h | 416 ----------------- source/glsl/{programsyntax.cpp => syntax.cpp} | 6 +- source/glsl/{programsyntax.h => syntax.h} | 10 +- source/resources/resources.cpp | 4 +- 10 files changed, 676 insertions(+), 675 deletions(-) rename source/glsl/{programcompiler.cpp => compiler.cpp} (79%) create mode 100644 source/glsl/compiler.h rename source/glsl/{programparser.cpp => parser.cpp} (87%) rename source/glsl/{programparser.h => parser.h} (55%) delete mode 100644 source/glsl/programcompiler.h rename source/glsl/{programsyntax.cpp => syntax.cpp} (98%) rename source/glsl/{programsyntax.h => syntax.h} (98%) diff --git a/Build b/Build index f193a780..02f502b4 100644 --- a/Build +++ b/Build @@ -53,13 +53,13 @@ package "mspgl" source "shaderlib"; build_info { + incpath "source"; incpath "source/core"; incpath "source/materials"; incpath "source/render"; incpath "source/effects"; incpath "source/animation"; incpath "source/resources"; - incpath "source/glsl"; incpath "source/builders"; }; install true; @@ -71,7 +71,7 @@ package "mspgl" map "source/effects" "include/msp/gl"; map "source/animation" "include/msp/gl"; map "source/resources" "include/msp/gl"; - map "source/glsl" "include/msp/gl"; + map "source/glsl" "include/msp/gl/glsl"; map "source/builders" "include/msp/gl"; map "extensions" "include/msp/gl/extensions"; }; diff --git a/source/core/program.cpp b/source/core/program.cpp index 00bca834..74c1df3e 100644 --- a/source/core/program.cpp +++ b/source/core/program.cpp @@ -14,9 +14,9 @@ #include "error.h" #include "misc.h" #include "program.h" -#include "programcompiler.h" #include "resources.h" #include "shader.h" +#include "glsl/compiler.h" using namespace std; @@ -32,7 +32,7 @@ Program::Program(const std::string &source) { init(); - ProgramCompiler compiler; + SL::Compiler compiler; if(source.find(';')==string::npos && source.size()>5 && !source.compare(source.size()-5, 5, ".glsl")) { if(RefPtr io = Resources::get_builtins().open(source)) diff --git a/source/glsl/programcompiler.cpp b/source/glsl/compiler.cpp similarity index 79% rename from source/glsl/programcompiler.cpp rename to source/glsl/compiler.cpp index d021ab4f..b862ef20 100644 --- a/source/glsl/programcompiler.cpp +++ b/source/glsl/compiler.cpp @@ -9,9 +9,7 @@ #include #include #include "error.h" -#include "program.h" -#include "programcompiler.h" -#include "resources.h" +#include "compiler.h" #include "shader.h" #undef interface @@ -40,50 +38,49 @@ const char builtins_src[] = namespace Msp { namespace GL { +namespace SL { -using namespace ProgramSyntax; - -ProgramCompiler::ProgramCompiler(): +Compiler::Compiler(): resources(0), module(0) { } -ProgramCompiler::~ProgramCompiler() +Compiler::~Compiler() { delete module; } -void ProgramCompiler::compile(const string &source, const string &src_name) +void Compiler::compile(const string &source, const string &src_name) { resources = 0; delete module; module = new Module(); - ProgramParser parser; + Parser parser; imported_names.push_back(src_name); append_module(parser.parse(source, src_name, 1)); process(); } -void ProgramCompiler::compile(IO::Base &io, Resources *res, const string &src_name) +void Compiler::compile(IO::Base &io, Resources *res, const string &src_name) { resources = res; delete module; module = new Module(); - ProgramParser parser; + Parser parser; imported_names.push_back(src_name); append_module(parser.parse(io, src_name, 1)); process(); } -void ProgramCompiler::compile(IO::Base &io, const string &src_name) +void Compiler::compile(IO::Base &io, const string &src_name) { compile(io, 0, src_name); } -void ProgramCompiler::add_shaders(Program &program) +void Compiler::add_shaders(Program &program) { if(!module) - throw invalid_operation("ProgramCompiler::add_shaders"); + throw invalid_operation("Compiler::add_shaders"); try { @@ -146,9 +143,9 @@ void ProgramCompiler::add_shaders(Program &program) } } -Module *ProgramCompiler::create_builtins_module() +Module *Compiler::create_builtins_module() { - ProgramParser parser; + Parser parser; Module *module = new Module(parser.parse(builtins_src, "")); for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) { @@ -160,13 +157,13 @@ Module *ProgramCompiler::create_builtins_module() return module; } -Module &ProgramCompiler::get_builtins_module() +Module &Compiler::get_builtins_module() { static RefPtr builtins_module = create_builtins_module(); return *builtins_module; } -Stage *ProgramCompiler::get_builtins(StageType type) +Stage *Compiler::get_builtins(StageType type) { Module &module = get_builtins_module(); for(list::iterator i=module.stages.begin(); i!=module.stages.end(); ++i) @@ -175,7 +172,7 @@ Stage *ProgramCompiler::get_builtins(StageType type) return 0; } -void ProgramCompiler::append_module(ProgramSyntax::Module &mod) +void Compiler::append_module(Module &mod) { vector imports = apply >(mod.shared); for(vector::iterator i=imports.begin(); i!=imports.end(); ++i) @@ -187,7 +184,7 @@ void ProgramCompiler::append_module(ProgramSyntax::Module &mod) append_stage(*i); } -void ProgramCompiler::append_stage(Stage &stage) +void Compiler::append_stage(Stage &stage) { Stage *target = 0; if(stage.type==SHARED) @@ -216,7 +213,7 @@ void ProgramCompiler::append_stage(Stage &stage) apply(*target); } -void ProgramCompiler::process() +void Compiler::process() { for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) generate(*i); @@ -231,7 +228,7 @@ void ProgramCompiler::process() finalize(*i); } -void ProgramCompiler::import(const string &name) +void Compiler::import(const string &name) { string fn = name+".glsl"; if(find(imported_names, fn)!=imported_names.end()) @@ -241,11 +238,11 @@ void ProgramCompiler::import(const string &name) RefPtr io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn)); if(!io) throw runtime_error(format("module %s not found", name)); - ProgramParser import_parser; + Parser import_parser; append_module(import_parser.parse(*io, fn, imported_names.size())); } -void ProgramCompiler::generate(Stage &stage) +void Compiler::generate(Stage &stage) { if(module->shared.required_version>stage.required_version) stage.required_version = module->shared.required_version; @@ -261,7 +258,7 @@ void ProgramCompiler::generate(Stage &stage) apply(stage); } -bool ProgramCompiler::optimize(Stage &stage) +bool Compiler::optimize(Stage &stage) { apply(stage); @@ -276,7 +273,7 @@ bool ProgramCompiler::optimize(Stage &stage) return !unused.empty(); } -void ProgramCompiler::finalize(Stage &stage) +void Compiler::finalize(Stage &stage) { if(get_gl_api()==OPENGL_ES2) apply(stage); @@ -284,7 +281,7 @@ void ProgramCompiler::finalize(Stage &stage) apply(stage); } -void ProgramCompiler::inject_block(Block &target, const Block &source) +void Compiler::inject_block(Block &target, const Block &source) { NodeList::iterator insert_point = target.body.begin(); for(NodeList::const_iterator i=source.body.begin(); i!=source.body.end(); ++i) @@ -292,7 +289,7 @@ void ProgramCompiler::inject_block(Block &target, const Block &source) } template -typename T::ResultType ProgramCompiler::apply(Stage &stage) +typename T::ResultType Compiler::apply(Stage &stage) { T visitor; visitor.apply(stage); @@ -300,7 +297,7 @@ typename T::ResultType ProgramCompiler::apply(Stage &stage) } template -typename T::ResultType ProgramCompiler::apply(Stage &stage, const A &arg) +typename T::ResultType Compiler::apply(Stage &stage, const A &arg) { T visitor(arg); visitor.apply(stage); @@ -308,28 +305,28 @@ typename T::ResultType ProgramCompiler::apply(Stage &stage, const A &arg) } -ProgramCompiler::Visitor::Visitor(): +Compiler::Visitor::Visitor(): stage(0) { } -void ProgramCompiler::Visitor::apply(Stage &s) +void Compiler::Visitor::apply(Stage &s) { SetForScope set(stage, &s); stage->content.visit(*this); } -ProgramCompiler::BlockModifier::BlockModifier(): +Compiler::BlockModifier::BlockModifier(): remove_node(false) { } -void ProgramCompiler::BlockModifier::flatten_block(Block &block) +void Compiler::BlockModifier::flatten_block(Block &block) { insert_nodes.insert(insert_nodes.end(), block.body.begin(), block.body.end()); remove_node = true; } -void ProgramCompiler::BlockModifier::apply_and_increment(Block &block, NodeList::iterator &i) +void Compiler::BlockModifier::apply_and_increment(Block &block, NodeList::iterator &i) { block.body.insert(i, insert_nodes.begin(), insert_nodes.end()); insert_nodes.clear(); @@ -341,7 +338,7 @@ void ProgramCompiler::BlockModifier::apply_and_increment(Block &block, NodeList< remove_node = false; } -void ProgramCompiler::BlockModifier::visit(Block &block) +void Compiler::BlockModifier::visit(Block &block) { for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ) { @@ -351,14 +348,14 @@ void ProgramCompiler::BlockModifier::visit(Block &block) } -ProgramCompiler::Formatter::Formatter(): +Compiler::Formatter::Formatter(): source_index(0), source_line(1), indent(0), parameter_list(false) { } -void ProgramCompiler::Formatter::apply(ProgramSyntax::Stage &s) +void Compiler::Formatter::apply(Stage &s) { GLApi api = get_gl_api(); const Version &ver = s.required_version; @@ -379,7 +376,7 @@ void ProgramCompiler::Formatter::apply(ProgramSyntax::Stage &s) Visitor::apply(s); } -void ProgramCompiler::Formatter::append(const string &text) +void Compiler::Formatter::append(const string &text) { formatted += text; for(string::const_iterator i=text.begin(); i!=text.end(); ++i) @@ -387,14 +384,14 @@ void ProgramCompiler::Formatter::append(const string &text) ++source_line; } -void ProgramCompiler::Formatter::append(char c) +void Compiler::Formatter::append(char c) { formatted += c; if(c=='\n') ++source_line; } -void ProgramCompiler::Formatter::set_source(unsigned index, unsigned line) +void Compiler::Formatter::set_source(unsigned index, unsigned line) { if(index!=source_index || (index && line!=source_line)) { @@ -412,30 +409,30 @@ void ProgramCompiler::Formatter::set_source(unsigned index, unsigned line) source_line = line; } -void ProgramCompiler::Formatter::visit(Literal &literal) +void Compiler::Formatter::visit(Literal &literal) { append(literal.token); } -void ProgramCompiler::Formatter::visit(ParenthesizedExpression &parexpr) +void Compiler::Formatter::visit(ParenthesizedExpression &parexpr) { append('('); parexpr.expression->visit(*this); append(')'); } -void ProgramCompiler::Formatter::visit(VariableReference &var) +void Compiler::Formatter::visit(VariableReference &var) { append(var.name); } -void ProgramCompiler::Formatter::visit(MemberAccess &memacc) +void Compiler::Formatter::visit(MemberAccess &memacc) { memacc.left->visit(*this); append(format(".%s", memacc.member)); } -void ProgramCompiler::Formatter::visit(UnaryExpression &unary) +void Compiler::Formatter::visit(UnaryExpression &unary) { if(unary.prefix) append(unary.oper); @@ -444,7 +441,7 @@ void ProgramCompiler::Formatter::visit(UnaryExpression &unary) append(unary.oper); } -void ProgramCompiler::Formatter::visit(BinaryExpression &binary) +void Compiler::Formatter::visit(BinaryExpression &binary) { binary.left->visit(*this); append(binary.oper); @@ -452,14 +449,14 @@ void ProgramCompiler::Formatter::visit(BinaryExpression &binary) append(binary.after); } -void ProgramCompiler::Formatter::visit(Assignment &assign) +void Compiler::Formatter::visit(Assignment &assign) { assign.left->visit(*this); append(format(" %s ", assign.oper)); assign.right->visit(*this); } -void ProgramCompiler::Formatter::visit(FunctionCall &call) +void Compiler::Formatter::visit(FunctionCall &call) { append(format("%s(", call.name)); for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) @@ -471,13 +468,13 @@ void ProgramCompiler::Formatter::visit(FunctionCall &call) append(')'); } -void ProgramCompiler::Formatter::visit(ExpressionStatement &expr) +void Compiler::Formatter::visit(ExpressionStatement &expr) { expr.expression->visit(*this); append(';'); } -void ProgramCompiler::Formatter::visit(Block &block) +void Compiler::Formatter::visit(Block &block) { unsigned brace_indent = indent; bool use_braces = (block.use_braces || (indent && block.body.size()!=1)); @@ -499,17 +496,17 @@ void ProgramCompiler::Formatter::visit(Block &block) append(format("\n%s}", string(brace_indent*2, ' '))); } -void ProgramCompiler::Formatter::visit(Import &import) +void Compiler::Formatter::visit(Import &import) { append(format("import %s;", import.module)); } -void ProgramCompiler::Formatter::visit(Precision &prec) +void Compiler::Formatter::visit(Precision &prec) { append(format("precision %s %s;", prec.precision, prec.type)); } -void ProgramCompiler::Formatter::visit(Layout &layout) +void Compiler::Formatter::visit(Layout &layout) { append("layout("); for(vector::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i) @@ -523,20 +520,20 @@ void ProgramCompiler::Formatter::visit(Layout &layout) append(')'); } -void ProgramCompiler::Formatter::visit(InterfaceLayout &layout) +void Compiler::Formatter::visit(InterfaceLayout &layout) { layout.layout.visit(*this); append(format(" %s;", layout.interface)); } -void ProgramCompiler::Formatter::visit(StructDeclaration &strct) +void Compiler::Formatter::visit(StructDeclaration &strct) { append(format("struct %s\n", strct.name)); strct.members.visit(*this); append(';'); } -void ProgramCompiler::Formatter::visit(VariableDeclaration &var) +void Compiler::Formatter::visit(VariableDeclaration &var) { if(var.layout) { @@ -580,7 +577,7 @@ void ProgramCompiler::Formatter::visit(VariableDeclaration &var) append(';'); } -void ProgramCompiler::Formatter::visit(InterfaceBlock &iface) +void Compiler::Formatter::visit(InterfaceBlock &iface) { SetForScope set(block_interface, iface.interface); append(format("%s %s\n", iface.interface, iface.name)); @@ -588,7 +585,7 @@ void ProgramCompiler::Formatter::visit(InterfaceBlock &iface) append(';'); } -void ProgramCompiler::Formatter::visit(FunctionDeclaration &func) +void Compiler::Formatter::visit(FunctionDeclaration &func) { append(format("%s %s(", func.return_type, func.name)); for(NodeArray::iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) @@ -608,7 +605,7 @@ void ProgramCompiler::Formatter::visit(FunctionDeclaration &func) append(';'); } -void ProgramCompiler::Formatter::visit(Conditional &cond) +void Compiler::Formatter::visit(Conditional &cond) { append("if("); cond.condition->visit(*this); @@ -633,7 +630,7 @@ void ProgramCompiler::Formatter::visit(Conditional &cond) } } -void ProgramCompiler::Formatter::visit(Iteration &iter) +void Compiler::Formatter::visit(Iteration &iter) { if(!iter.init_statement && iter.condition && !iter.loop_expression) { @@ -671,7 +668,7 @@ void ProgramCompiler::Formatter::visit(Iteration &iter) } } -void ProgramCompiler::Formatter::visit(Return &ret) +void Compiler::Formatter::visit(Return &ret) { append("return"); if(ret.expression) @@ -682,18 +679,18 @@ void ProgramCompiler::Formatter::visit(Return &ret) append(';'); } -void ProgramCompiler::Formatter::visit(Jump &jump) +void Compiler::Formatter::visit(Jump &jump) { append(jump.keyword); append(';'); } -ProgramCompiler::DeclarationCombiner::DeclarationCombiner(): +Compiler::DeclarationCombiner::DeclarationCombiner(): toplevel(true) { } -void ProgramCompiler::DeclarationCombiner::visit(Block &block) +void Compiler::DeclarationCombiner::visit(Block &block) { if(!toplevel) return; @@ -702,7 +699,7 @@ void ProgramCompiler::DeclarationCombiner::visit(Block &block) BlockModifier::visit(block); } -void ProgramCompiler::DeclarationCombiner::visit(FunctionDeclaration &func) +void Compiler::DeclarationCombiner::visit(FunctionDeclaration &func) { vector &decls = functions[func.name]; if(func.definition) @@ -716,7 +713,7 @@ void ProgramCompiler::DeclarationCombiner::visit(FunctionDeclaration &func) decls.push_back(&func); } -void ProgramCompiler::DeclarationCombiner::visit(VariableDeclaration &var) +void Compiler::DeclarationCombiner::visit(VariableDeclaration &var) { VariableDeclaration *&ptr = variables[var.name]; if(ptr) @@ -752,14 +749,14 @@ void ProgramCompiler::DeclarationCombiner::visit(VariableDeclaration &var) } -ProgramCompiler::VariableResolver::VariableResolver(): +Compiler::VariableResolver::VariableResolver(): anonymous(false), record_target(false), assignment_target(0), self_referencing(false) { } -void ProgramCompiler::VariableResolver::apply(Stage &s) +void Compiler::VariableResolver::apply(Stage &s) { SetForScope set(stage, &s); Stage *builtins = get_builtins(stage->type); @@ -770,7 +767,7 @@ void ProgramCompiler::VariableResolver::apply(Stage &s) blocks.pop_back(); } -void ProgramCompiler::VariableResolver::visit(Block &block) +void Compiler::VariableResolver::visit(Block &block) { blocks.push_back(&block); block.variables.clear(); @@ -778,7 +775,7 @@ void ProgramCompiler::VariableResolver::visit(Block &block) blocks.pop_back(); } -void ProgramCompiler::VariableResolver::visit(VariableReference &var) +void Compiler::VariableResolver::visit(VariableReference &var) { var.declaration = 0; type = 0; @@ -808,7 +805,7 @@ void ProgramCompiler::VariableResolver::visit(VariableReference &var) self_referencing = true; } -void ProgramCompiler::VariableResolver::visit(MemberAccess &memacc) +void Compiler::VariableResolver::visit(MemberAccess &memacc) { type = 0; TraversingVisitor::visit(memacc); @@ -826,7 +823,7 @@ void ProgramCompiler::VariableResolver::visit(MemberAccess &memacc) } } -void ProgramCompiler::VariableResolver::visit(BinaryExpression &binary) +void Compiler::VariableResolver::visit(BinaryExpression &binary) { if(binary.oper=="[") { @@ -844,7 +841,7 @@ void ProgramCompiler::VariableResolver::visit(BinaryExpression &binary) } } -void ProgramCompiler::VariableResolver::visit(Assignment &assign) +void Compiler::VariableResolver::visit(Assignment &assign) { { SetFlag set(record_target); @@ -859,13 +856,13 @@ void ProgramCompiler::VariableResolver::visit(Assignment &assign) assign.target_declaration = assignment_target; } -void ProgramCompiler::VariableResolver::visit(StructDeclaration &strct) +void Compiler::VariableResolver::visit(StructDeclaration &strct) { TraversingVisitor::visit(strct); blocks.back()->types[strct.name] = &strct; } -void ProgramCompiler::VariableResolver::visit(VariableDeclaration &var) +void Compiler::VariableResolver::visit(VariableDeclaration &var) { for(vector::iterator i=blocks.end(); i!=blocks.begin(); ) { @@ -884,7 +881,7 @@ void ProgramCompiler::VariableResolver::visit(VariableDeclaration &var) blocks[blocks.size()-2]->variables[var.name] = &var; } -void ProgramCompiler::VariableResolver::visit(InterfaceBlock &iface) +void Compiler::VariableResolver::visit(InterfaceBlock &iface) { SetFlag set(anonymous); SetForScope set2(block_interface, iface.interface); @@ -892,7 +889,7 @@ void ProgramCompiler::VariableResolver::visit(InterfaceBlock &iface) } -void ProgramCompiler::FunctionResolver::visit(FunctionCall &call) +void Compiler::FunctionResolver::visit(FunctionCall &call) { map >::iterator i = functions.find(call.name); if(i!=functions.end()) @@ -901,7 +898,7 @@ void ProgramCompiler::FunctionResolver::visit(FunctionCall &call) TraversingVisitor::visit(call); } -void ProgramCompiler::FunctionResolver::visit(FunctionDeclaration &func) +void Compiler::FunctionResolver::visit(FunctionDeclaration &func) { vector &decls = functions[func.name]; if(func.definition) @@ -920,11 +917,11 @@ void ProgramCompiler::FunctionResolver::visit(FunctionDeclaration &func) } -ProgramCompiler::InterfaceGenerator::InterfaceGenerator(): +Compiler::InterfaceGenerator::InterfaceGenerator(): scope_level(0) { } -string ProgramCompiler::InterfaceGenerator::get_out_prefix(StageType type) +string Compiler::InterfaceGenerator::get_out_prefix(StageType type) { if(type==VERTEX) return "_vs_out_"; @@ -934,7 +931,7 @@ string ProgramCompiler::InterfaceGenerator::get_out_prefix(StageType type) return string(); } -void ProgramCompiler::InterfaceGenerator::apply(Stage &s) +void Compiler::InterfaceGenerator::apply(Stage &s) { SetForScope set(stage, &s); if(stage->previous) @@ -943,7 +940,7 @@ void ProgramCompiler::InterfaceGenerator::apply(Stage &s) stage->content.visit(*this); } -void ProgramCompiler::InterfaceGenerator::visit(Block &block) +void Compiler::InterfaceGenerator::visit(Block &block) { SetForScope set(scope_level, scope_level+1); for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ) @@ -964,13 +961,13 @@ void ProgramCompiler::InterfaceGenerator::visit(Block &block) } } -string ProgramCompiler::InterfaceGenerator::change_prefix(const string &name, const string &prefix) const +string Compiler::InterfaceGenerator::change_prefix(const string &name, const string &prefix) const { unsigned offset = (name.compare(0, in_prefix.size(), in_prefix) ? 0 : in_prefix.size()); return prefix+name.substr(offset); } -bool ProgramCompiler::InterfaceGenerator::generate_interface(VariableDeclaration &var, const string &iface, const string &name) +bool Compiler::InterfaceGenerator::generate_interface(VariableDeclaration &var, const string &iface, const string &name) { const map &stage_vars = (iface=="in" ? stage->in_variables : stage->out_variables); if(stage_vars.count(name) || iface_declarations.count(name)) @@ -995,7 +992,7 @@ bool ProgramCompiler::InterfaceGenerator::generate_interface(VariableDeclaration return true; } -ExpressionStatement &ProgramCompiler::InterfaceGenerator::insert_assignment(const string &left, ProgramSyntax::Expression *right) +ExpressionStatement &Compiler::InterfaceGenerator::insert_assignment(const string &left, Expression *right) { Assignment *assign = new Assignment; VariableReference *ref = new VariableReference; @@ -1012,7 +1009,7 @@ ExpressionStatement &ProgramCompiler::InterfaceGenerator::insert_assignment(cons return *stmt; } -void ProgramCompiler::InterfaceGenerator::visit(VariableReference &var) +void Compiler::InterfaceGenerator::visit(VariableReference &var) { if(var.declaration || !stage->previous) return; @@ -1030,7 +1027,7 @@ void ProgramCompiler::InterfaceGenerator::visit(VariableReference &var) } } -void ProgramCompiler::InterfaceGenerator::visit(VariableDeclaration &var) +void Compiler::InterfaceGenerator::visit(VariableDeclaration &var) { if(var.interface=="out") { @@ -1068,7 +1065,7 @@ void ProgramCompiler::InterfaceGenerator::visit(VariableDeclaration &var) TraversingVisitor::visit(var); } -void ProgramCompiler::InterfaceGenerator::visit(Passthrough &pass) +void Compiler::InterfaceGenerator::visit(Passthrough &pass) { vector pass_vars; @@ -1134,12 +1131,12 @@ void ProgramCompiler::InterfaceGenerator::visit(Passthrough &pass) } -ProgramCompiler::DeclarationReorderer::DeclarationReorderer(): +Compiler::DeclarationReorderer::DeclarationReorderer(): scope_level(0), kind(NO_DECLARATION) { } -void ProgramCompiler::DeclarationReorderer::visit(FunctionCall &call) +void Compiler::DeclarationReorderer::visit(FunctionCall &call) { FunctionDeclaration *def = call.declaration; if(def) @@ -1148,7 +1145,7 @@ void ProgramCompiler::DeclarationReorderer::visit(FunctionCall &call) needed_funcs.insert(def); } -void ProgramCompiler::DeclarationReorderer::visit(Block &block) +void Compiler::DeclarationReorderer::visit(Block &block) { SetForScope set(scope_level, scope_level+1); if(scope_level>1) @@ -1226,13 +1223,13 @@ void ProgramCompiler::DeclarationReorderer::visit(Block &block) } } -void ProgramCompiler::DeclarationReorderer::visit(ProgramSyntax::VariableDeclaration &var) +void Compiler::DeclarationReorderer::visit(VariableDeclaration &var) { Visitor::visit(var); kind = VARIABLE; } -void ProgramCompiler::DeclarationReorderer::visit(FunctionDeclaration &func) +void Compiler::DeclarationReorderer::visit(FunctionDeclaration &func) { needed_funcs.clear(); func.body.visit(*this); @@ -1241,11 +1238,11 @@ void ProgramCompiler::DeclarationReorderer::visit(FunctionDeclaration &func) } -ProgramCompiler::InlineableFunctionLocator::InlineableFunctionLocator(): +Compiler::InlineableFunctionLocator::InlineableFunctionLocator(): in_function(0) { } -void ProgramCompiler::InlineableFunctionLocator::visit(FunctionCall &call) +void Compiler::InlineableFunctionLocator::visit(FunctionCall &call) { FunctionDeclaration *def = call.declaration; if(def && def->definition!=def) @@ -1262,7 +1259,7 @@ void ProgramCompiler::InlineableFunctionLocator::visit(FunctionCall &call) TraversingVisitor::visit(call); } -void ProgramCompiler::InlineableFunctionLocator::visit(FunctionDeclaration &func) +void Compiler::InlineableFunctionLocator::visit(FunctionDeclaration &func) { unsigned &count = refcounts[func.definition]; if(!count && func.parameters.empty()) @@ -1273,16 +1270,16 @@ void ProgramCompiler::InlineableFunctionLocator::visit(FunctionDeclaration &func } -ProgramCompiler::FunctionInliner::FunctionInliner(): +Compiler::FunctionInliner::FunctionInliner(): extract_result(0) { } -ProgramCompiler::FunctionInliner::FunctionInliner(const set &in): +Compiler::FunctionInliner::FunctionInliner(const set &in): inlineable(in), extract_result(0) { } -void ProgramCompiler::FunctionInliner::visit_and_inline(RefPtr &ptr) +void Compiler::FunctionInliner::visit_and_inline(RefPtr &ptr) { inline_result = 0; ptr->visit(*this); @@ -1290,7 +1287,7 @@ void ProgramCompiler::FunctionInliner::visit_and_inline(RefPtr &ptr) ptr = inline_result; } -void ProgramCompiler::FunctionInliner::visit(Block &block) +void Compiler::FunctionInliner::visit(Block &block) { if(extract_result) --extract_result; @@ -1303,26 +1300,26 @@ void ProgramCompiler::FunctionInliner::visit(Block &block) } } -void ProgramCompiler::FunctionInliner::visit(UnaryExpression &unary) +void Compiler::FunctionInliner::visit(UnaryExpression &unary) { visit_and_inline(unary.expression); inline_result = 0; } -void ProgramCompiler::FunctionInliner::visit(BinaryExpression &binary) +void Compiler::FunctionInliner::visit(BinaryExpression &binary) { visit_and_inline(binary.left); visit_and_inline(binary.right); inline_result = 0; } -void ProgramCompiler::FunctionInliner::visit(MemberAccess &memacc) +void Compiler::FunctionInliner::visit(MemberAccess &memacc) { visit_and_inline(memacc.left); inline_result = 0; } -void ProgramCompiler::FunctionInliner::visit(FunctionCall &call) +void Compiler::FunctionInliner::visit(FunctionCall &call) { for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) visit_and_inline(*i); @@ -1340,14 +1337,14 @@ void ProgramCompiler::FunctionInliner::visit(FunctionCall &call) inline_result = 0; } -void ProgramCompiler::FunctionInliner::visit(VariableDeclaration &var) +void Compiler::FunctionInliner::visit(VariableDeclaration &var) { if(var.init_expression) visit_and_inline(var.init_expression); inline_result = 0; } -void ProgramCompiler::FunctionInliner::visit(Return &ret) +void Compiler::FunctionInliner::visit(Return &ret) { TraversingVisitor::visit(ret); @@ -1356,19 +1353,19 @@ void ProgramCompiler::FunctionInliner::visit(Return &ret) } -ProgramCompiler::ExpressionEvaluator::ExpressionEvaluator(): +Compiler::ExpressionEvaluator::ExpressionEvaluator(): variable_values(0), result(0.0f), result_valid(false) { } -ProgramCompiler::ExpressionEvaluator::ExpressionEvaluator(const ValueMap &v): +Compiler::ExpressionEvaluator::ExpressionEvaluator(const ValueMap &v): variable_values(&v), result(0.0f), result_valid(false) { } -void ProgramCompiler::ExpressionEvaluator::visit(Literal &literal) +void Compiler::ExpressionEvaluator::visit(Literal &literal) { if(literal.token=="true") result = 1.0f; @@ -1379,12 +1376,12 @@ void ProgramCompiler::ExpressionEvaluator::visit(Literal &literal) result_valid = true; } -void ProgramCompiler::ExpressionEvaluator::visit(ParenthesizedExpression &parexp) +void Compiler::ExpressionEvaluator::visit(ParenthesizedExpression &parexp) { parexp.expression->visit(*this); } -void ProgramCompiler::ExpressionEvaluator::visit(VariableReference &var) +void Compiler::ExpressionEvaluator::visit(VariableReference &var) { if(!var.declaration) return; @@ -1399,7 +1396,7 @@ void ProgramCompiler::ExpressionEvaluator::visit(VariableReference &var) var.declaration->init_expression->visit(*this); } -void ProgramCompiler::ExpressionEvaluator::visit(UnaryExpression &unary) +void Compiler::ExpressionEvaluator::visit(UnaryExpression &unary) { result_valid = false; unary.expression->visit(*this); @@ -1412,7 +1409,7 @@ void ProgramCompiler::ExpressionEvaluator::visit(UnaryExpression &unary) result_valid = false; } -void ProgramCompiler::ExpressionEvaluator::visit(BinaryExpression &binary) +void Compiler::ExpressionEvaluator::visit(BinaryExpression &binary) { result_valid = false; binary.left->visit(*this); @@ -1446,12 +1443,12 @@ void ProgramCompiler::ExpressionEvaluator::visit(BinaryExpression &binary) } -ProgramCompiler::ConstantConditionEliminator::ConstantConditionEliminator(): +Compiler::ConstantConditionEliminator::ConstantConditionEliminator(): scope_level(0), record_only(false) { } -void ProgramCompiler::ConstantConditionEliminator::visit(Block &block) +void Compiler::ConstantConditionEliminator::visit(Block &block) { SetForScope set(scope_level, scope_level+1); BlockModifier::visit(block); @@ -1460,25 +1457,25 @@ void ProgramCompiler::ConstantConditionEliminator::visit(Block &block) variable_values.erase(i->second); } -void ProgramCompiler::ConstantConditionEliminator::visit(UnaryExpression &unary) +void Compiler::ConstantConditionEliminator::visit(UnaryExpression &unary) { if(VariableReference *var = dynamic_cast(unary.expression.get())) if(unary.oper=="++" || unary.oper=="--") variable_values.erase(var->declaration); } -void ProgramCompiler::ConstantConditionEliminator::visit(Assignment &assign) +void Compiler::ConstantConditionEliminator::visit(Assignment &assign) { variable_values.erase(assign.target_declaration); } -void ProgramCompiler::ConstantConditionEliminator::visit(VariableDeclaration &var) +void Compiler::ConstantConditionEliminator::visit(VariableDeclaration &var) { if(var.constant || scope_level>1) variable_values[&var] = var.init_expression.get(); } -void ProgramCompiler::ConstantConditionEliminator::visit(Conditional &cond) +void Compiler::ConstantConditionEliminator::visit(Conditional &cond) { if(!record_only) { @@ -1494,7 +1491,7 @@ void ProgramCompiler::ConstantConditionEliminator::visit(Conditional &cond) TraversingVisitor::visit(cond); } -void ProgramCompiler::ConstantConditionEliminator::visit(Iteration &iter) +void Compiler::ConstantConditionEliminator::visit(Iteration &iter) { if(!record_only) { @@ -1526,7 +1523,7 @@ void ProgramCompiler::ConstantConditionEliminator::visit(Iteration &iter) } -ProgramCompiler::UnusedVariableLocator::UnusedVariableLocator(): +Compiler::UnusedVariableLocator::UnusedVariableLocator(): aggregate(0), assignment(0), assignment_target(false), @@ -1534,7 +1531,7 @@ ProgramCompiler::UnusedVariableLocator::UnusedVariableLocator(): global_scope(true) { } -void ProgramCompiler::UnusedVariableLocator::apply(Stage &s) +void Compiler::UnusedVariableLocator::apply(Stage &s) { variables.push_back(BlockVariableMap()); Visitor::apply(s); @@ -1552,7 +1549,7 @@ void ProgramCompiler::UnusedVariableLocator::apply(Stage &s) variables.pop_back(); } -void ProgramCompiler::UnusedVariableLocator::visit(VariableReference &var) +void Compiler::UnusedVariableLocator::visit(VariableReference &var) { map::iterator i = aggregates.find(var.declaration); if(i!=aggregates.end()) @@ -1566,13 +1563,13 @@ void ProgramCompiler::UnusedVariableLocator::visit(VariableReference &var) } } -void ProgramCompiler::UnusedVariableLocator::visit(MemberAccess &memacc) +void Compiler::UnusedVariableLocator::visit(MemberAccess &memacc) { TraversingVisitor::visit(memacc); unused_nodes.erase(memacc.declaration); } -void ProgramCompiler::UnusedVariableLocator::visit(BinaryExpression &binary) +void Compiler::UnusedVariableLocator::visit(BinaryExpression &binary) { if(binary.oper=="[") { @@ -1586,7 +1583,7 @@ void ProgramCompiler::UnusedVariableLocator::visit(BinaryExpression &binary) TraversingVisitor::visit(binary); } -void ProgramCompiler::UnusedVariableLocator::visit(Assignment &assign) +void Compiler::UnusedVariableLocator::visit(Assignment &assign) { { assign_to_subscript = false; @@ -1597,7 +1594,7 @@ void ProgramCompiler::UnusedVariableLocator::visit(Assignment &assign) assignment = &assign; } -void ProgramCompiler::UnusedVariableLocator::record_assignment(VariableDeclaration &var, Node &node, bool chained) +void Compiler::UnusedVariableLocator::record_assignment(VariableDeclaration &var, Node &node, bool chained) { VariableInfo &var_info = variables.back()[&var]; if(!chained) @@ -1606,7 +1603,7 @@ void ProgramCompiler::UnusedVariableLocator::record_assignment(VariableDeclarati var_info.conditionally_assigned = false; } -void ProgramCompiler::UnusedVariableLocator::clear_assignments(VariableInfo &var_info, bool mark_unused) +void Compiler::UnusedVariableLocator::clear_assignments(VariableInfo &var_info, bool mark_unused) { if(mark_unused) { @@ -1616,7 +1613,7 @@ void ProgramCompiler::UnusedVariableLocator::clear_assignments(VariableInfo &var var_info.assignments.clear(); } -void ProgramCompiler::UnusedVariableLocator::visit(ExpressionStatement &expr) +void Compiler::UnusedVariableLocator::visit(ExpressionStatement &expr) { assignment = 0; TraversingVisitor::visit(expr); @@ -1624,14 +1621,14 @@ void ProgramCompiler::UnusedVariableLocator::visit(ExpressionStatement &expr) record_assignment(*assignment->target_declaration, expr, (assignment->self_referencing || assign_to_subscript)); } -void ProgramCompiler::UnusedVariableLocator::visit(StructDeclaration &strct) +void Compiler::UnusedVariableLocator::visit(StructDeclaration &strct) { SetForScope set(aggregate, &strct); unused_nodes.insert(&strct); TraversingVisitor::visit(strct); } -void ProgramCompiler::UnusedVariableLocator::visit(VariableDeclaration &var) +void Compiler::UnusedVariableLocator::visit(VariableDeclaration &var) { if(aggregate) aggregates[&var] = aggregate; @@ -1645,14 +1642,14 @@ void ProgramCompiler::UnusedVariableLocator::visit(VariableDeclaration &var) TraversingVisitor::visit(var); } -void ProgramCompiler::UnusedVariableLocator::visit(InterfaceBlock &iface) +void Compiler::UnusedVariableLocator::visit(InterfaceBlock &iface) { SetForScope set(aggregate, &iface); unused_nodes.insert(&iface); TraversingVisitor::visit(iface); } -void ProgramCompiler::UnusedVariableLocator::visit(FunctionDeclaration &func) +void Compiler::UnusedVariableLocator::visit(FunctionDeclaration &func) { variables.push_back(BlockVariableMap()); @@ -1671,7 +1668,7 @@ void ProgramCompiler::UnusedVariableLocator::visit(FunctionDeclaration &func) merge_down_variables(); } -void ProgramCompiler::UnusedVariableLocator::merge_down_variables() +void Compiler::UnusedVariableLocator::merge_down_variables() { BlockVariableMap &parent_variables = variables[variables.size()-2]; BlockVariableMap &block_variables = variables.back(); @@ -1700,7 +1697,7 @@ void ProgramCompiler::UnusedVariableLocator::merge_down_variables() variables.pop_back(); } -void ProgramCompiler::UnusedVariableLocator::visit(Conditional &cond) +void Compiler::UnusedVariableLocator::visit(Conditional &cond) { cond.condition->visit(*this); variables.push_back(BlockVariableMap()); @@ -1733,7 +1730,7 @@ void ProgramCompiler::UnusedVariableLocator::visit(Conditional &cond) merge_down_variables(); } -void ProgramCompiler::UnusedVariableLocator::visit(Iteration &iter) +void Compiler::UnusedVariableLocator::visit(Iteration &iter) { variables.push_back(BlockVariableMap()); TraversingVisitor::visit(iter); @@ -1747,14 +1744,14 @@ void ProgramCompiler::UnusedVariableLocator::visit(Iteration &iter) } -ProgramCompiler::UnusedVariableLocator::VariableInfo::VariableInfo(): +Compiler::UnusedVariableLocator::VariableInfo::VariableInfo(): local(false), conditionally_assigned(false), referenced(false) { } -void ProgramCompiler::UnusedFunctionLocator::visit(FunctionCall &call) +void Compiler::UnusedFunctionLocator::visit(FunctionCall &call) { TraversingVisitor::visit(call); @@ -1763,7 +1760,7 @@ void ProgramCompiler::UnusedFunctionLocator::visit(FunctionCall &call) used_definitions.insert(call.declaration->definition); } -void ProgramCompiler::UnusedFunctionLocator::visit(FunctionDeclaration &func) +void Compiler::UnusedFunctionLocator::visit(FunctionDeclaration &func) { TraversingVisitor::visit(func); @@ -1772,11 +1769,11 @@ void ProgramCompiler::UnusedFunctionLocator::visit(FunctionDeclaration &func) } -ProgramCompiler::NodeRemover::NodeRemover(const set &r): +Compiler::NodeRemover::NodeRemover(const set &r): to_remove(r) { } -void ProgramCompiler::NodeRemover::visit(Block &block) +void Compiler::NodeRemover::visit(Block &block) { for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ) { @@ -1788,7 +1785,7 @@ void ProgramCompiler::NodeRemover::visit(Block &block) } } -void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var) +void Compiler::NodeRemover::visit(VariableDeclaration &var) { if(to_remove.count(&var)) { @@ -1802,7 +1799,7 @@ void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var) var.init_expression = 0; } -void ProgramCompiler::NodeRemover::visit(Iteration &iter) +void Compiler::NodeRemover::visit(Iteration &iter) { if(to_remove.count(iter.init_statement.get())) iter.init_statement = 0; @@ -1810,22 +1807,22 @@ void ProgramCompiler::NodeRemover::visit(Iteration &iter) } -void ProgramCompiler::PrecisionRemover::visit(Precision &) +void Compiler::PrecisionRemover::visit(Precision &) { remove_node = true; } -void ProgramCompiler::PrecisionRemover::visit(VariableDeclaration &var) +void Compiler::PrecisionRemover::visit(VariableDeclaration &var) { var.precision.clear(); } -ProgramCompiler::DefaultPrecisionGenerator::DefaultPrecisionGenerator(): +Compiler::DefaultPrecisionGenerator::DefaultPrecisionGenerator(): toplevel(true) { } -void ProgramCompiler::DefaultPrecisionGenerator::visit(Block &block) +void Compiler::DefaultPrecisionGenerator::visit(Block &block) { if(toplevel) { @@ -1836,12 +1833,12 @@ void ProgramCompiler::DefaultPrecisionGenerator::visit(Block &block) Visitor::visit(block); } -void ProgramCompiler::DefaultPrecisionGenerator::visit(Precision &prec) +void Compiler::DefaultPrecisionGenerator::visit(Precision &prec) { have_default.insert(prec.type); } -void ProgramCompiler::DefaultPrecisionGenerator::visit(VariableDeclaration &var) +void Compiler::DefaultPrecisionGenerator::visit(VariableDeclaration &var) { if(var.type_declaration) return; @@ -1869,19 +1866,19 @@ void ProgramCompiler::DefaultPrecisionGenerator::visit(VariableDeclaration &var) } -ProgramCompiler::LegacyConverter::LegacyConverter(): +Compiler::LegacyConverter::LegacyConverter(): target_api(get_gl_api()), target_version(get_glsl_version()), frag_out(0) { } -ProgramCompiler::LegacyConverter::LegacyConverter(const Version &v): +Compiler::LegacyConverter::LegacyConverter(const Version &v): target_api(get_gl_api()), target_version(v), frag_out(0) { } -bool ProgramCompiler::LegacyConverter::check_version(const Version &feature_version) const +bool Compiler::LegacyConverter::check_version(const Version &feature_version) const { if(target_version +#include "parser.h" +#include "program.h" +#include "resources.h" +#include "syntax.h" + +namespace Msp { +namespace GL { +namespace SL { + +class Compiler +{ +private: + struct Visitor: TraversingVisitor + { + typedef void ResultType; + + Stage *stage; + + Visitor(); + + virtual void apply(Stage &); + void get_result() const { } + }; + + struct BlockModifier: Visitor + { + bool remove_node; + std::vector > insert_nodes; + + BlockModifier(); + + void flatten_block(Block &); + void apply_and_increment(Block &, NodeList::iterator &); + using Visitor::visit; + virtual void visit(Block &); + }; + + struct Formatter: Visitor + { + typedef std::string ResultType; + + std::string formatted; + unsigned source_index; + unsigned source_line; + unsigned indent; + bool parameter_list; + std::string block_interface; + + Formatter(); + + virtual void apply(Stage &); + const std::string &get_result() const { return formatted; } + using Visitor::visit; + void append(const std::string &); + void append(char); + void set_source(unsigned, unsigned); + virtual void visit(Block &); + virtual void visit(Literal &); + virtual void visit(ParenthesizedExpression &); + virtual void visit(VariableReference &); + virtual void visit(MemberAccess &); + virtual void visit(UnaryExpression &); + virtual void visit(BinaryExpression &); + virtual void visit(Assignment &); + virtual void visit(FunctionCall &); + virtual void visit(ExpressionStatement &); + virtual void visit(Import &); + virtual void visit(Precision &); + virtual void visit(Layout &); + virtual void visit(InterfaceLayout &); + virtual void visit(StructDeclaration &); + virtual void visit(VariableDeclaration &); + virtual void visit(InterfaceBlock &); + virtual void visit(FunctionDeclaration &); + virtual void visit(Conditional &); + virtual void visit(Iteration &); + virtual void visit(Return &); + virtual void visit(Jump &); + }; + + template + struct NodeGatherer: Visitor + { + typedef std::vector ResultType; + + std::vector nodes; + + const ResultType &get_result() const { return nodes; } + using Visitor::visit; + virtual void visit(T &n) { nodes.push_back(&n); } + }; + + struct DeclarationCombiner: BlockModifier + { + bool toplevel; + std::map > functions; + std::map variables; + + DeclarationCombiner(); + + using Visitor::visit; + virtual void visit(Block &); + virtual void visit(FunctionDeclaration &); + virtual void visit(VariableDeclaration &); + }; + + struct VariableResolver: Visitor + { + std::vector blocks; + StructDeclaration *type; + bool anonymous; + std::string block_interface; + bool record_target; + VariableDeclaration *assignment_target; + bool self_referencing; + + VariableResolver(); + + virtual void apply(Stage &); + using Visitor::visit; + virtual void visit(Block &); + virtual void visit(VariableReference &); + virtual void visit(MemberAccess &); + virtual void visit(BinaryExpression &); + virtual void visit(Assignment &); + virtual void visit(StructDeclaration &); + virtual void visit(VariableDeclaration &); + virtual void visit(InterfaceBlock &); + }; + + struct FunctionResolver: Visitor + { + std::map > functions; + + using Visitor::visit; + virtual void visit(FunctionCall &); + virtual void visit(FunctionDeclaration &); + }; + + struct InterfaceGenerator: BlockModifier + { + std::string in_prefix; + std::string out_prefix; + unsigned scope_level; + std::map > iface_declarations; + + InterfaceGenerator(); + + static std::string get_out_prefix(StageType); + virtual void apply(Stage &); + using Visitor::visit; + virtual void visit(Block &); + std::string change_prefix(const std::string &, const std::string &) const; + bool generate_interface(VariableDeclaration &, const std::string &, const std::string &); + ExpressionStatement &insert_assignment(const std::string &, Expression *); + virtual void visit(VariableReference &); + virtual void visit(VariableDeclaration &); + virtual void visit(Passthrough &); + }; + + struct DeclarationReorderer: Visitor + { + enum DeclarationKind + { + NO_DECLARATION, + LAYOUT, + STRUCT, + VARIABLE, + FUNCTION + }; + + unsigned scope_level; + DeclarationKind kind; + std::set ordered_funcs; + std::set needed_funcs; + + DeclarationReorderer(); + + using Visitor::visit; + virtual void visit(Block &); + virtual void visit(FunctionCall &); + virtual void visit(InterfaceLayout &) { kind = LAYOUT; } + virtual void visit(StructDeclaration &) { kind = STRUCT; } + virtual void visit(VariableDeclaration &); + virtual void visit(InterfaceBlock &) { kind = VARIABLE; } + virtual void visit(FunctionDeclaration &); + }; + + struct InlineableFunctionLocator: Visitor + { + typedef std::set ResultType; + + std::map refcounts; + std::set inlineable; + FunctionDeclaration *in_function; + + InlineableFunctionLocator(); + + const ResultType &get_result() const { return inlineable; } + using Visitor::visit; + virtual void visit(FunctionCall &); + virtual void visit(FunctionDeclaration &); + }; + + struct FunctionInliner: Visitor + { + std::set inlineable; + unsigned extract_result; + RefPtr inline_result; + + FunctionInliner(); + FunctionInliner(const std::set &); + + void visit_and_inline(RefPtr &); + using Visitor::visit; + virtual void visit(Block &); + virtual void visit(UnaryExpression &); + virtual void visit(BinaryExpression &); + virtual void visit(MemberAccess &); + virtual void visit(FunctionCall &); + virtual void visit(VariableDeclaration &); + virtual void visit(Return &); + }; + + struct ExpressionEvaluator: NodeVisitor + { + typedef std::map ValueMap; + + const ValueMap *variable_values; + float result; + bool result_valid; + + ExpressionEvaluator(); + ExpressionEvaluator(const ValueMap &); + + using NodeVisitor::visit; + virtual void visit(Literal &); + virtual void visit(ParenthesizedExpression &); + virtual void visit(VariableReference &); + virtual void visit(UnaryExpression &); + virtual void visit(BinaryExpression &); + }; + + struct ConstantConditionEliminator: BlockModifier + { + unsigned scope_level; + bool record_only; + ExpressionEvaluator::ValueMap variable_values; + + ConstantConditionEliminator(); + + using Visitor::visit; + virtual void visit(Block &); + virtual void visit(UnaryExpression &); + virtual void visit(Assignment &); + virtual void visit(VariableDeclaration &); + virtual void visit(Conditional &); + virtual void visit(Iteration &); + }; + + struct UnusedVariableLocator: Visitor + { + struct VariableInfo + { + bool local; + std::vector assignments; + bool conditionally_assigned; + bool referenced; + + VariableInfo(); + }; + + typedef std::set ResultType; + typedef std::map BlockVariableMap; + + std::set unused_nodes; + std::map aggregates; + Node *aggregate; + std::vector variables; + Assignment *assignment; + bool assignment_target; + bool assign_to_subscript; + bool global_scope; + + UnusedVariableLocator(); + + virtual void apply(Stage &); + const ResultType &get_result() const { return unused_nodes; } + using Visitor::visit; + virtual void visit(VariableReference &); + virtual void visit(MemberAccess &); + virtual void visit(BinaryExpression &); + virtual void visit(Assignment &); + void record_assignment(VariableDeclaration &, Node &, bool); + void clear_assignments(VariableInfo &, bool); + virtual void visit(ExpressionStatement &); + virtual void visit(StructDeclaration &); + virtual void visit(VariableDeclaration &); + virtual void visit(InterfaceBlock &); + virtual void visit(FunctionDeclaration &); + void merge_down_variables(); + virtual void visit(Conditional &); + virtual void visit(Iteration &); + }; + + struct UnusedFunctionLocator: Visitor + { + typedef std::set ResultType; + + std::set unused_nodes; + std::set used_definitions; + + const ResultType &get_result() const { return unused_nodes; } + using Visitor::visit; + virtual void visit(FunctionCall &); + virtual void visit(FunctionDeclaration &); + }; + + struct NodeRemover: Visitor + { + std::set to_remove; + + NodeRemover() { } + NodeRemover(const std::set &); + + using Visitor::visit; + virtual void visit(Block &); + virtual void visit(VariableDeclaration &); + virtual void visit(Iteration &); + }; + + struct PrecisionRemover: BlockModifier + { + using Visitor::visit; + virtual void visit(Precision &); + virtual void visit(VariableDeclaration &); + }; + + struct DefaultPrecisionGenerator: BlockModifier + { + bool toplevel; + std::set have_default; + + DefaultPrecisionGenerator(); + + using Visitor::visit; + virtual void visit(Block &); + virtual void visit(Precision &); + virtual void visit(VariableDeclaration &); + }; + + struct LegacyConverter: BlockModifier + { + GLApi target_api; + Version target_version; + std::string type; + VariableDeclaration *frag_out; + + LegacyConverter(); + LegacyConverter(const Version &); + + bool check_version(const Version &) const; + bool check_extension(const Extension &) const; + using Visitor::visit; + bool supports_unified_interface_syntax() const; + virtual void visit(VariableReference &); + virtual void visit(Assignment &); + bool supports_unified_sampling_functions() const; + virtual void visit(FunctionCall &); + bool supports_interface_layouts() const; + bool supports_centroid_sampling() const; + bool supports_sample_sampling() const; + virtual void visit(VariableDeclaration &); + bool supports_interface_blocks(const std::string &) const; + virtual void visit(InterfaceBlock &); + }; + + Resources *resources; + Module *module; + std::vector imported_names; + +public: + Compiler(); + ~Compiler(); + + void compile(const std::string &, const std::string & = ""); + void compile(IO::Base &, Resources * = 0, const std::string & = ""); + void compile(IO::Base &, const std::string &); + void add_shaders(Program &); + +private: + static Module *create_builtins_module(); + static Module &get_builtins_module(); + static Stage *get_builtins(StageType); + void append_module(Module &); + void append_stage(Stage &); + void process(); + void import(const std::string &); + void generate(Stage &); + bool optimize(Stage &); + void finalize(Stage &); + static void inject_block(Block &, const Block &); + template + static typename T::ResultType apply(Stage &); + template + static typename T::ResultType apply(Stage &, const A &); +}; + +} // namespace SL +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/glsl/programparser.cpp b/source/glsl/parser.cpp similarity index 87% rename from source/glsl/programparser.cpp rename to source/glsl/parser.cpp index 83a2879f..d55cdab3 100644 --- a/source/glsl/programparser.cpp +++ b/source/glsl/parser.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "programparser.h" +#include "parser.h" #undef interface @@ -9,10 +9,9 @@ using namespace std; namespace Msp { namespace GL { +namespace SL { -using namespace ProgramSyntax; - -ProgramParser::Operator ProgramParser::operators[] = +Parser::Operator Parser::operators[] = { { "[", 2, BINARY, LEFT_TO_RIGHT }, { "(", 2, BINARY, LEFT_TO_RIGHT }, @@ -61,16 +60,16 @@ ProgramParser::Operator ProgramParser::operators[] = { { 0 }, 18, NO_OPERATOR, LEFT_TO_RIGHT } }; -ProgramParser::ProgramParser(): +Parser::Parser(): module(0) { } -ProgramParser::~ProgramParser() +Parser::~Parser() { delete module; } -Module &ProgramParser::parse(const string &s, const string &n, unsigned i) +Module &Parser::parse(const string &s, const string &n, unsigned i) { source = s; source_name = n; @@ -79,7 +78,7 @@ Module &ProgramParser::parse(const string &s, const string &n, unsigned i) return *module; } -Module &ProgramParser::parse(IO::Base &io, const string &n, unsigned i) +Module &Parser::parse(IO::Base &io, const string &n, unsigned i) { source = string(); source_name = n; @@ -94,7 +93,7 @@ Module &ProgramParser::parse(IO::Base &io, const string &n, unsigned i) return *module; } -void ProgramParser::parse_source() +void Parser::parse_source() { while(1) { @@ -118,25 +117,25 @@ void ProgramParser::parse_source() cur_stage->content.body.push_back(statement); } -string ProgramParser::format_error(const std::string &message) +string Parser::format_error(const std::string &message) { string location = format("%s:%d: ", source_name, current_line); return location+message; } -string ProgramParser::format_syntax_error(const std::string &expected) +string Parser::format_syntax_error(const std::string &expected) { return format_error(format("Syntax error at '%s': expected %s", last_token, expected)); } -const string &ProgramParser::peek_token(unsigned index) +const string &Parser::peek_token(unsigned index) { while(next_tokens.size()<=index) next_tokens.push_back(parse_token_()); return (last_token = next_tokens[index]); } -const string &ProgramParser::parse_token() +const string &Parser::parse_token() { if(!next_tokens.empty()) { @@ -148,7 +147,7 @@ const string &ProgramParser::parse_token() return (last_token = parse_token_()); } -string ProgramParser::parse_token_() +string Parser::parse_token_() { while(1) { @@ -170,7 +169,7 @@ string ProgramParser::parse_token_() } } -string ProgramParser::parse_identifier() +string Parser::parse_identifier() { string ident; while(iter!=source_end) @@ -184,7 +183,7 @@ string ProgramParser::parse_identifier() return ident; } -string ProgramParser::parse_number() +string Parser::parse_number() { bool accept_sign = false; string number; @@ -206,7 +205,7 @@ string ProgramParser::parse_number() return number; } -string ProgramParser::parse_other() +string Parser::parse_other() { if(iter==source_end) return string(); @@ -231,7 +230,7 @@ string ProgramParser::parse_other() return token; } -void ProgramParser::skip_comment_and_whitespace() +void Parser::skip_comment_and_whitespace() { unsigned comment = 0; while(iter!=source_end) @@ -281,14 +280,14 @@ void ProgramParser::skip_comment_and_whitespace() } } -void ProgramParser::expect(const string &token) +void Parser::expect(const string &token) { string parsed = parse_token(); if(parsed!=token) throw runtime_error(format_syntax_error(format("'%s'", token))); } -string ProgramParser::expect_type() +string Parser::expect_type() { string token = parse_token(); if(!is_type(token)) @@ -296,7 +295,7 @@ string ProgramParser::expect_type() return token; } -string ProgramParser::expect_identifier() +string Parser::expect_identifier() { string token = parse_token(); if(!is_identifier(token)) @@ -304,7 +303,7 @@ string ProgramParser::expect_identifier() return token; } -bool ProgramParser::check(const string &token) +bool Parser::check(const string &token) { bool result = (peek_token()==token); if(result) @@ -312,27 +311,27 @@ bool ProgramParser::check(const string &token) return result; } -bool ProgramParser::is_interface_qualifier(const string &token) +bool Parser::is_interface_qualifier(const string &token) { return (token=="uniform" || token=="in" || token=="out"); } -bool ProgramParser::is_sampling_qualifier(const string &token) +bool Parser::is_sampling_qualifier(const string &token) { return (token=="centroid" || token=="sample"); } -bool ProgramParser::is_interpolation_qualifier(const string &token) +bool Parser::is_interpolation_qualifier(const string &token) { return (token=="smooth" || token=="flat" || token=="noperspective"); } -bool ProgramParser::is_precision_qualifier(const string &token) +bool Parser::is_precision_qualifier(const string &token) { return (token=="highp" || token=="mediump" || token=="lowp"); } -bool ProgramParser::is_qualifier(const string &token) +bool Parser::is_qualifier(const string &token) { return (token=="const" || is_interface_qualifier(token) || @@ -341,24 +340,24 @@ bool ProgramParser::is_qualifier(const string &token) is_precision_qualifier(token)); } -bool ProgramParser::is_builtin_type(const string &token) +bool Parser::is_builtin_type(const string &token) { static Regex re("^(void|float|int|bool|[ib]?vec[234]|mat[234](x[234])?|sampler((1D|2D|Cube)(Array)?(Shadow)?|3D))$"); return re.match(token); } -bool ProgramParser::is_type(const string &token) +bool Parser::is_type(const string &token) { return is_builtin_type(token) || declared_types.count(token); } -bool ProgramParser::is_identifier(const string &token) +bool Parser::is_identifier(const string &token) { static Regex re("^[a-zA-Z_][a-zA-Z0-9_]*$"); return re.match(token); } -void ProgramParser::preprocess() +void Parser::preprocess() { expect("#"); @@ -380,7 +379,7 @@ void ProgramParser::preprocess() iter = line_end; } -void ProgramParser::preprocess_version() +void Parser::preprocess_version() { expect("version"); string token = parse_token(); @@ -392,7 +391,7 @@ void ProgramParser::preprocess_version() throw runtime_error(format_syntax_error("end of line")); } -void ProgramParser::preprocess_pragma() +void Parser::preprocess_pragma() { expect("pragma"); string token = parse_token(); @@ -400,7 +399,7 @@ void ProgramParser::preprocess_pragma() preprocess_pragma_msp(); } -void ProgramParser::preprocess_pragma_msp() +void Parser::preprocess_pragma_msp() { string token = peek_token(); if(token=="stage") @@ -413,7 +412,7 @@ void ProgramParser::preprocess_pragma_msp() throw runtime_error(format_syntax_error("end of line")); } -void ProgramParser::preprocess_stage() +void Parser::preprocess_stage() { if(!allow_stage_change) throw runtime_error(format_error("Changing stage not allowed here")); @@ -442,7 +441,7 @@ void ProgramParser::preprocess_stage() cur_stage = &module->stages.back(); } -RefPtr ProgramParser::parse_global_declaration() +RefPtr Parser::parse_global_declaration() { allow_stage_change = true; string token = peek_token(); @@ -498,7 +497,7 @@ RefPtr ProgramParser::parse_global_declaration() throw runtime_error(format_syntax_error("a global declaration")); } -RefPtr ProgramParser::parse_statement() +RefPtr Parser::parse_statement() { string token = peek_token(); if(token=="if") @@ -537,7 +536,7 @@ RefPtr ProgramParser::parse_statement() throw runtime_error(format_syntax_error("a statement")); } -RefPtr ProgramParser::parse_import() +RefPtr Parser::parse_import() { if(cur_stage->type!=SHARED) throw runtime_error(format_error("Imports are only allowed in the shared section")); @@ -551,7 +550,7 @@ RefPtr ProgramParser::parse_import() return import; } -RefPtr ProgramParser::parse_precision() +RefPtr Parser::parse_precision() { expect("precision"); RefPtr precision = new Precision; @@ -572,7 +571,7 @@ RefPtr ProgramParser::parse_precision() return precision; } -RefPtr ProgramParser::parse_layout() +RefPtr Parser::parse_layout() { expect("layout"); expect("("); @@ -600,7 +599,7 @@ RefPtr ProgramParser::parse_layout() return layout; } -void ProgramParser::parse_block(Block &block, bool require_braces) +void Parser::parse_block(Block &block, bool require_braces) { bool have_braces = (require_braces || peek_token()=="{"); if(have_braces) @@ -620,7 +619,7 @@ void ProgramParser::parse_block(Block &block, bool require_braces) expect("}"); } -RefPtr ProgramParser::parse_expression(unsigned precedence) +RefPtr Parser::parse_expression(unsigned precedence) { RefPtr left; VariableReference *left_var = 0; @@ -707,7 +706,7 @@ RefPtr ProgramParser::parse_expression(unsigned precedence) } } -RefPtr ProgramParser::parse_binary(const RefPtr &left, const Operator *oper) +RefPtr Parser::parse_binary(const RefPtr &left, const Operator *oper) { RefPtr binary = (oper->precedence==16 ? new Assignment : new BinaryExpression); binary->left = left; @@ -723,7 +722,7 @@ RefPtr ProgramParser::parse_binary(const RefPtr &l return binary; } -RefPtr ProgramParser::parse_function_call(const VariableReference &var) +RefPtr Parser::parse_function_call(const VariableReference &var) { RefPtr call = new FunctionCall; call->name = var.name; @@ -739,7 +738,7 @@ RefPtr ProgramParser::parse_function_call(const VariableReference return call; } -RefPtr ProgramParser::parse_struct_declaration() +RefPtr Parser::parse_struct_declaration() { expect("struct"); RefPtr strct = new StructDeclaration; @@ -754,7 +753,7 @@ RefPtr ProgramParser::parse_struct_declaration() return strct; } -RefPtr ProgramParser::parse_variable_declaration() +RefPtr Parser::parse_variable_declaration() { RefPtr var = new VariableDeclaration; var->source = source_index; @@ -797,7 +796,7 @@ RefPtr ProgramParser::parse_variable_declaration() return var; } -RefPtr ProgramParser::parse_function_declaration() +RefPtr Parser::parse_function_declaration() { RefPtr func = new FunctionDeclaration; func->source = source_index; @@ -835,7 +834,7 @@ RefPtr ProgramParser::parse_function_declaration() return func; } -RefPtr ProgramParser::parse_interface_block() +RefPtr Parser::parse_interface_block() { RefPtr iface = new InterfaceBlock; iface->source = source_index; @@ -861,7 +860,7 @@ RefPtr ProgramParser::parse_interface_block() return iface; } -RefPtr ProgramParser::parse_conditional() +RefPtr Parser::parse_conditional() { expect("if"); RefPtr cond = new Conditional; @@ -883,7 +882,7 @@ RefPtr ProgramParser::parse_conditional() return cond; } -RefPtr ProgramParser::parse_for() +RefPtr Parser::parse_for() { expect("for"); RefPtr loop = new Iteration; @@ -915,7 +914,7 @@ RefPtr ProgramParser::parse_for() return loop; } -RefPtr ProgramParser::parse_while() +RefPtr Parser::parse_while() { expect("while"); RefPtr loop = new Iteration; @@ -930,7 +929,7 @@ RefPtr ProgramParser::parse_while() return loop; } -RefPtr ProgramParser::parse_passthrough() +RefPtr Parser::parse_passthrough() { expect("passthrough"); RefPtr pass = new Passthrough; @@ -946,7 +945,7 @@ RefPtr ProgramParser::parse_passthrough() return pass; } -RefPtr ProgramParser::parse_return() +RefPtr Parser::parse_return() { expect("return"); RefPtr ret = new Return; @@ -958,5 +957,6 @@ RefPtr ProgramParser::parse_return() return ret; } +} // namespace SL } // namespace GL } // namespace Msp diff --git a/source/glsl/programparser.h b/source/glsl/parser.h similarity index 55% rename from source/glsl/programparser.h rename to source/glsl/parser.h index e3660473..c9588bfb 100644 --- a/source/glsl/programparser.h +++ b/source/glsl/parser.h @@ -1,17 +1,18 @@ -#ifndef MSP_GL_PROGRAMPARSER_H_ -#define MSP_GL_PROGRAMPARSER_H_ +#ifndef MSP_GL_SL_PARSER_H_ +#define MSP_GL_SL_PARSER_H_ #include #include #include #include #include -#include "programsyntax.h" +#include "syntax.h" namespace Msp { namespace GL { +namespace SL { -class ProgramParser +class Parser { private: enum OperatorType @@ -46,18 +47,18 @@ private: bool allow_stage_change; std::string last_token; std::deque next_tokens; - ProgramSyntax::Module *module; - ProgramSyntax::Stage *cur_stage; + Module *module; + Stage *cur_stage; std::set declared_types; static Operator operators[]; public: - ProgramParser(); - ~ProgramParser(); + Parser(); + ~Parser(); - ProgramSyntax::Module &parse(const std::string &, const std::string &, unsigned = 0); - ProgramSyntax::Module &parse(IO::Base &, const std::string &, unsigned = 0); + Module &parse(const std::string &, const std::string &, unsigned = 0); + Module &parse(IO::Base &, const std::string &, unsigned = 0); private: void parse_source(); @@ -92,26 +93,27 @@ private: void preprocess_pragma_msp(); void preprocess_stage(); - RefPtr parse_global_declaration(); - RefPtr parse_statement(); - RefPtr parse_import(); - RefPtr parse_precision(); - RefPtr parse_layout(); - void parse_block(ProgramSyntax::Block &, bool); - RefPtr parse_expression(unsigned = 0); - RefPtr parse_binary(const RefPtr &, const Operator *); - RefPtr parse_function_call(const ProgramSyntax::VariableReference &); - RefPtr parse_struct_declaration(); - RefPtr parse_variable_declaration(); - RefPtr parse_function_declaration(); - RefPtr parse_interface_block(); - RefPtr parse_conditional(); - RefPtr parse_for(); - RefPtr parse_while(); - RefPtr parse_passthrough(); - RefPtr parse_return(); + RefPtr parse_global_declaration(); + RefPtr parse_statement(); + RefPtr parse_import(); + RefPtr parse_precision(); + RefPtr parse_layout(); + void parse_block(Block &, bool); + RefPtr parse_expression(unsigned = 0); + RefPtr parse_binary(const RefPtr &, const Operator *); + RefPtr parse_function_call(const VariableReference &); + RefPtr parse_struct_declaration(); + RefPtr parse_variable_declaration(); + RefPtr parse_function_declaration(); + RefPtr parse_interface_block(); + RefPtr parse_conditional(); + RefPtr parse_for(); + RefPtr parse_while(); + RefPtr parse_passthrough(); + RefPtr parse_return(); }; +} // namespace SL } // namespace GL } // namespace Msp diff --git a/source/glsl/programcompiler.h b/source/glsl/programcompiler.h deleted file mode 100644 index 0bff354a..00000000 --- a/source/glsl/programcompiler.h +++ /dev/null @@ -1,416 +0,0 @@ -#ifndef MSP_GL_PROGRAMCOMPILER_H_ -#define MSP_GL_PROGRAMCOMPILER_H_ - -#include -#include "programparser.h" -#include "programsyntax.h" - -namespace Msp { -namespace GL { - -class Program; -class Resources; - -class ProgramCompiler -{ -private: - struct Visitor: ProgramSyntax::TraversingVisitor - { - typedef void ResultType; - - ProgramSyntax::Stage *stage; - - Visitor(); - - virtual void apply(ProgramSyntax::Stage &); - void get_result() const { } - }; - - struct BlockModifier: Visitor - { - bool remove_node; - std::vector > insert_nodes; - - BlockModifier(); - - void flatten_block(ProgramSyntax::Block &); - void apply_and_increment(ProgramSyntax::Block &, ProgramSyntax::NodeList::iterator &); - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - }; - - struct Formatter: Visitor - { - typedef std::string ResultType; - - std::string formatted; - unsigned source_index; - unsigned source_line; - unsigned indent; - bool parameter_list; - std::string block_interface; - - Formatter(); - - virtual void apply(ProgramSyntax::Stage &); - const std::string &get_result() const { return formatted; } - using Visitor::visit; - void append(const std::string &); - void append(char); - void set_source(unsigned, unsigned); - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::Literal &); - virtual void visit(ProgramSyntax::ParenthesizedExpression &); - virtual void visit(ProgramSyntax::VariableReference &); - virtual void visit(ProgramSyntax::MemberAccess &); - virtual void visit(ProgramSyntax::UnaryExpression &); - virtual void visit(ProgramSyntax::BinaryExpression &); - virtual void visit(ProgramSyntax::Assignment &); - virtual void visit(ProgramSyntax::FunctionCall &); - virtual void visit(ProgramSyntax::ExpressionStatement &); - virtual void visit(ProgramSyntax::Import &); - virtual void visit(ProgramSyntax::Precision &); - virtual void visit(ProgramSyntax::Layout &); - virtual void visit(ProgramSyntax::InterfaceLayout &); - virtual void visit(ProgramSyntax::StructDeclaration &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::InterfaceBlock &); - virtual void visit(ProgramSyntax::FunctionDeclaration &); - virtual void visit(ProgramSyntax::Conditional &); - virtual void visit(ProgramSyntax::Iteration &); - virtual void visit(ProgramSyntax::Return &); - virtual void visit(ProgramSyntax::Jump &); - }; - - template - struct NodeGatherer: Visitor - { - typedef std::vector ResultType; - - std::vector nodes; - - const ResultType &get_result() const { return nodes; } - using Visitor::visit; - virtual void visit(T &n) { nodes.push_back(&n); } - }; - - struct DeclarationCombiner: BlockModifier - { - bool toplevel; - std::map > functions; - std::map variables; - - DeclarationCombiner(); - - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::FunctionDeclaration &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - }; - - struct VariableResolver: Visitor - { - std::vector blocks; - ProgramSyntax::StructDeclaration *type; - bool anonymous; - std::string block_interface; - bool record_target; - ProgramSyntax::VariableDeclaration *assignment_target; - bool self_referencing; - - VariableResolver(); - - virtual void apply(ProgramSyntax::Stage &); - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::VariableReference &); - virtual void visit(ProgramSyntax::MemberAccess &); - virtual void visit(ProgramSyntax::BinaryExpression &); - virtual void visit(ProgramSyntax::Assignment &); - virtual void visit(ProgramSyntax::StructDeclaration &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::InterfaceBlock &); - }; - - struct FunctionResolver: Visitor - { - std::map > functions; - - using Visitor::visit; - virtual void visit(ProgramSyntax::FunctionCall &); - virtual void visit(ProgramSyntax::FunctionDeclaration &); - }; - - struct InterfaceGenerator: BlockModifier - { - std::string in_prefix; - std::string out_prefix; - unsigned scope_level; - std::map > iface_declarations; - - InterfaceGenerator(); - - static std::string get_out_prefix(ProgramSyntax::StageType); - virtual void apply(ProgramSyntax::Stage &); - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - std::string change_prefix(const std::string &, const std::string &) const; - bool generate_interface(ProgramSyntax::VariableDeclaration &, const std::string &, const std::string &); - ProgramSyntax::ExpressionStatement &insert_assignment(const std::string &, ProgramSyntax::Expression *); - virtual void visit(ProgramSyntax::VariableReference &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::Passthrough &); - }; - - struct DeclarationReorderer: Visitor - { - enum DeclarationKind - { - NO_DECLARATION, - LAYOUT, - STRUCT, - VARIABLE, - FUNCTION - }; - - unsigned scope_level; - DeclarationKind kind; - std::set ordered_funcs; - std::set needed_funcs; - - DeclarationReorderer(); - - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::FunctionCall &); - virtual void visit(ProgramSyntax::InterfaceLayout &) { kind = LAYOUT; } - virtual void visit(ProgramSyntax::StructDeclaration &) { kind = STRUCT; } - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::InterfaceBlock &) { kind = VARIABLE; } - virtual void visit(ProgramSyntax::FunctionDeclaration &); - }; - - struct InlineableFunctionLocator: Visitor - { - typedef std::set ResultType; - - std::map refcounts; - std::set inlineable; - ProgramSyntax::FunctionDeclaration *in_function; - - InlineableFunctionLocator(); - - const ResultType &get_result() const { return inlineable; } - using Visitor::visit; - virtual void visit(ProgramSyntax::FunctionCall &); - virtual void visit(ProgramSyntax::FunctionDeclaration &); - }; - - struct FunctionInliner: Visitor - { - std::set inlineable; - unsigned extract_result; - RefPtr inline_result; - - FunctionInliner(); - FunctionInliner(const std::set &); - - void visit_and_inline(RefPtr &); - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::UnaryExpression &); - virtual void visit(ProgramSyntax::BinaryExpression &); - virtual void visit(ProgramSyntax::MemberAccess &); - virtual void visit(ProgramSyntax::FunctionCall &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::Return &); - }; - - struct ExpressionEvaluator: ProgramSyntax::NodeVisitor - { - typedef std::map ValueMap; - - const ValueMap *variable_values; - float result; - bool result_valid; - - ExpressionEvaluator(); - ExpressionEvaluator(const ValueMap &); - - using ProgramSyntax::NodeVisitor::visit; - virtual void visit(ProgramSyntax::Literal &); - virtual void visit(ProgramSyntax::ParenthesizedExpression &); - virtual void visit(ProgramSyntax::VariableReference &); - virtual void visit(ProgramSyntax::UnaryExpression &); - virtual void visit(ProgramSyntax::BinaryExpression &); - }; - - struct ConstantConditionEliminator: BlockModifier - { - unsigned scope_level; - bool record_only; - ExpressionEvaluator::ValueMap variable_values; - - ConstantConditionEliminator(); - - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::UnaryExpression &); - virtual void visit(ProgramSyntax::Assignment &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::Conditional &); - virtual void visit(ProgramSyntax::Iteration &); - }; - - struct UnusedVariableLocator: Visitor - { - struct VariableInfo - { - bool local; - std::vector assignments; - bool conditionally_assigned; - bool referenced; - - VariableInfo(); - }; - - typedef std::set ResultType; - typedef std::map BlockVariableMap; - - std::set unused_nodes; - std::map aggregates; - ProgramSyntax::Node *aggregate; - std::vector variables; - ProgramSyntax::Assignment *assignment; - bool assignment_target; - bool assign_to_subscript; - bool global_scope; - - UnusedVariableLocator(); - - virtual void apply(ProgramSyntax::Stage &); - const ResultType &get_result() const { return unused_nodes; } - using Visitor::visit; - virtual void visit(ProgramSyntax::VariableReference &); - virtual void visit(ProgramSyntax::MemberAccess &); - virtual void visit(ProgramSyntax::BinaryExpression &); - virtual void visit(ProgramSyntax::Assignment &); - void record_assignment(ProgramSyntax::VariableDeclaration &, ProgramSyntax::Node &, bool); - void clear_assignments(VariableInfo &, bool); - virtual void visit(ProgramSyntax::ExpressionStatement &); - virtual void visit(ProgramSyntax::StructDeclaration &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::InterfaceBlock &); - virtual void visit(ProgramSyntax::FunctionDeclaration &); - void merge_down_variables(); - virtual void visit(ProgramSyntax::Conditional &); - virtual void visit(ProgramSyntax::Iteration &); - }; - - struct UnusedFunctionLocator: Visitor - { - typedef std::set ResultType; - - std::set unused_nodes; - std::set used_definitions; - - const ResultType &get_result() const { return unused_nodes; } - using Visitor::visit; - virtual void visit(ProgramSyntax::FunctionCall &); - virtual void visit(ProgramSyntax::FunctionDeclaration &); - }; - - struct NodeRemover: Visitor - { - std::set to_remove; - - NodeRemover() { } - NodeRemover(const std::set &); - - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - virtual void visit(ProgramSyntax::Iteration &); - }; - - struct PrecisionRemover: BlockModifier - { - using Visitor::visit; - virtual void visit(ProgramSyntax::Precision &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - }; - - struct DefaultPrecisionGenerator: BlockModifier - { - bool toplevel; - std::set have_default; - - DefaultPrecisionGenerator(); - - using Visitor::visit; - virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::Precision &); - virtual void visit(ProgramSyntax::VariableDeclaration &); - }; - - struct LegacyConverter: BlockModifier - { - GLApi target_api; - Version target_version; - std::string type; - ProgramSyntax::VariableDeclaration *frag_out; - - LegacyConverter(); - LegacyConverter(const Version &); - - bool check_version(const Version &) const; - bool check_extension(const Extension &) const; - using Visitor::visit; - bool supports_unified_interface_syntax() const; - virtual void visit(ProgramSyntax::VariableReference &); - virtual void visit(ProgramSyntax::Assignment &); - bool supports_unified_sampling_functions() const; - virtual void visit(ProgramSyntax::FunctionCall &); - bool supports_interface_layouts() const; - bool supports_centroid_sampling() const; - bool supports_sample_sampling() const; - virtual void visit(ProgramSyntax::VariableDeclaration &); - bool supports_interface_blocks(const std::string &) const; - virtual void visit(ProgramSyntax::InterfaceBlock &); - }; - - Resources *resources; - ProgramSyntax::Module *module; - std::vector imported_names; - -public: - ProgramCompiler(); - ~ProgramCompiler(); - - void compile(const std::string &, const std::string & = ""); - void compile(IO::Base &, Resources * = 0, const std::string & = ""); - void compile(IO::Base &, const std::string &); - void add_shaders(Program &); - -private: - static ProgramSyntax::Module *create_builtins_module(); - static ProgramSyntax::Module &get_builtins_module(); - static ProgramSyntax::Stage *get_builtins(ProgramSyntax::StageType); - void append_module(ProgramSyntax::Module &); - void append_stage(ProgramSyntax::Stage &); - void process(); - void import(const std::string &); - void generate(ProgramSyntax::Stage &); - bool optimize(ProgramSyntax::Stage &); - void finalize(ProgramSyntax::Stage &); - static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &); - template - static typename T::ResultType apply(ProgramSyntax::Stage &); - template - static typename T::ResultType apply(ProgramSyntax::Stage &, const A &); -}; - -} // namespace GL -} // namespace Msp - -#endif diff --git a/source/glsl/programsyntax.cpp b/source/glsl/syntax.cpp similarity index 98% rename from source/glsl/programsyntax.cpp rename to source/glsl/syntax.cpp index 6dea029f..9705c989 100644 --- a/source/glsl/programsyntax.cpp +++ b/source/glsl/syntax.cpp @@ -1,10 +1,10 @@ -#include "programsyntax.h" +#include "syntax.h" using namespace std; namespace Msp { namespace GL { -namespace ProgramSyntax { +namespace SL { template NodeContainer::NodeContainer(const NodeContainer &c): @@ -328,6 +328,6 @@ Module::Module(): shared(SHARED) { } -} // namespace ProgramSyntax +} // namespace SL } // namespace GL } // namespace Msp diff --git a/source/glsl/programsyntax.h b/source/glsl/syntax.h similarity index 98% rename from source/glsl/programsyntax.h rename to source/glsl/syntax.h index e7b5111e..a2630ef0 100644 --- a/source/glsl/programsyntax.h +++ b/source/glsl/syntax.h @@ -1,5 +1,5 @@ -#ifndef MSP_GL_PROGRAMSYNTAX_H_ -#define MSP_GL_PROGRAMSYNTAX_H_ +#ifndef MSP_GL_SL_SYNTAX_H_ +#define MSP_GL_SL_SYNTAX_H_ #include #include @@ -14,7 +14,7 @@ namespace Msp { namespace GL { -namespace ProgramSyntax { +namespace SL { struct NodeVisitor; @@ -398,7 +398,7 @@ struct Stage { StageType type; Stage *previous; - ProgramSyntax::Block content; + Block content; std::map in_variables; std::map out_variables; std::map locations; @@ -416,7 +416,7 @@ struct Module Module(); }; -} // namespace ProgramSyntax +} // namespace SL } // namespace GL } // namespace Msp diff --git a/source/resources/resources.cpp b/source/resources/resources.cpp index d52dbe34..11099ae0 100644 --- a/source/resources/resources.cpp +++ b/source/resources/resources.cpp @@ -12,7 +12,6 @@ #include "pipelinetemplate.h" #include "pose.h" #include "program.h" -#include "programcompiler.h" #include "resourcemanager.h" #include "resources.h" #include "sampler.h" @@ -21,6 +20,7 @@ #include "texture2d.h" #include "texture2darray.h" #include "texturecube.h" +#include "glsl/compiler.h" using namespace std; @@ -172,7 +172,7 @@ Program *Resources::create_program(const string &name) if(RefPtr io = open_raw(name)) { - ProgramCompiler compiler; + SL::Compiler compiler; compiler.compile(*io, this, name); RefPtr program = new Program; compiler.add_shaders(*program); -- 2.45.2