]> git.tdb.fi Git - libs/gl.git/commitdiff
Inline variables which are simple aliases, even if not optimizing
authorMikko Rasa <tdb@tdb.fi>
Tue, 13 May 2014 16:43:31 +0000 (19:43 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 13 May 2014 16:44:42 +0000 (19:44 +0300)
This fixes another problem with unoptimized legacy shaders, making them
work properly again.

source/programbuilder.cpp
source/programbuilder.h

index 0f29675f19dd3e45e4a63633747c6d31093f5680..bf89e7db8270ddb552ab8d3eebe49bbd687047aa 100644 (file)
@@ -292,11 +292,8 @@ void ProgramBuilder::add_shaders(Program &prog) const
                }
        }
 
-       if(optimize)
-       {
-               for(list<ShaderVariable *>::const_iterator i=resolved_vars.begin(); i!=resolved_vars.end(); ++i)
-                       (*i)->check_inline(features.legacy);
-       }
+       for(list<ShaderVariable *>::const_iterator i=resolved_vars.begin(); i!=resolved_vars.end(); ++i)
+               (*i)->check_inline(features.legacy, !optimize);
 
        prog.attach_shader_owned(new VertexShader(create_source(resolved_vars, VERTEX)));
        prog.attach_shader_owned(new FragmentShader(create_source(resolved_vars, FRAGMENT)));
@@ -624,19 +621,39 @@ void ProgramBuilder::ShaderVariable::update_reference(ShaderVariable &from, Shad
                resolve_space(to.resolved_space);
 }
 
-void ProgramBuilder::ShaderVariable::check_inline(bool allow_legacy)
+void ProgramBuilder::ShaderVariable::check_inline(bool allow_legacy, bool trivial_only)
 {
        if(variable->expression)
        {
                if(!allow_legacy && !strncmp(variable->expression, "gl_", 3))
                        return;
 
+               // Never inline goal variables
                unsigned total_refs = referenced_by.size();
+               if(!total_refs)
+                       return;
+
+               // Inline an expression consisting of a single identifier
+               unsigned start, length;
+               if(parse_identifier(variable->expression, start, length))
+                       if(start==0 && variable->expression[length]==0)
+                       {
+                               inlined = true;
+                               return;
+                       }
+
+               if(trivial_only)
+                       return;
+
                unsigned in_scope_refs = 0;
                for(list<ShaderVariable *>::const_iterator i=referenced_by.begin(); i!=referenced_by.end(); ++i)
                        if((*i)->variable->scope==variable->scope)
                                ++in_scope_refs;
-               if(total_refs==1 || (total_refs>0 && in_scope_refs==0))
+
+               /* Inline if there's only one ref, or if all refs are in other scopes.
+               In the latter case, the actual inlining will happen in the interface
+               variable assignment. */
+               if(total_refs==1 || in_scope_refs==0)
                {
                        inlined = true;
                        unsigned level = 0;
index 7840ecf00a2ef993a3590b6dd802f798b3d5878e..8275e4579556e91aabd3c1b6d39d63698146b34d 100644 (file)
@@ -82,7 +82,7 @@ private:
                void resolve_space(const std::string &);
                void add_reference(ShaderVariable &);
                void update_reference(ShaderVariable &, ShaderVariable &);
-               void check_inline(bool);
+               void check_inline(bool, bool);
                bool is_referenced_from(VariableScope) const;
                std::string get_expression() const;
        };