| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 | class WebGPUAttributes {	constructor( device ) {		this.buffers = new WeakMap();		this.device = device;	}	get( attribute ) {		if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;		return this.buffers.get( attribute );	}	remove( attribute ) {		if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;		const data = this.buffers.get( attribute );		if ( data ) {			data.buffer.destroy();			this.buffers.delete( attribute );		}	}	update( attribute, isIndex = false, usage = null ) {		if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;		let data = this.buffers.get( attribute );		if ( data === undefined ) {			if ( usage === null ) {				usage = ( isIndex === true ) ? GPUBufferUsage.INDEX : GPUBufferUsage.VERTEX;			}			data = this._createBuffer( attribute, usage );			this.buffers.set( attribute, data );		} else if ( usage && usage !== data.usage ) {			data.buffer.destroy();			data = this._createBuffer( attribute, usage );			this.buffers.set( attribute, data );		} else if ( data.version < attribute.version ) {			this._writeBuffer( data.buffer, attribute );			data.version = attribute.version;		}	}	_createBuffer( attribute, usage ) {		const array = attribute.array;		const size = array.byteLength + ( ( 4 - ( array.byteLength % 4 ) ) % 4 ); // ensure 4 byte alignment, see #20441		const buffer = this.device.createBuffer( {			size: size,			usage: usage | GPUBufferUsage.COPY_DST,			mappedAtCreation: true,		} );		new array.constructor( buffer.getMappedRange() ).set( array );		buffer.unmap();		attribute.onUploadCallback();		return {			version: attribute.version,			buffer: buffer,			usage: usage		};	}	_writeBuffer( buffer, attribute ) {		const array = attribute.array;		const updateRange = attribute.updateRange;		if ( updateRange.count === - 1 ) {			// Not using update ranges			this.device.queue.writeBuffer(				buffer,				0,				array,				0			);		} else {			this.device.queue.writeBuffer(				buffer,				0,				array,				updateRange.offset * array.BYTES_PER_ELEMENT,				updateRange.count * array.BYTES_PER_ELEMENT			);			updateRange.count = - 1; // reset range		}	}}export default WebGPUAttributes;
 |