Accueil / npm / three@0.186.1 / src / nodes / gpgpu / BarrierNode.js

BarrierNode.js

import { error } from '../../utils.js';
import Node from '../core/Node.js';
import { nodeProxy } from '../tsl/TSLCore.js';

/**
 * Represents a GPU control barrier that synchronizes compute operations within a given scope.
 *
 * This node can only be used with a WebGPU backend.
 *
 * @augments Node
 */
class BarrierNode extends Node {

	/**
	 * Constructs a new barrier node.
	 *
	 * @param {string} scope - The scope defines the behavior of the node.
	 */
	constructor( scope ) {

		super();

		this.scope = scope;

		this.isBarrierNode = true;

	}

	setup( builder ) {

		builder.allowEarlyReturns = false;
		builder.allowGlobalVariables = false;

	}

	generate( builder ) {

		const { scope } = this;
		const { renderer, shaderStage } = builder;

		const barrierMethod = `${scope}Barrier`;

		if ( shaderStage !== 'compute' ) {

			error( `TSL: "${barrierMethod}" is not supported in the ${shaderStage} stage and can only be executed in compute.` );

		}

		if ( renderer.backend.isWebGLBackend === true ) {

			builder.addFlowCode( `\t// ${barrierMethod}() \n` );

		} else {

			builder.addLineFlowCode( `${barrierMethod}()`, this );

		}

	}

}

export default BarrierNode;

/**
 * TSL function for creating a barrier node.
 *
 * @tsl
 * @function
 * @param {string} scope - The scope defines the behavior of the node..
 * @returns {BarrierNode}
 */
const barrier = /*@__PURE__*/ nodeProxy( BarrierNode );

/**
 * TSL function for creating a workgroup barrier. All compute shader
 * invocations must wait for each invocation within a workgroup to
 * complete before the barrier can be surpassed.
 *
 * @tsl
 * @function
 * @returns {BarrierNode}
 */
export const workgroupBarrier = () => barrier( 'workgroup' ).toStack();

/**
 * TSL function for creating a storage barrier. All invocations must
 * wait for each access to variables within the 'storage' address space
 * to complete before the barrier can be passed.
 *
 * @tsl
 * @function
 * @returns {BarrierNode}
 */
export const storageBarrier = () => barrier( 'storage' ).toStack();

/**
 * TSL function for creating a texture barrier. All invocations must
 * wait for each access to variables within the 'texture' address space
 * to complete before the barrier can be passed.
 *
 * @tsl
 * @function
 * @returns {BarrierNode}
 */
export const textureBarrier = () => barrier( 'texture' ).toStack();