diff --git a/src/nodes/core/NodeBuilder.js b/src/nodes/core/NodeBuilder.js index 095186daabdde4..61e258a8f0532f 100644 --- a/src/nodes/core/NodeBuilder.js +++ b/src/nodes/core/NodeBuilder.js @@ -277,6 +277,23 @@ class NodeBuilder { } + sortBindingGroups() { + + const bindingsGroups = this.getBindings(); + + bindingsGroups.sort( ( a, b ) => ( a.bindings[ 0 ].groupNode.order - b.bindings[ 0 ].groupNode.order ) ); + + for ( let i = 0; i < bindingsGroups.length; i ++ ) { + + const bindingGroup = bindingsGroups[ i ]; + this.bindingsIndexes[ bindingGroup.name ].group = i; + + bindingGroup.index = i; + + } + + } + setHashNode( node, hash ) { this.hashNodes[ hash ] = node; diff --git a/src/nodes/core/UniformGroupNode.js b/src/nodes/core/UniformGroupNode.js index b1416f29fd23cc..b3848c749f4bee 100644 --- a/src/nodes/core/UniformGroupNode.js +++ b/src/nodes/core/UniformGroupNode.js @@ -8,7 +8,7 @@ class UniformGroupNode extends Node { } - constructor( name, shared = false ) { + constructor( name, shared = false, order = 1 ) { super( 'string' ); @@ -16,7 +16,7 @@ class UniformGroupNode extends Node { this.version = 0; this.shared = shared; - + this.order = order; this.isUniformGroup = true; } @@ -52,7 +52,7 @@ class UniformGroupNode extends Node { export default UniformGroupNode; export const uniformGroup = ( name ) => new UniformGroupNode( name ); -export const sharedUniformGroup = ( name ) => new UniformGroupNode( name, true ); +export const sharedUniformGroup = ( name, order = 0 ) => new UniformGroupNode( name, true, order ); export const frameGroup = /*@__PURE__*/ sharedUniformGroup( 'frame' ); export const renderGroup = /*@__PURE__*/ sharedUniformGroup( 'render' ); diff --git a/src/renderers/webgpu/WebGPUBackend.js b/src/renderers/webgpu/WebGPUBackend.js index db364c260ce977..eb1284a875e389 100644 --- a/src/renderers/webgpu/WebGPUBackend.js +++ b/src/renderers/webgpu/WebGPUBackend.js @@ -425,7 +425,7 @@ class WebGPUBackend extends Backend { renderContextData.descriptor = descriptor; renderContextData.encoder = encoder; renderContextData.currentPass = currentPass; - renderContextData.currentSets = { attributes: {}, pipeline: null, index: null }; + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; renderContextData.renderBundles = []; // @@ -848,12 +848,19 @@ class WebGPUBackend extends Backend { // bind groups + const currentBindingGroups = currentSets.bindingGroups; + for ( let i = 0, l = bindings.length; i < l; i ++ ) { const bindGroup = bindings[ i ]; const bindingsData = this.get( bindGroup ); - passEncoderGPU.setBindGroup( bindGroup.index, bindingsData.group ); + if ( currentBindingGroups[ bindGroup.index ] !== bindGroup.id ) { + + passEncoderGPU.setBindGroup( bindGroup.index, bindingsData.group ); + currentBindingGroups[ bindGroup.index ] = bindGroup.id; + + } } @@ -1286,7 +1293,7 @@ class WebGPUBackend extends Backend { renderContextData._currentPass = renderContextData.currentPass; renderContextData._currentSets = renderContextData.currentSets; - renderContextData.currentSets = { attributes: {}, pipeline: null, index: null }; + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; renderContextData.currentPass = this.pipelineUtils.createBundleEncoder( renderContext ); } @@ -1515,7 +1522,7 @@ class WebGPUBackend extends Backend { if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; renderContextData.currentPass = encoder.beginRenderPass( descriptor ); - renderContextData.currentSets = { attributes: {}, pipeline: null, index: null }; + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; } diff --git a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js index 148ed2940ce8d4..3bfe929bd850db 100644 --- a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +++ b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js @@ -1043,6 +1043,8 @@ ${ flowData.code } const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; + this.sortBindingGroups(); + for ( const shaderStage in shadersData ) { const stageData = shadersData[ shaderStage ];