Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions src/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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;

Expand Down
58 changes: 42 additions & 16 deletions src/nodes/tsl/TSLCore.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,6 @@ Object.defineProperties( Node.prototype, proto );

// --- FINISH ---

const nodeBuilderFunctionsCacheMap = new WeakMap();

const ShaderNodeObject = function ( obj, altType = null ) {

const type = getValueType( obj );
Expand Down Expand Up @@ -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 {

Expand Down Expand Up @@ -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 ];

Expand Down
14 changes: 11 additions & 3 deletions src/renderers/common/Bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,20 @@ class Bindings extends DataMap {
const bindings = this.nodes.getForCompute( computeNode ).bindings;
const computeNodeData = this.get( computeNode );

if ( computeNodeData.initialized !== true ) {
if ( computeNodeData.initialized !== true || computeNodeData.bindings !== bindings ) {

// bind groups are created once per object
// bind groups are created once per compute node version

if ( computeNodeData.bindings !== undefined ) {

this._destroyBindings( computeNodeData.bindings );

}

this._createBindings( bindings );

computeNodeData.initialized = true;
computeNodeData.bindings = bindings;

}

Expand Down Expand Up @@ -149,7 +156,8 @@ class Bindings extends DataMap {
*/
deleteForCompute( computeNode ) {

const bindings = this.nodes.getForCompute( computeNode ).bindings;
const computeNodeData = this.get( computeNode );
const bindings = computeNodeData.bindings || this.nodes.getForCompute( computeNode ).bindings;

this._destroyBindings( bindings );

Expand Down
3 changes: 2 additions & 1 deletion src/renderers/common/nodes/NodeManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,14 +448,15 @@ class NodeManager extends DataMap {

let nodeBuilderState = computeData.nodeBuilderState;

if ( nodeBuilderState === undefined ) {
if ( nodeBuilderState === undefined || computeData.version !== computeNode.version ) {

const nodeBuilder = this.backend.createNodeBuilder( computeNode, this.renderer );
nodeBuilder.build();

nodeBuilderState = this._createNodeBuilderState( nodeBuilder );

computeData.nodeBuilderState = nodeBuilderState;
computeData.version = computeNode.version;

}

Expand Down