Skip to content

Commit d31f771

Browse files
authored
WebGPURenderer: Improve cache bindings from node uniforms (#32244)
1 parent 91a913b commit d31f771

File tree

5 files changed

+90
-22
lines changed

5 files changed

+90
-22
lines changed

src/nodes/core/NodeBuilder.js

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import { warn, error } from '../../utils.js';
3535

3636
let _id = 0;
3737

38+
const sharedNodeData = new WeakMap();
39+
3840
const rendererCache = new WeakMap();
3941

4042
const typeFromArray = new Map( [
@@ -2951,6 +2953,26 @@ class NodeBuilder {
29512953

29522954
}
29532955

2956+
/**
2957+
* Returns shared data object for the given node.
2958+
*
2959+
* @param {Node} node - The node to get shared data from.
2960+
* @return {Object} The shared data.
2961+
*/
2962+
getSharedDataFromNode( node ) {
2963+
2964+
let data = sharedNodeData.get( node );
2965+
2966+
if ( data === undefined ) {
2967+
2968+
data = {};
2969+
2970+
}
2971+
2972+
return data;
2973+
2974+
}
2975+
29542976
/**
29552977
* Returns a uniform representation which is later used for UBO generation and rendering.
29562978
*
@@ -2960,16 +2982,31 @@ class NodeBuilder {
29602982
*/
29612983
getNodeUniform( uniformNode, type ) {
29622984

2963-
if ( type === 'float' || type === 'int' || type === 'uint' ) return new NumberNodeUniform( uniformNode );
2964-
if ( type === 'vec2' || type === 'ivec2' || type === 'uvec2' ) return new Vector2NodeUniform( uniformNode );
2965-
if ( type === 'vec3' || type === 'ivec3' || type === 'uvec3' ) return new Vector3NodeUniform( uniformNode );
2966-
if ( type === 'vec4' || type === 'ivec4' || type === 'uvec4' ) return new Vector4NodeUniform( uniformNode );
2967-
if ( type === 'color' ) return new ColorNodeUniform( uniformNode );
2968-
if ( type === 'mat2' ) return new Matrix2NodeUniform( uniformNode );
2969-
if ( type === 'mat3' ) return new Matrix3NodeUniform( uniformNode );
2970-
if ( type === 'mat4' ) return new Matrix4NodeUniform( uniformNode );
2985+
const nodeData = this.getSharedDataFromNode( uniformNode );
2986+
2987+
let node = nodeData.cache;
2988+
2989+
if ( node === undefined ) {
2990+
2991+
if ( type === 'float' || type === 'int' || type === 'uint' ) node = new NumberNodeUniform( uniformNode );
2992+
else if ( type === 'vec2' || type === 'ivec2' || type === 'uvec2' ) node = new Vector2NodeUniform( uniformNode );
2993+
else if ( type === 'vec3' || type === 'ivec3' || type === 'uvec3' ) node = new Vector3NodeUniform( uniformNode );
2994+
else if ( type === 'vec4' || type === 'ivec4' || type === 'uvec4' ) node = new Vector4NodeUniform( uniformNode );
2995+
else if ( type === 'color' ) node = new ColorNodeUniform( uniformNode );
2996+
else if ( type === 'mat2' ) node = new Matrix2NodeUniform( uniformNode );
2997+
else if ( type === 'mat3' ) node = new Matrix3NodeUniform( uniformNode );
2998+
else if ( type === 'mat4' ) node = new Matrix4NodeUniform( uniformNode );
2999+
else {
3000+
3001+
throw new Error( `Uniform "${ type }" not implemented.` );
29713002

2972-
throw new Error( `Uniform "${type}" not declared.` );
3003+
}
3004+
3005+
nodeData.cache = node;
3006+
3007+
}
3008+
3009+
return node;
29733010

29743011
}
29753012

src/renderers/common/Binding.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ class Binding {
4444

4545
}
4646

47+
/**
48+
* The shader stages in which the binding's resource is visible.
49+
*
50+
* @return {number} The visibility bitmask.
51+
*/
52+
getVisibility() {
53+
54+
return this.visibility;
55+
56+
}
57+
4758
/**
4859
* Clones the binding.
4960
*

src/renderers/common/Bindings.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,14 @@ class Bindings extends DataMap {
251251

252252
for ( const binding of bindGroup.bindings ) {
253253

254-
if ( binding.isNodeUniformsGroup ) {
254+
const updatedGroup = this.nodes.updateGroup( binding );
255255

256-
const updated = this.nodes.updateGroup( binding );
256+
// every uniforms group is a uniform buffer. So if no update is required,
257+
// we move one with the next binding. Otherwise the next if block will update the group.
257258

258-
// every uniforms group is a uniform buffer. So if no update is required,
259-
// we move one with the next binding. Otherwise the next if block will update the group.
259+
if ( updatedGroup === false ) continue;
260260

261-
if ( updated === false ) continue;
262-
263-
}
261+
//
264262

265263
if ( binding.isStorageBuffer ) {
266264

src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,11 +1531,22 @@ void main() {
15311531

15321532
} else if ( type === 'buffer' ) {
15331533

1534-
node.name = `NodeBuffer_${ node.id }`;
15351534
uniformNode.name = `buffer${ node.id }`;
15361535

1537-
const buffer = new NodeUniformBuffer( node, group );
1538-
buffer.name = node.name;
1536+
const sharedData = this.getSharedDataFromNode( node );
1537+
1538+
let buffer = sharedData.buffer;
1539+
1540+
if ( buffer === undefined ) {
1541+
1542+
node.name = `NodeBuffer_${ node.id }`;
1543+
1544+
buffer = new NodeUniformBuffer( node, group );
1545+
buffer.name = node.name;
1546+
1547+
sharedData.buffer = buffer;
1548+
1549+
}
15391550

15401551
bindings.push( buffer );
15411552

src/renderers/webgpu/nodes/WGSLNodeBuilder.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -974,10 +974,21 @@ class WGSLNodeBuilder extends NodeBuilder {
974974

975975
} else if ( type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer' ) {
976976

977-
const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer;
977+
const sharedData = this.getSharedDataFromNode( node );
978978

979-
const buffer = new bufferClass( node, group );
980-
buffer.setVisibility( gpuShaderStageLib[ shaderStage ] );
979+
let buffer = sharedData.buffer;
980+
981+
if ( buffer === undefined ) {
982+
983+
const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer;
984+
985+
buffer = new bufferClass( node, group );
986+
987+
sharedData.buffer = buffer;
988+
989+
}
990+
991+
buffer.setVisibility( buffer.getVisibility() | gpuShaderStageLib[ shaderStage ] );
981992

982993
bindings.push( buffer );
983994

0 commit comments

Comments
 (0)