Prechádzať zdrojové kódy

added MeshBatch.forcedPerInstance (cachefile not yet implemented)

Nicolas Cannasse 2 rokov pred
rodič
commit
d9cbd68021
3 zmenil súbory, kde vykonal 56 pridanie a 17 odobranie
  1. 4 2
      h3d/scene/MeshBatch.hx
  2. 43 9
      hxsl/Cache.hx
  3. 9 6
      hxsl/CacheFile.hx

+ 4 - 2
h3d/scene/MeshBatch.hx

@@ -68,11 +68,13 @@ class MeshBatch extends MultiMaterial {
 	public var primitiveSubPart : MeshBatchPart;
 	public var primitiveSubPart : MeshBatchPart;
 	var primitiveSubBytes : haxe.io.Bytes;
 	var primitiveSubBytes : haxe.io.Bytes;
 
 
-	/** 
+	/**
 		If set, exact bounds will be recalculated during emitInstance (default true)
 		If set, exact bounds will be recalculated during emitInstance (default true)
 	**/
 	**/
 	public var calcBounds = true;
 	public var calcBounds = true;
 
 
+	var forcedPerInstance : Array<{ shader : String, params : Array<String> }>;
+
 	public function new( primitive, ?material, ?parent ) {
 	public function new( primitive, ?material, ?parent ) {
 		instanced = new h3d.prim.Instanced();
 		instanced = new h3d.prim.Instanced();
 		instanced.commands = new h3d.impl.InstanceBuffer();
 		instanced.commands = new h3d.impl.InstanceBuffer();
@@ -120,7 +122,7 @@ class MeshBatch extends MultiMaterial {
 				var manager = cast(ctx,h3d.pass.Default).manager;
 				var manager = cast(ctx,h3d.pass.Default).manager;
 				var shaders = p.getShadersRec();
 				var shaders = p.getShadersRec();
 				var rt = manager.compileShaders(shaders, false);
 				var rt = manager.compileShaders(shaders, false);
-				var shader = manager.shaderCache.makeBatchShader(rt, shaders);
+				var shader = manager.shaderCache.makeBatchShader(rt, shaders, forcedPerInstance);
 
 
 				var b = new BatchData();
 				var b = new BatchData();
 				b.indexCount = matInfo.count;
 				b.indexCount = matInfo.count;

+ 43 - 9
hxsl/Cache.hx

@@ -42,7 +42,7 @@ class Cache {
 
 
 	var linkCache : SearchMap;
 	var linkCache : SearchMap;
 	var linkShaders : Map<String, Shader>;
 	var linkShaders : Map<String, Shader>;
-	var batchShaders : Map<RuntimeShader, { shader : SharedShader, params : RuntimeShader.AllocParam, size : Int }>;
+	var batchShaders : Map<RuntimeShader, Map<String,{ shader : SharedShader, params : RuntimeShader.AllocParam, size : Int }>>;
 	var byID : Map<String, RuntimeShader>;
 	var byID : Map<String, RuntimeShader>;
 	public var constsToGlobal : Bool;
 	public var constsToGlobal : Bool;
 
 
@@ -486,11 +486,21 @@ class Cache {
 		return c;
 		return c;
 	}
 	}
 
 
-	public function makeBatchShader( rt : RuntimeShader, shaders ) : BatchShader {
-		var sh = batchShaders.get(rt); // don't use rt.id to avoid collisions on identical signatures
+	public function makeBatchShader( rt : RuntimeShader, shaders, forcedPerInstance : Array<{ shader : String, params : Array<String> }> ) : BatchShader {
+		var msh = batchShaders.get(rt); // don't use rt.id to avoid collisions on identical signatures
+		if( msh == null ) {
+			msh = new Map();
+			batchShaders.set(rt, msh);
+		}
+		if( forcedPerInstance != null ) {
+			for( fp in forcedPerInstance )
+				fp.params.sort(Reflect.compare);
+		}
+		var sign = forcedPerInstance == null ? "" : haxe.crypto.Md5.encode([for( s in forcedPerInstance ) s.shader+"="+s.params.join(",")].join(";")).substr(0,8);
+		var sh = msh.get(sign);
 		if( sh == null ) {
 		if( sh == null ) {
-			sh = createBatchShader(rt, shaders);
-			batchShaders.set(rt,sh);
+			sh = createBatchShader(rt, shaders, forcedPerInstance, forcedPerInstance == null ? null : sign);
+			msh.set(sign,sh);
 		}
 		}
 		var shader = std.Type.createEmptyInstance(BatchShader);
 		var shader = std.Type.createEmptyInstance(BatchShader);
 		@:privateAccess shader.shader = sh.shader;
 		@:privateAccess shader.shader = sh.shader;
@@ -508,9 +518,9 @@ class Cache {
 		return false;
 		return false;
 	}
 	}
 
 
-	function createBatchShader( rt : RuntimeShader, shaders : hxsl.ShaderList ) : { shader : SharedShader, params : RuntimeShader.AllocParam, size : Int } {
+	function createBatchShader( rt : RuntimeShader, shaders : hxsl.ShaderList, forcedPerInstance : Array<{ shader : String, params : Array<String> }>, extraSign : String ) : { shader : SharedShader, params : RuntimeShader.AllocParam, size : Int } {
 		var s = new hxsl.SharedShader("");
 		var s = new hxsl.SharedShader("");
-		var id = rt.spec.signature.substr(0, 8);
+		var id = (extraSign == null ? rt.spec.signature : haxe.crypto.Md5.encode(rt.spec.signature + extraSign)).substr(0, 8);
 
 
 		function declVar( name, t, kind ) : TVar {
 		function declVar( name, t, kind ) : TVar {
 			return {
 			return {
@@ -521,6 +531,21 @@ class Cache {
 			};
 			};
 		}
 		}
 
 
+		var instancedParams = [];
+		if( forcedPerInstance != null ) {
+			var instanceIndex = 1;
+			var forcedIndex = forcedPerInstance.length - 1;
+			var s = shaders;
+			while( s != null && forcedIndex > 0 ) {
+				if( @:privateAccess s.s.shader.data.name == forcedPerInstance[forcedIndex].shader ) {
+					instancedParams[instanceIndex] = forcedPerInstance[forcedIndex].params;
+					forcedIndex--;
+				}
+				instanceIndex++;
+				s = s.next;
+			}
+		}
+
 		var pos = null;
 		var pos = null;
 
 
 		var hasOffset = declVar("Batch_HasOffset",TBool,Param);
 		var hasOffset = declVar("Batch_HasOffset",TBool,Param);
@@ -642,17 +667,26 @@ class Cache {
 			params = p2;
 			params = p2;
 		}
 		}
 
 
+		inline function isPerInstance(p:RuntimeShader.AllocParam,v) {
+			var params = instancedParams[p.instance];
+			if( params != null && params.indexOf(p.name) >= 0 )
+				return true;
+			if( this.isPerInstance(v) )
+				return true;
+			return false;
+		}
+
 		var p = rt.vertex.params;
 		var p = rt.vertex.params;
 		while( p != null ) {
 		while( p != null ) {
 			var v = getVar(p);
 			var v = getVar(p);
-			if( isPerInstance(v) )
+			if( isPerInstance(p, v) )
 				addParam(p);
 				addParam(p);
 			p = p.next;
 			p = p.next;
 		}
 		}
 		var p = rt.fragment.params;
 		var p = rt.fragment.params;
 		while( p != null ) {
 		while( p != null ) {
 			var v = getVar(p);
 			var v = getVar(p);
-			if( isPerInstance(v) )
+			if( isPerInstance(p, v) )
 				addParam(p);
 				addParam(p);
 			p = p.next;
 			p = p.next;
 		}
 		}

+ 9 - 6
hxsl/CacheFile.hx

@@ -31,7 +31,7 @@ class CacheFile extends Cache {
 	var shaders : Map<String,{ shader : SharedShader, version : String }> = new Map();
 	var shaders : Map<String,{ shader : SharedShader, version : String }> = new Map();
 	var runtimeShaders : Array<RuntimeShader> = [];
 	var runtimeShaders : Array<RuntimeShader> = [];
 	var linkers : Array<{ shader : Shader, vars : Array<hxsl.Output> }> = [];
 	var linkers : Array<{ shader : Shader, vars : Array<hxsl.Output> }> = [];
-	var batchers : Array<{ shader : SharedShader, rt : RuntimeShader }> = [];
+	var batchers : Array<{ shader : SharedShader, rt : RuntimeShader, instance : Array<{shader:String,params:Array<String>}> }> = [];
 
 
 	// sources
 	// sources
 	var compiledSources : Map<String,{ vertex : String, fragment : String }> = new Map();
 	var compiledSources : Map<String,{ vertex : String, fragment : String }> = new Map();
@@ -69,9 +69,9 @@ class CacheFile extends Cache {
 		return shader;
 		return shader;
 	}
 	}
 
 
-	override function createBatchShader( rt, shaders ) {
-		var b = super.createBatchShader(rt, shaders);
-		batchers.push({ rt : rt, shader : b.shader });
+	override function createBatchShader( rt, shaders, perInstance, sign ) {
+		var b = super.createBatchShader(rt, shaders, perInstance, sign);
+		batchers.push({ rt : rt, shader : b.shader, instance : perInstance });
 		return b;
 		return b;
 	}
 	}
 
 
@@ -263,7 +263,7 @@ class CacheFile extends Cache {
 								r = null; // was modified
 								r = null; // was modified
 								break;
 								break;
 							}
 							}
-							var sh = makeBatchShader(rt.rt, rt.shaders);
+							var sh = makeBatchShader(rt.rt, rt.shaders, null);
 							i.shader = { version : null, shader : sh.shader };
 							i.shader = { version : null, shader : sh.shader };
 							batchMode = true;
 							batchMode = true;
 						}
 						}
@@ -315,7 +315,7 @@ class CacheFile extends Cache {
 								r = null; // was modified
 								r = null; // was modified
 								break;
 								break;
 							}
 							}
-							var sh = makeBatchShader(rt.rt, rt.shaders);
+							var sh = makeBatchShader(rt.rt, rt.shaders, null);
 							i.shader = { version : null, shader : sh.shader };
 							i.shader = { version : null, shader : sh.shader };
 							r.batchMode = true;
 							r.batchMode = true;
 						}
 						}
@@ -477,6 +477,9 @@ class CacheFile extends Cache {
 			separator();
 			separator();
 			writeString(@:privateAccess b.shader.data.name);
 			writeString(@:privateAccess b.shader.data.name);
 			writeString(@:privateAccess b.rt.spec.signature);
 			writeString(@:privateAccess b.rt.spec.signature);
+			if( b.instance != null ) {
+				throw "Not implemented";
+			}
 		}
 		}
 		separator();
 		separator();
 		writeString(null);
 		writeString(null);