From: Mikko Rasa Date: Sun, 28 Feb 2021 19:37:05 +0000 (+0200) Subject: Inject builtins into the module X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=9ec831710f64a62ad5f2e896a55ae82a3519f29e Inject builtins into the module This makes identifier resolution easier to manage and also helps an eventual SPIR-V implementation. --- diff --git a/source/glsl/builtin.cpp b/source/glsl/builtin.cpp index 1fd496b4..04974065 100644 --- a/source/glsl/builtin.cpp +++ b/source/glsl/builtin.cpp @@ -1,5 +1,4 @@ #include "builtin.h" -#include "generate.h" #include "parser.h" using namespace std; @@ -37,13 +36,7 @@ Module *get_builtins_module() initialized = true; Parser parser; - Module *module = new Module(parser.parse(builtins_src, "")); - for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) - { - VariableResolver().apply(*i); - for(map::iterator j=i->content.variables.begin(); j!=i->content.variables.end(); ++j) - j->second->linked_declaration = j->second; - } + Module *module = new Module(parser.parse(builtins_src, "", BUILTIN_SOURCE)); builtins_module = module; } diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 5bec9c8b..c68b67bd 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "builtin.h" #include "compatibility.h" #include "compiler.h" #include "debug.h" @@ -185,6 +186,13 @@ void Compiler::append_stage(Stage &stage) target = &*i; } + if(target->content.body.empty()) + { + Stage *builtins = get_builtins(stage.type); + if(builtins && builtins!=&stage) + append_stage(*builtins); + } + if(stage.required_features.glsl_version>target->required_features.glsl_version) target->required_features.glsl_version = stage.required_features.glsl_version; for(NodeList::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i) diff --git a/source/glsl/debug.cpp b/source/glsl/debug.cpp index 50d2b985..5397372e 100644 --- a/source/glsl/debug.cpp +++ b/source/glsl/debug.cpp @@ -254,7 +254,9 @@ void DumpTree::visit(VariableDeclaration &var) if(!var.precision.empty()) decl += format("%s ", var.precision); decl += format("%s %s", var.type, var.name); - if(var.linked_declaration) + if(var.source==BUILTIN_SOURCE) + decl += " (builtin)"; + else if(var.linked_declaration) decl += " (linked)"; append(decl); @@ -290,7 +292,9 @@ void DumpTree::visit(InterfaceBlock &block) head += format(" %s", block.instance_name); if(block.array) head += "[]"; - if(block.linked_block) + if(block.source==BUILTIN_SOURCE) + head += " (builtin)"; + else if(block.linked_block) head += " (linked)"; annotated_branch(head, block.members); } @@ -298,7 +302,9 @@ void DumpTree::visit(InterfaceBlock &block) void DumpTree::visit(FunctionDeclaration &func) { string text = format("%%%d %s %s", get_label(func), func.return_type, func.name); - if(!func.definition) + if(func.source==BUILTIN_SOURCE) + text += " (builtin)"; + else if(!func.definition) text += " (undefined)"; append(text); begin_sub(); diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index fe053ade..2fa930a9 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -116,7 +116,6 @@ void BlockHierarchyResolver::enter(Block &block) VariableResolver::VariableResolver(): stage(0), - builtins(0), members(0), record_target(false), assignment_target(0), @@ -128,16 +127,9 @@ void VariableResolver::apply(Stage &s) stage = &s; s.types.clear(); s.interface_blocks.clear(); - Stage *builtin_stage = get_builtins(s.type); - builtins = (builtin_stage ? &builtin_stage->content : 0); s.content.visit(*this); } -Block *VariableResolver::next_block(Block &block) -{ - return block.parent ? block.parent : &block!=builtins ? builtins : 0; -} - void VariableResolver::enter(Block &block) { block.variables.clear(); @@ -147,7 +139,7 @@ void VariableResolver::visit(VariableReference &var) { var.declaration = 0; members = 0; - for(Block *block=current_block; (!var.declaration && block); block=next_block(*block)) + for(Block *block=current_block; (!var.declaration && block); block=block->parent) { map::iterator i = block->variables.find(var.name); if(i!=block->variables.end()) @@ -199,7 +191,7 @@ void VariableResolver::visit(VariableReference &var) void VariableResolver::visit(InterfaceBlockReference &iface) { iface.declaration = 0; - for(Block *block=current_block; block; block=next_block(*block)) + for(Block *block=current_block; block; block=block->parent) { map::iterator i = stage->interface_blocks.find(iface.name); if(i!=stage->interface_blocks.end()) diff --git a/source/glsl/generate.h b/source/glsl/generate.h index 4359a09f..977ed156 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -61,7 +61,6 @@ class VariableResolver: private TraversingVisitor { private: Stage *stage; - Block *builtins; std::map *members; RefPtr iface_ref; std::string block_interface; @@ -75,8 +74,6 @@ public: void apply(Stage &); private: - Block *next_block(Block &); - virtual void enter(Block &); virtual void visit(VariableReference &); virtual void visit(InterfaceBlockReference &); diff --git a/source/glsl/output.cpp b/source/glsl/output.cpp index 44acd634..81f33573 100644 --- a/source/glsl/output.cpp +++ b/source/glsl/output.cpp @@ -161,10 +161,14 @@ void Formatter::visit(Block &block) SetForScope set(indent, indent+(indent>0 || use_braces)); string spaces(indent*2, ' '); + bool first = true; for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) { - if(i!=block.body.begin()) + if((*i)->source==BUILTIN_SOURCE) + continue; + if(!first) append('\n'); + first = false; set_source((*i)->source, (*i)->line); append(spaces); (*i)->visit(*this); diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index d9fdbc4e..1f0d7124 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -29,14 +29,14 @@ Parser::~Parser() delete module; } -Module &Parser::parse(const string &s, const string &n, unsigned i) +Module &Parser::parse(const string &s, const string &n, int i) { source = s; parse_source(n, i); return *module; } -Module &Parser::parse(IO::Base &io, const string &n, unsigned i) +Module &Parser::parse(IO::Base &io, const string &n, int i) { source = string(); while(!io.eof()) @@ -49,14 +49,15 @@ Module &Parser::parse(IO::Base &io, const string &n, unsigned i) return *module; } -void Parser::parse_source(const string &name, unsigned index) +void Parser::parse_source(const string &name, int index) { delete module; module = new Module; cur_stage = &module->shared; base_index = index; source_index = index; - source_reference(1, name); + if(index>=0) + source_reference(1, name); tokenizer.begin(name, source); allow_stage_change = true; while(!tokenizer.peek_token().empty()) @@ -74,7 +75,7 @@ void Parser::set_required_version(const Version &ver) void Parser::source_reference(unsigned index, const string &name) { - if(index<1) + if(index<1 || base_index<0) throw invalid_shader_source(tokenizer.get_location(), "Invalid source reference"); module->source_map.set_name(base_index+index-1, name); diff --git a/source/glsl/parser.h b/source/glsl/parser.h index acfb7d9e..bce9698f 100644 --- a/source/glsl/parser.h +++ b/source/glsl/parser.h @@ -16,8 +16,8 @@ class Parser { private: std::string source; - unsigned base_index; - unsigned source_index; + int base_index; + int source_index; Tokenizer tokenizer; Preprocessor preprocessor; bool allow_stage_change; @@ -30,11 +30,11 @@ public: Parser(); ~Parser(); - Module &parse(const std::string &, const std::string &, unsigned = 0); - Module &parse(IO::Base &, const std::string &, unsigned = 0); + Module &parse(const std::string &, const std::string &, int); + Module &parse(IO::Base &, const std::string &, int); private: - void parse_source(const std::string &, unsigned); + void parse_source(const std::string &, int); void set_required_version(const Version &); void source_reference(unsigned, const std::string &); void stage_change(Stage::Type); diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index 7f2efdce..55dc94a7 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -67,7 +67,7 @@ NodeContainer::NodeContainer(const NodeContainer &c): Statement::Statement(): - source(0), + source(GENERATED_SOURCE), line(1) { } diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index 70ea50d1..e7c642ba 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -41,6 +41,12 @@ struct Operator static const Operator operators[]; }; +enum +{ + BUILTIN_SOURCE = -1, + GENERATED_SOURCE = 0 +}; + struct NodeVisitor; struct Node @@ -96,7 +102,7 @@ struct FunctionDeclaration; struct Statement: Node { - unsigned source; + int source; unsigned line; Statement();