Skip to content

Commit 95cf8c4

Browse files
committed
WebGPURenderer: Don't set redundant state
1 parent c9ce570 commit 95cf8c4

File tree

5 files changed

+56
-10
lines changed

5 files changed

+56
-10
lines changed

examples/jsm/renderers/common/Attributes.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ class Attributes extends DataMap {
6262

6363
}
6464

65+
getUUID( attribute ) {
66+
67+
return this._getBufferAttribute( attribute ).uuid;
68+
69+
}
70+
6571
_getBufferAttribute( attribute ) {
6672

6773
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;

examples/jsm/renderers/common/RenderObject.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ let id = 0;
22

33
export default class RenderObject {
44

5-
constructor( nodes, geometries, renderer, object, material, scene, camera, lightsNode ) {
5+
constructor( nodes, attributes, geometries, renderer, object, material, scene, camera, lightsNode ) {
66

77
this._nodes = nodes;
8+
this._attributes = attributes;
89
this._geometries = geometries;
910

1011
this.id = id ++;
@@ -72,6 +73,18 @@ export default class RenderObject {
7273

7374
}
7475

76+
getAttributeHash( index ) {
77+
78+
return this._attributes.getUUID( this.getAttributes()[ index ] );
79+
80+
}
81+
82+
getIndexHash() {
83+
84+
return this._attributes.getUUID( this.getIndex() );
85+
86+
}
87+
7588
getCacheKey() {
7689

7790
const { material, scene, lightsNode } = this;

examples/jsm/renderers/common/RenderObjects.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import RenderObject from './RenderObject.js';
44

55
class RenderObjects extends ChainMap {
66

7-
constructor( renderer, nodes, geometries, pipelines, info ) {
7+
constructor( renderer, nodes, attributes, geometries, pipelines, info ) {
88

99
super();
1010

1111
this.renderer = renderer;
1212
this.nodes = nodes;
13+
this.attributes = attributes;
1314
this.geometries = geometries;
1415
this.pipelines = pipelines;
1516
this.info = info;
@@ -26,7 +27,7 @@ class RenderObjects extends ChainMap {
2627

2728
if ( renderObject === undefined ) {
2829

29-
renderObject = new RenderObject( this.nodes, this.geometries, this.renderer, object, material, scene, camera, lightsNode );
30+
renderObject = new RenderObject( this.nodes, this.attributes, this.geometries, this.renderer, object, material, scene, camera, lightsNode );
3031

3132
this._initRenderObject( renderObject );
3233

examples/jsm/renderers/common/Renderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class Renderer {
134134
this._textures = new Textures( backend, this._info );
135135
this._pipelines = new Pipelines( backend, this._nodes );
136136
this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this._info );
137-
this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._info );
137+
this._objects = new RenderObjects( this, this._nodes, this._attributes, this._geometries, this._pipelines, this._info );
138138
this._renderLists = new RenderLists();
139139
this._renderContexts = new RenderContexts();
140140

examples/jsm/renderers/webgpu/WebGPUBackend.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*// debugger utils
2+
import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js';
3+
//*/
4+
15
import { GPUFeatureName, GPUTextureFormat, GPULoadOp, GPUStoreOp, GPUIndexFormat, GPUTextureViewDimension } from './utils/WebGPUConstants.js';
26

37
import WebGPUNodeBuilder from './nodes/WGSLNodeBuilder.js';
@@ -243,6 +247,7 @@ class WebGPUBackend extends Backend {
243247
renderContextData.descriptor = descriptor;
244248
renderContextData.encoder = encoder;
245249
renderContextData.currentPass = currentPass;
250+
renderContextData.currentAttributesSet = {};
246251

247252
//
248253

@@ -395,6 +400,7 @@ class WebGPUBackend extends Backend {
395400
const bindingsData = this.get( renderObject.getBindings() );
396401
const contextData = this.get( context );
397402
const pipelineGPU = this.get( pipeline ).pipeline;
403+
const attributesSet = contextData.currentAttributesSet;
398404

399405
// pipeline
400406

@@ -406,18 +412,28 @@ class WebGPUBackend extends Backend {
406412
const bindGroupGPU = bindingsData.group;
407413
passEncoderGPU.setBindGroup( 0, bindGroupGPU );
408414

409-
// index
415+
// attributes
410416

411417
const index = renderObject.getIndex();
412418

413419
const hasIndex = ( index !== null );
414420

421+
// index
422+
415423
if ( hasIndex === true ) {
416424

417-
const buffer = this.get( index ).buffer;
418-
const indexFormat = ( index.array instanceof Uint16Array ) ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32;
425+
const indexHash = renderObject.getIndexHash();
419426

420-
passEncoderGPU.setIndexBuffer( buffer, indexFormat );
427+
if ( attributesSet.index !== indexHash ) {
428+
429+
const buffer = this.get( index ).buffer;
430+
const indexFormat = ( index.array instanceof Uint16Array ) ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32;
431+
432+
passEncoderGPU.setIndexBuffer( buffer, indexFormat );
433+
434+
attributesSet.index = indexHash;
435+
436+
}
421437

422438
}
423439

@@ -427,8 +443,17 @@ class WebGPUBackend extends Backend {
427443

428444
for ( let i = 0, l = attributes.length; i < l; i ++ ) {
429445

430-
const buffer = this.get( attributes[ i ] ).buffer;
431-
passEncoderGPU.setVertexBuffer( i, buffer );
446+
const attribute = attributes[ i ];
447+
const attributeHash = renderObject.getAttributeHash( i );
448+
449+
if ( attributesSet[ i ] !== attributeHash ) {
450+
451+
const buffer = this.get( attribute ).buffer;
452+
passEncoderGPU.setVertexBuffer( i, buffer );
453+
454+
attributesSet[ i ] = attributeHash;
455+
456+
}
432457

433458
}
434459

@@ -703,6 +728,7 @@ class WebGPUBackend extends Backend {
703728
if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load;
704729

705730
renderContextData.currentPass = encoder.beginRenderPass( descriptor );
731+
renderContextData.currentAttributesSet = {};
706732

707733
}
708734

0 commit comments

Comments
 (0)