174 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			174 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import DataMap from './DataMap.js'; | ||
|  | import { AttributeType } from './Constants.js'; | ||
|  | 
 | ||
|  | class Bindings extends DataMap { | ||
|  | 
 | ||
|  | 	constructor( backend, nodes, textures, attributes, pipelines, info ) { | ||
|  | 
 | ||
|  | 		super(); | ||
|  | 
 | ||
|  | 		this.backend = backend; | ||
|  | 		this.textures = textures; | ||
|  | 		this.pipelines = pipelines; | ||
|  | 		this.attributes = attributes; | ||
|  | 		this.nodes = nodes; | ||
|  | 		this.info = info; | ||
|  | 
 | ||
|  | 		this.pipelines.bindings = this; // assign bindings to pipelines
 | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	getForRender( renderObject ) { | ||
|  | 
 | ||
|  | 		const bindings = renderObject.getBindings(); | ||
|  | 
 | ||
|  | 		const data = this.get( renderObject ); | ||
|  | 
 | ||
|  | 		if ( data.bindings !== bindings ) { | ||
|  | 
 | ||
|  | 			// each object defines an array of bindings (ubos, textures, samplers etc.)
 | ||
|  | 
 | ||
|  | 			data.bindings = bindings; | ||
|  | 
 | ||
|  | 			this._init( bindings ); | ||
|  | 
 | ||
|  | 			this.backend.createBindings( bindings ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return data.bindings; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	getForCompute( computeNode ) { | ||
|  | 
 | ||
|  | 		const data = this.get( computeNode ); | ||
|  | 
 | ||
|  | 		if ( data.bindings === undefined ) { | ||
|  | 
 | ||
|  | 			const nodeBuilderState = this.nodes.getForCompute( computeNode ); | ||
|  | 
 | ||
|  | 			const bindings = nodeBuilderState.bindings; | ||
|  | 
 | ||
|  | 			data.bindings = bindings; | ||
|  | 
 | ||
|  | 			this._init( bindings ); | ||
|  | 
 | ||
|  | 			this.backend.createBindings( bindings ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return data.bindings; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	updateForCompute( computeNode ) { | ||
|  | 
 | ||
|  | 		this._update( computeNode, this.getForCompute( computeNode ) ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	updateForRender( renderObject ) { | ||
|  | 
 | ||
|  | 		this._update( renderObject, this.getForRender( renderObject ) ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	_init( bindings ) { | ||
|  | 
 | ||
|  | 		for ( const binding of bindings ) { | ||
|  | 
 | ||
|  | 			if ( binding.isSampledTexture ) { | ||
|  | 
 | ||
|  | 				this.textures.updateTexture( binding.texture ); | ||
|  | 
 | ||
|  | 			} else if ( binding.isStorageBuffer ) { | ||
|  | 
 | ||
|  | 				const attribute = binding.attribute; | ||
|  | 
 | ||
|  | 				this.attributes.update( attribute, AttributeType.STORAGE ); | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	_update( object, bindings ) { | ||
|  | 
 | ||
|  | 		const { backend } = this; | ||
|  | 
 | ||
|  | 		let needsBindingsUpdate = false; | ||
|  | 
 | ||
|  | 		// iterate over all bindings and check if buffer updates or a new binding group is required
 | ||
|  | 
 | ||
|  | 		for ( const binding of bindings ) { | ||
|  | 
 | ||
|  | 			if ( binding.isNodeUniformsGroup ) { | ||
|  | 
 | ||
|  | 				const updated = this.nodes.updateGroup( binding ); | ||
|  | 
 | ||
|  | 				if ( ! updated ) continue; | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if ( binding.isUniformBuffer ) { | ||
|  | 
 | ||
|  | 				const updated = binding.update(); | ||
|  | 
 | ||
|  | 				if ( updated ) { | ||
|  | 
 | ||
|  | 					backend.updateBinding( binding ); | ||
|  | 
 | ||
|  | 				} | ||
|  | 
 | ||
|  | 			} else if ( binding.isSampledTexture ) { | ||
|  | 
 | ||
|  | 				const texture = binding.texture; | ||
|  | 
 | ||
|  | 				if ( binding.needsBindingsUpdate ) needsBindingsUpdate = true; | ||
|  | 
 | ||
|  | 				const updated = binding.update(); | ||
|  | 
 | ||
|  | 				if ( updated ) { | ||
|  | 
 | ||
|  | 					this.textures.updateTexture( binding.texture ); | ||
|  | 
 | ||
|  | 				} | ||
|  | 
 | ||
|  | 				if ( texture.isStorageTexture === true ) { | ||
|  | 
 | ||
|  | 					const textureData = this.get( texture ); | ||
|  | 
 | ||
|  | 					if ( binding.store === true ) { | ||
|  | 
 | ||
|  | 						textureData.needsMipmap = true; | ||
|  | 
 | ||
|  | 					} else if ( texture.generateMipmaps === true && this.textures.needsMipmaps( texture ) && textureData.needsMipmap === true ) { | ||
|  | 
 | ||
|  | 						this.backend.generateMipmaps( texture ); | ||
|  | 
 | ||
|  | 						textureData.needsMipmap = false; | ||
|  | 
 | ||
|  | 					} | ||
|  | 
 | ||
|  | 				} | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( needsBindingsUpdate === true ) { | ||
|  | 
 | ||
|  | 			const pipeline = this.pipelines.getForRender( object ); | ||
|  | 
 | ||
|  | 			this.backend.updateBindings( bindings, pipeline ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | export default Bindings; |