]> git.tdb.fi Git - libs/gl.git/commitdiff
Inject builtins into the module
authorMikko Rasa <tdb@tdb.fi>
Sun, 28 Feb 2021 19:37:05 +0000 (21:37 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 28 Feb 2021 19:42:35 +0000 (21:42 +0200)
This makes identifier resolution easier to manage and also helps an
eventual SPIR-V implementation.

source/glsl/builtin.cpp
source/glsl/compiler.cpp
source/glsl/debug.cpp
source/glsl/generate.cpp
source/glsl/generate.h
source/glsl/output.cpp
source/glsl/parser.cpp
source/glsl/parser.h
source/glsl/syntax.cpp
source/glsl/syntax.h

index 1fd496b40c5e8210636960d2a69644363844e95a..049740657a5c251432f5054a67a40d1fa4b98164 100644 (file)
@@ -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, "<builtin>"));
-               for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
-               {
-                       VariableResolver().apply(*i);
-                       for(map<string, VariableDeclaration *>::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>", BUILTIN_SOURCE));
 
                builtins_module = module;
        }
index 5bec9c8b1b8f475163b50a35b57b0a92e5bec84b..c68b67bd0cd629f81db2838c60840b43c1abe720 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/core/algorithm.h>
 #include <msp/gl/extensions/ext_gpu_shader4.h>
 #include <msp/strings/format.h>
+#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<Statement>::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
index 50d2b985604ccfa4f5a4c1c2afe0d667d02be01c..5397372e611bd7108c3e3da0fc254e4bc9a575b4 100644 (file)
@@ -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();
index fe053ade254c3105d80771a72d575b264583946a..2fa930a9df822ac369842d46045baaa8955fadd5 100644 (file)
@@ -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<string, VariableDeclaration *>::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<string, InterfaceBlock *>::iterator i = stage->interface_blocks.find(iface.name);
                if(i!=stage->interface_blocks.end())
index 4359a09fdc59d7d772d19be09f02714dfba0e225..977ed156f4490ab9e282b328d59c6c88074db3f2 100644 (file)
@@ -61,7 +61,6 @@ class VariableResolver: private TraversingVisitor
 {
 private:
        Stage *stage;
-       Block *builtins;
        std::map<std::string, VariableDeclaration *> *members;
        RefPtr<InterfaceBlockReference> 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 &);
index 44acd634d388e1d3f9c7ab86081e43e4368f01ee..81f335735e80eb433fd746ae85216dc59b309e83 100644 (file)
@@ -161,10 +161,14 @@ void Formatter::visit(Block &block)
 
        SetForScope<unsigned> set(indent, indent+(indent>0 || use_braces));
        string spaces(indent*2, ' ');
+       bool first = true;
        for(NodeList<Statement>::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);
index d9fdbc4ea998e56d98d2209e6a5d79558511bf34..1f0d712467f3b43c2d9990dfa277bb1c46d0ff42 100644 (file)
@@ -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);
index acfb7d9eed9a8cc857becf5436e59a92bac522ba..bce9698f7d608a4b3c18417bf2eef1d149f54a81 100644 (file)
@@ -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);
index 7f2efdce93ebb30557be4b713d49125bca646da0..55dc94a77ff3552dbc449ade8da8659e3c1b9880 100644 (file)
@@ -67,7 +67,7 @@ NodeContainer<C>::NodeContainer(const NodeContainer &c):
 
 
 Statement::Statement():
-       source(0),
+       source(GENERATED_SOURCE),
        line(1)
 { }
 
index 70ea50d106f774c2c8be8974cb3140fbf0421d39..e7c642ba4abe0c9f4b2d8b91b065a85e499f0362 100644 (file)
@@ -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();