|
@@ -233,6 +233,25 @@ class Linker {
|
|
|
cur.onStack = false;
|
|
|
}
|
|
|
|
|
|
+ function uniqueLocals( expr : TExpr, locals : Map < String, Bool > ) {
|
|
|
+ switch( expr.e ) {
|
|
|
+ case TVarDecl(v, _):
|
|
|
+ if( locals.exists(v.name) ) {
|
|
|
+ var k = 2;
|
|
|
+ while( locals.exists(v.name + k) )
|
|
|
+ k++;
|
|
|
+ v.name += k;
|
|
|
+ }
|
|
|
+ locals.set(v.name, true);
|
|
|
+ case TBlock(el):
|
|
|
+ var locals = [for( k in locals.keys() ) k => true];
|
|
|
+ for( e in el )
|
|
|
+ uniqueLocals(e, locals);
|
|
|
+ default:
|
|
|
+ expr.iter(uniqueLocals.bind(_, locals));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public function link( shadersData : Array<ShaderData>, outVars : Array<String> ) : ShaderData {
|
|
|
varMap = new Map();
|
|
|
varIdMap = new Map();
|
|
@@ -240,6 +259,15 @@ class Linker {
|
|
|
shaders = [];
|
|
|
locals = new Map();
|
|
|
|
|
|
+ var dupShaders = new Map();
|
|
|
+ shadersData = [for( s in shadersData ) {
|
|
|
+ var s = s, sreal = s;
|
|
|
+ if( dupShaders.exists(s) )
|
|
|
+ s = Clone.shaderData(s);
|
|
|
+ dupShaders.set(s, sreal);
|
|
|
+ s;
|
|
|
+ }];
|
|
|
+
|
|
|
// globalize vars
|
|
|
curInstance = 0;
|
|
|
for( s in shadersData ) {
|
|
@@ -355,18 +383,29 @@ class Linker {
|
|
|
default:
|
|
|
exprs.push(s.body);
|
|
|
}
|
|
|
+ var expr = { e : TBlock(exprs), t : TVoid, p : exprs.length == 0 ? null : exprs[0].p };
|
|
|
+ uniqueLocals(expr, new Map());
|
|
|
return {
|
|
|
kind : kind,
|
|
|
ref : v,
|
|
|
ret : TVoid,
|
|
|
args : [],
|
|
|
- expr : { e : TBlock(exprs), t : TVoid, p : exprs.length == 0 ? null : exprs[0].p },
|
|
|
+ expr : expr,
|
|
|
};
|
|
|
}
|
|
|
var funs = [
|
|
|
build(Vertex, "vertex", v),
|
|
|
build(Fragment, "fragment", f),
|
|
|
];
|
|
|
+
|
|
|
+ // make sure the first merged var is the original for duplicate shaders
|
|
|
+ for( s in dupShaders.keys() ) {
|
|
|
+ var sreal = dupShaders.get(s);
|
|
|
+ if( s == sreal ) continue;
|
|
|
+ for( i in 0...s.vars.length )
|
|
|
+ allocVar(s.vars[i],null).merged.unshift(sreal.vars[i]);
|
|
|
+ }
|
|
|
+
|
|
|
return { name : "out", vars : outVars, funs : funs };
|
|
|
}
|
|
|
|