Просмотр исходного кода

TSL: Make sure structs are built when compiling functions. (#33524)

Co-authored-by: sunag <sunagbrasil@gmail.com>
Michael Herzog 1 месяц назад
Родитель
Сommit
e7f41f980f
2 измененных файлов с 67 добавлено и 21 удалено
  1. 25 5
      src/nodes/core/NodeBuilder.js
  2. 42 16
      src/nodes/tsl/TSLCore.js

+ 25 - 5
src/nodes/core/NodeBuilder.js

@@ -35,6 +35,7 @@ import { warn, error, yieldToMain } from '../../utils.js';
 let _id = 0;
 
 const _bindingGroupsCache = new WeakMap();
+const _functionNodeCache = new WeakMap();
 
 const sharedNodeData = new WeakMap();
 
@@ -2378,15 +2379,34 @@ class NodeBuilder {
 	 */
 	buildFunctionNode( shaderNode ) {
 
-		const fn = new FunctionNode();
+		const backend = this.renderer.backend;
 
-		const previous = this.currentFunctionNode;
+		let cache = _functionNodeCache.get( backend );
 
-		this.currentFunctionNode = fn;
+		if ( cache === undefined ) {
 
-		fn.code = this.buildFunctionCode( shaderNode );
+			cache = new WeakMap();
+			_functionNodeCache.set( backend, cache );
 
-		this.currentFunctionNode = previous;
+		}
+
+		let fn = cache.get( shaderNode );
+
+		if ( fn === undefined ) {
+
+			fn = new FunctionNode();
+
+			const previous = this.currentFunctionNode;
+
+			this.currentFunctionNode = fn;
+
+			fn.code = this.buildFunctionCode( shaderNode );
+
+			this.currentFunctionNode = previous;
+
+			cache.set( shaderNode, fn );
+
+		}
 
 		return fn;
 

+ 42 - 16
src/nodes/tsl/TSLCore.js

@@ -291,8 +291,6 @@ Object.defineProperties( Node.prototype, proto );
 
 // --- FINISH ---
 
-const nodeBuilderFunctionsCacheMap = new WeakMap();
-
 const ShaderNodeObject = function ( obj, altType = null ) {
 
 	const type = getValueType( obj );
@@ -506,35 +504,59 @@ class ShaderCallNodeInternal extends Node {
 
 		if ( shaderNode.layout ) {
 
-			const backend = builder.renderer.backend;
+			// build inputs first
 
-			let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get( backend );
+			if ( rawInputs ) {
 
-			if ( functionNodesCacheMap === undefined ) {
+				// use layout inputs to ensure that no extra parameters are built
 
-				functionNodesCacheMap = new WeakMap();
+				const inputs = shaderNode.layout.inputs;
 
-				nodeBuilderFunctionsCacheMap.set( backend, functionNodesCacheMap );
+				if ( isArrayAsParameter( rawInputs ) ) {
 
-			}
+					const rawArrayParameters = rawInputs;
+
+					for ( let i = 0; i < inputs.length; i ++ ) {
+
+						const rawParameter = rawArrayParameters[ i ];
+
+						if ( rawParameter && rawParameter.isNode ) {
+
+							rawParameter.build( builder );
+
+						}
+
+					}
+
+				} else {
+
+					const rawObjectParameters = rawInputs[ 0 ];
 
-			let functionNode = functionNodesCacheMap.get( shaderNode );
+					for ( const param of inputs ) {
 
-			if ( functionNode === undefined ) {
+						const rawParameter = rawObjectParameters[ param.name ];
 
-				functionNode = nodeObject( builder.buildFunctionNode( shaderNode ) );
+						if ( rawParameter && rawParameter.isNode ) {
 
-				functionNodesCacheMap.set( shaderNode, functionNode );
+							rawParameter.build( builder );
+
+						}
+
+					}
+
+				}
 
 			}
 
+			const functionNode = builder.buildFunctionNode( shaderNode );
+
 			builder.addInclude( functionNode );
 
 			//
 
 			const inputs = rawInputs ? getLayoutParameters( rawInputs ) : null;
 
-			result = nodeObject( functionNode.call( inputs ) );
+			result = functionNode.call( inputs );
 
 		} else {
 
@@ -681,15 +703,19 @@ class ShaderCallNodeInternal extends Node {
 
 }
 
+function isArrayAsParameter( params ) {
+
+	return params[ 0 ] && ( params[ 0 ].isNode || Object.getPrototypeOf( params[ 0 ] ) !== Object.prototype );
+
+}
+
 function getLayoutParameters( params ) {
 
 	let output;
 
 	nodeObjects( params );
 
-	const isArrayAsParameter = params[ 0 ] && ( params[ 0 ].isNode || Object.getPrototypeOf( params[ 0 ] ) !== Object.prototype );
-
-	if ( isArrayAsParameter ) {
+	if ( isArrayAsParameter( params ) ) {
 
 		output = [ ...params ];
 

粤ICP备19079148号