diff --git a/src/renderers/common/Attributes.js b/src/renderers/common/Attributes.js index 5be5dc85b66f68..3bb7c2ef32f402 100644 --- a/src/renderers/common/Attributes.js +++ b/src/renderers/common/Attributes.js @@ -49,6 +49,13 @@ class Attributes extends DataMap { if ( attributeData !== null ) { + + if ( attributeData.onDispose !== undefined ) { + + attribute.removeEventListener( 'dispose', attributeData.onDispose ); + + } + this.backend.destroyAttribute( attribute ); this.info.destroyAttribute( attribute ); @@ -69,6 +76,7 @@ class Attributes extends DataMap { update( attribute, type ) { const data = this.get( attribute ); + const bufferAttribute = this._getBufferAttribute( attribute ); if ( data.version === undefined ) { @@ -94,11 +102,19 @@ class Attributes extends DataMap { } - data.version = this._getBufferAttribute( attribute ).version; + // Standalone disposal is currently limited to WebGPU storage/indirect attributes. + // Other attribute types would require additional render-state invalidation before this is safe. - } else { + if ( this.backend.isWebGPUBackend === true && ( type === AttributeType.STORAGE || type === AttributeType.INDIRECT ) ) { - const bufferAttribute = this._getBufferAttribute( attribute ); + data.onDispose = () => this.delete( attribute ); + attribute.addEventListener( 'dispose', data.onDispose ); + + } + + data.version = bufferAttribute.version; + + } else { if ( data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage ) { diff --git a/src/renderers/common/Bindings.js b/src/renderers/common/Bindings.js index f2f906f55e9479..57e19d9e6071c1 100644 --- a/src/renderers/common/Bindings.js +++ b/src/renderers/common/Bindings.js @@ -325,6 +325,10 @@ class Bindings extends DataMap { if ( bindingData.attribute !== attribute ) { bindingData.attribute = attribute; + const bindGroupData = backend.get( bindGroup ); + + bindGroupData.groups = undefined; + bindGroupData.versions = undefined; needsBindingsUpdate = true;