From: Mikko Rasa Date: Tue, 13 May 2014 16:43:31 +0000 (+0300) Subject: Inline variables which are simple aliases, even if not optimizing X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=cdd4ca79e38325a482f007d5d271d08b2d9bec6c;p=libs%2Fgl.git Inline variables which are simple aliases, even if not optimizing This fixes another problem with unoptimized legacy shaders, making them work properly again. --- diff --git a/source/programbuilder.cpp b/source/programbuilder.cpp index 0f29675f..bf89e7db 100644 --- a/source/programbuilder.cpp +++ b/source/programbuilder.cpp @@ -292,11 +292,8 @@ void ProgramBuilder::add_shaders(Program &prog) const } } - if(optimize) - { - for(list::const_iterator i=resolved_vars.begin(); i!=resolved_vars.end(); ++i) - (*i)->check_inline(features.legacy); - } + for(list::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::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; diff --git a/source/programbuilder.h b/source/programbuilder.h index 7840ecf0..8275e457 100644 --- a/source/programbuilder.h +++ b/source/programbuilder.h @@ -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; };