+ /* Uniforms are available to all stages and are not passed through
+ interfaces */
+ if(variable->scope==UNIFORM)
+ return NO_INTERFACE;
+
+ int flags = NO_INTERFACE;
+
+ for(list<ShaderVariable *>::const_iterator i=referenced_by.begin(); i!=referenced_by.end(); ++i)
+ {
+ /* Variables used in a later scope than they are declared in need to go
+ through the interface */
+ if((*i)->variable->scope>scope && variable->scope<=scope)
+ flags |= OUTPUT;
+ if((*i)->variable->scope>=scope && variable->scope<scope)
+ if(!inlined || variable->scope!=ATTRIBUTE || scope!=VERTEX)
+ flags |= INPUT;
+ }
+
+ // Variables without any references are goals and also outputs.
+ if(referenced_by.empty() && variable->scope==scope)
+ flags |= OUTPUT|GOAL;
+
+ return static_cast<InterfaceFlags>(flags);
+}
+
+string ProgramBuilder::ShaderVariable::create_declaration(char interface, bool loop) const
+{
+ if(variable->scope==UNIFORM && !array_subscript.empty())
+ {
+ const char *bracket = strrchr(variable->type, '[');
+ if(bracket)
+ return format("%s %s[%d]", string(variable->type, bracket), resolved_name, array_size);
+ }
+
+ string array;
+ if(!array_sum && array_size>1 && !loop)
+ array = format("[%d]", array_size);
+
+ if(interface)
+ return format("%s %c_%s%s", variable->type, interface, resolved_name, array);
+ else
+ return format("%s %s%s", variable->type, resolved_name, array);
+}
+
+string ProgramBuilder::ShaderVariable::create_replacement(VariableScope from_scope, const char *loop) const
+{
+ string replacement = resolved_name;
+ InterfaceFlags interface = NO_INTERFACE;
+ if(variable)
+ {
+ interface = get_interface_flags(from_scope);
+ if((interface&INPUT) && interfaces[from_scope-1])
+ replacement = format("%c_%s", interfaces[from_scope-1], replacement);
+ else if(inlined)