فهرست منبع

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

Nicolas Cannasse 11 سال پیش
والد
کامیت
a4ae53b78a
2فایلهای تغییر یافته به همراه35 افزوده شده و 19 حذف شده
  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"]));