Skip to content

Commit bb7f17a

Browse files
aardgooseaardgoose
andauthored
WebGPURenderer: Per "texture set" bindGroup caching. (#29845)
* prototype per texture set bindgroup * lint * add cache versioning --------- Co-authored-by: aardgoose <[email protected]>
1 parent 91147e9 commit bb7f17a

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

examples/jsm/tsl/display/GaussianBlurNode.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import { TempNode, nodeObject, Fn, If, float, NodeUpdateType, uv, uniform, conve
44
// WebGPU: The use of a single QuadMesh for both gaussian blur passes results in a single RenderObject with a SampledTexture binding that
55
// alternates between source textures and triggers creation of new BindGroups and BindGroupLayouts every frame.
66

7-
const _quadMesh1 = /*@__PURE__*/ new QuadMesh();
8-
const _quadMesh2 = /*@__PURE__*/ new QuadMesh();
7+
const _quadMesh = /*@__PURE__*/ new QuadMesh();
98

109
let _rendererState;
1110

@@ -108,8 +107,7 @@ class GaussianBlurNode extends TempNode {
108107

109108
const currentTexture = textureNode.value;
110109

111-
_quadMesh1.material = this._material;
112-
_quadMesh2.material = this._material;
110+
_quadMesh.material = this._material;
113111

114112
this.setSize( map.image.width, map.image.height );
115113

@@ -124,7 +122,7 @@ class GaussianBlurNode extends TempNode {
124122

125123
this._passDirection.value.set( 1, 0 );
126124

127-
_quadMesh1.render( renderer );
125+
_quadMesh.render( renderer );
128126

129127
// vertical
130128

@@ -133,7 +131,7 @@ class GaussianBlurNode extends TempNode {
133131

134132
this._passDirection.value.set( 0, 1 );
135133

136-
_quadMesh2.render( renderer );
134+
_quadMesh.render( renderer );
137135

138136
// restore
139137

src/renderers/common/Bindings.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Bindings extends DataMap {
3232

3333
this._init( bindGroup );
3434

35-
this.backend.createBindings( bindGroup, bindings );
35+
this.backend.createBindings( bindGroup, bindings, 0 );
3636

3737
groupData.bindGroup = bindGroup;
3838

@@ -56,7 +56,7 @@ class Bindings extends DataMap {
5656

5757
this._init( bindGroup );
5858

59-
this.backend.createBindings( bindGroup, bindings );
59+
this.backend.createBindings( bindGroup, bindings, 0 );
6060

6161
groupData.bindGroup = bindGroup;
6262

@@ -116,6 +116,9 @@ class Bindings extends DataMap {
116116
const { backend } = this;
117117

118118
let needsBindingsUpdate = false;
119+
let cacheBindings = true;
120+
let cacheIndex = 0;
121+
let version = 0;
119122

120123
// iterate over all bindings and check if buffer updates or a new binding group is required
121124

@@ -145,7 +148,9 @@ class Bindings extends DataMap {
145148

146149
} else if ( binding.isSampledTexture ) {
147150

148-
if ( binding.needsBindingsUpdate( this.textures.get( binding.texture ).generation ) ) needsBindingsUpdate = true;
151+
const texturesTextureData = this.textures.get( binding.texture );
152+
153+
if ( binding.needsBindingsUpdate( texturesTextureData.generation ) ) needsBindingsUpdate = true;
149154

150155
const updated = binding.update();
151156

@@ -159,6 +164,17 @@ class Bindings extends DataMap {
159164

160165
const textureData = backend.get( texture );
161166

167+
if ( textureData.externalTexture !== undefined || texturesTextureData.isDefaultTexture ) {
168+
169+
cacheBindings = false;
170+
171+
} else {
172+
173+
cacheIndex = cacheIndex * 10 + texture.id;
174+
version += texture.version;
175+
176+
}
177+
162178
if ( backend.isWebGPUBackend === true && textureData.texture === undefined && textureData.externalTexture === undefined ) {
163179

164180
// TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend
@@ -193,7 +209,7 @@ class Bindings extends DataMap {
193209

194210
if ( needsBindingsUpdate === true ) {
195211

196-
this.backend.updateBindings( bindGroup, bindings );
212+
this.backend.updateBindings( bindGroup, bindings, cacheBindings ? cacheIndex : 0, version );
197213

198214
}
199215

src/renderers/webgpu/WebGPUBackend.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,15 +1361,15 @@ class WebGPUBackend extends Backend {
13611361

13621362
// bindings
13631363

1364-
createBindings( bindGroup ) {
1364+
createBindings( bindGroup, bindings, cacheIndex, version ) {
13651365

1366-
this.bindingUtils.createBindings( bindGroup );
1366+
this.bindingUtils.createBindings( bindGroup, bindings, cacheIndex, version );
13671367

13681368
}
13691369

1370-
updateBindings( bindGroup ) {
1370+
updateBindings( bindGroup, bindings, cacheIndex, version ) {
13711371

1372-
this.bindingUtils.createBindings( bindGroup );
1372+
this.bindingUtils.createBindings( bindGroup, bindings, cacheIndex, version );
13731373

13741374
}
13751375

src/renderers/webgpu/utils/WebGPUBindingUtils.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class WebGPUBindingUtils {
140140

141141
}
142142

143-
createBindings( bindGroup ) {
143+
createBindings( bindGroup, bindings, cacheIndex, version = 0 ) {
144144

145145
const { backend, bindGroupLayoutCache } = this;
146146
const bindingsData = backend.get( bindGroup );
@@ -156,10 +156,40 @@ class WebGPUBindingUtils {
156156

157157
}
158158

159-
const bindGroupGPU = this.createBindGroup( bindGroup, bindLayoutGPU );
159+
let bindGroupGPU;
160+
161+
if ( cacheIndex > 0 ) {
162+
163+
if ( bindingsData.groups === undefined ) {
164+
165+
bindingsData.groups = [];
166+
bindingsData.versions = [];
167+
168+
}
169+
170+
if ( bindingsData.versions[ cacheIndex ] === version ) {
171+
172+
bindGroupGPU = bindingsData.groups[ cacheIndex ];
173+
174+
}
175+
176+
}
177+
178+
if ( bindGroupGPU === undefined ) {
179+
180+
bindGroupGPU = this.createBindGroup( bindGroup, bindLayoutGPU );
181+
182+
if ( cacheIndex > 0 ) {
183+
184+
bindingsData.groups[ cacheIndex ] = bindGroupGPU;
185+
bindingsData.versions[ cacheIndex ] = version;
186+
187+
}
188+
189+
}
160190

161-
bindingsData.layout = bindLayoutGPU;
162191
bindingsData.group = bindGroupGPU;
192+
bindingsData.layout = bindLayoutGPU;
163193

164194
}
165195

0 commit comments

Comments
 (0)