Przeglądaj źródła

fixed dependency for multiple RW on same var and prevent mutating instance var name

Nicolas Cannasse 11 lat temu
rodzic
commit
a4ae53b78a
2 zmienionych plików z 35 dodań i 19 usunięć
  1. 30 11
      hxsl/Linker.hx
  2. 5 8
      test/Test.hx

+ 30 - 11
hxsl/Linker.hx

@@ -110,6 +110,7 @@ class Linker {
 				default:
 				}
 		var v2 = varMap.get(key);
+		var vname = v.name;
 		if( v2 != null ) {
 			for( vm in v2.merged )
 				if( vm == v )
@@ -117,9 +118,15 @@ class Linker {
 			if( v.kind == Param || v.kind == Function || (v.kind == Var && v.hasQualifier(Private)) ) {
 				// allocate a new unique name in the shader if already in use
 				var k = 2;
-				while( varMap.exists(key + k) )
+				while( true ) {
+					var a = varMap.get(key + k);
+					if( a == null ) break;
+					for( vm in a.merged )
+						if( vm == v )
+							return a;
 					k++;
-				v.name += k;
+				}
+				vname += k;
 				key += k;
 			} else {
 				mergeVar(key, v, v2.v, p);
@@ -131,7 +138,7 @@ class Linker {
 		var vid = allVars.length;
 		var v2 : TVar = {
 			id : vid,
-			name : v.name,
+			name : vname,
 			type : v.type,
 			kind : v.kind,
 			qualifiers : v.qualifiers,
@@ -217,16 +224,22 @@ class Linker {
 		return s2.priority - s1.priority;
 	}
 	
-	function buildDependency( parent : ShaderInfos, v : AllocatedVar ) {
+	function buildDependency( parent : ShaderInfos, v : AllocatedVar, isWritten : Bool ) {
+		var found = !isWritten;
 		for( s in shaders ) {
-			if( !s.write.exists(v.id) || parent == s )
+			if( parent == s ) {
+				found = true;
+				continue;
+			} else if( !found )
+				continue;
+			if( !s.write.exists(v.id) )
 				continue;
-			//trace(parent.name + " => " + s.name + " (" + v.path + ")");
+//			trace(parent.name + " => " + s.name + " (" + v.path + ")");
 			parent.deps.set(s, true);
 			if( s.deps == null ) {
 				s.deps = new Map();
 				for( r in s.read )
-					buildDependency(s, r);
+					buildDependency(s, r, s.write.exists(r.id));
 			}
 			if( !s.read.exists(v.id) )
 				return;
@@ -259,13 +272,19 @@ class Linker {
 		// globalize vars
 		for( s in shadersData ) {
 			for( v in s.vars ) {
+				// check name before rename
 				var kind = switch( v.name ) {
 				case "vertex": Vertex;
 				case "fragment": Fragment;
 				case "__init__": Init;
-				default: Function;
+				default: null;
 				}
-				allocVar(v, null).kind = kind;
+				var v = allocVar(v, null);
+				if( kind != null ) v.kind = kind;
+			}
+			for( f in s.funs ) {
+				var v = allocVar(f.ref, f.expr.p);
+				if( v.kind == Var ) v.kind = Function;
 			}
 		}
 		
@@ -294,7 +313,7 @@ class Linker {
 						expr : mapExprVar(f.expr),
 					});
 				case Var:
-					throw "assert";
+					throw "assert "+v.v.name;
 				}
 			}
 			priority++;
@@ -308,7 +327,7 @@ class Linker {
 			var v = varMap.get(outVar);
 			if( v == null )
 				throw "Variable not found " + outVar;
-			buildDependency(s, v);
+			buildDependency(s, v, false);
 		}
 		
 		// collect needed dependencies

+ 5 - 8
test/Test.hx

@@ -150,10 +150,7 @@ static var SRC = {
 	
 	var transformedPosition : Vec3;
 	var transformedNormal : Vec3; // will be tagged as read in either vertex or fragment depending on conditional
-	
-	@private var color : Vec3; // will be tagged as written in vertex and read in fragment if !perPixel, or unused either
-	
-	var pixelColor : Vec4; // will be tagged as read+written in fragment
+	var pixelColor : Vec4;
 
 	function calcLight() : Vec3 {
 		var col = light.ambient;
@@ -170,14 +167,12 @@ static var SRC = {
 	}
 	
 	function vertex() {
-		if( !light.perPixel ) color = calcLight();
+		if( !light.perPixel ) pixelColor.rgb *= calcLight();
 	}
 	
 	function fragment() {
 		if( light.perPixel )
 			pixelColor.rgb *= calcLight();
-		else
-			pixelColor.rgb *= color;
 	}
 
 }
@@ -343,11 +338,13 @@ class Test {
 	static function main() {
 		var shaders = [
 			new Proto(),
+			new LightSystem(),
 			{ var t = new Texture(); t.killAlpha = true; t; },
 			new AnimatedUV(),
-		//	new Outline(),
+			//new AnimatedUV(),
 		];
 		var globals = new hxsl.Globals();
+		//globals.set("light.perPixel", true);
 		var instances = [for( s in shaders ) { s.updateConstants(globals); s.instance; }];
 		var cache = hxsl.Cache.get();
 		var s = cache.link(instances, cache.allocOutputVars(["output.position", "output.color"]));