three
Version:
JavaScript 3D library
108 lines (79 loc) • 2.37 kB
JavaScript
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();