mirror of
https://github.com/gpujs/gpu.js.git
synced 2026-01-18 16:04:10 +00:00
Internal Documentation: kernel.js (webgl)
This commit is contained in:
parent
f3e51e30e5
commit
fe78eb5d9e
@ -9,25 +9,39 @@ const kernelString = require('./kernel-string');
|
||||
///
|
||||
/// Class: WebGLKernel
|
||||
///
|
||||
/// Kernel Implementation for WebGL.
|
||||
/// This builds the shaders and runs them on the GPU,
|
||||
/// the outputs the result back as float(enabled by default) and Texture.
|
||||
///
|
||||
/// Extends:
|
||||
/// KernelBase
|
||||
///
|
||||
/// Parameters:
|
||||
/// textureCache - {Object} - webGl Texture cache
|
||||
/// threadDim - {Object} - The thread dimensions, x, y and z
|
||||
/// programUniformLocationCache - {Object} - Location of program variables in memory
|
||||
/// framebuffer - {Object} - Webgl frameBuffer
|
||||
/// buffer - {Object} - WebGL buffer
|
||||
/// program - {Object} - The webGl Program
|
||||
/// functionBuilder - {Object} - Function Builder instance bound to this Kernel
|
||||
/// outputToTexture - {Boolean} - Set output type to Texture, instead of float
|
||||
/// endianness - {String} - Endian information like Little-endian, Big-endian.
|
||||
/// paramTypes - {Array} - Types of parameters sent to the Kernel
|
||||
/// argumentsLength - {Number} - Number of parameters sent to the Kernel
|
||||
/// compiledFragShaderString - {String} - Compiled fragment shader string
|
||||
/// compiledVertShaderString - {String} - Compiled Vertical shader string
|
||||
///
|
||||
module.exports = class WebGLKernel extends KernelBase {
|
||||
_getFragShaderArtifactMap(args) {
|
||||
return {
|
||||
HEADER: this._getHeaderString(),
|
||||
LOOP_MAX: this._getLoopMaxString(),
|
||||
CONSTANTS: this._getConstantsString(),
|
||||
DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
|
||||
ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
|
||||
GET_WRAPAROUND: this._getGetWraparoundString(),
|
||||
GET_TEXTURE_CHANNEL: this._getGetTextureChannelString(),
|
||||
GET_TEXTURE_INDEX: this._getGetTextureIndexString(),
|
||||
GET_RESULT: this._getGetResultString(),
|
||||
MAIN_PARAMS: this._getMainParamsString(args),
|
||||
MAIN_CONSTANTS: this._getMainConstantsString(),
|
||||
KERNEL: this._getKernelString(),
|
||||
MAIN_RESULT: this._getMainResultString()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// [Constructor]
|
||||
//
|
||||
|
||||
///
|
||||
/// Function: WebGLKernel
|
||||
///
|
||||
/// Instantiates properties to the WebGl Kernel.
|
||||
///
|
||||
constructor(fnString, settings) {
|
||||
super(fnString, settings);
|
||||
this.textureCache = {};
|
||||
@ -50,6 +64,13 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
if (!this._webGl) this._webGl = utils.initWebGl(this.canvas);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: validateOptions
|
||||
///
|
||||
/// Validate options related to Kernel, such as
|
||||
/// floatOutputs and Textures, texSize, dimensions,
|
||||
/// graphical output.
|
||||
///
|
||||
validateOptions() {
|
||||
const isReadPixel = utils.isFloatReadPixelsSupported;
|
||||
if (this.floatTextures === true && !utils.OES_texture_float) {
|
||||
@ -97,6 +118,13 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: build
|
||||
///
|
||||
/// Builds the Kernel, by compiling Fragment and Vertical Shaders,
|
||||
/// and instantiates the program.
|
||||
///
|
||||
|
||||
build() {
|
||||
this.validateOptions();
|
||||
this.setupParams(arguments);
|
||||
@ -145,12 +173,24 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
gl.attachShader(program, vertShader);
|
||||
gl.attachShader(program, fragShader);
|
||||
gl.linkProgram(program);
|
||||
this.framebuffer = this._webGl.createFramebuffer();
|
||||
this.framebuffer = gl.createFramebuffer();
|
||||
this.framebuffer.width = this.texSize[0];
|
||||
this.framebuffer.height = this.texSize[1];
|
||||
return this;
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: run
|
||||
///
|
||||
/// Run the kernel program, and send the output to renderOutput
|
||||
///
|
||||
/// This method calls a helper method *renderOutput* to return the result.
|
||||
///
|
||||
/// Returns:
|
||||
/// Result {Object} The final output of the program, as float, and as Textures for reuse.
|
||||
///
|
||||
///
|
||||
|
||||
run() {
|
||||
if (this.program === null) {
|
||||
this.build.apply(this, arguments);
|
||||
@ -274,6 +314,23 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
return this.renderOutput(outputTexture);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: renderOutput
|
||||
///
|
||||
///
|
||||
/// Helper function to return webGl function's output.
|
||||
/// Since the program runs on GPU, we need to get the
|
||||
/// output of the program back to CPU and then return them.
|
||||
///
|
||||
/// *Note*: This should not be called directly.
|
||||
///
|
||||
/// Parameters:
|
||||
/// outputTexture Output Texture returned by webGl program
|
||||
///
|
||||
/// Returns:
|
||||
/// result {Object|Array}
|
||||
///
|
||||
///
|
||||
renderOutput(outputTexture) {
|
||||
const texSize = this.texSize;
|
||||
const gl = this._webGl;
|
||||
@ -307,18 +364,59 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: getOutputTexture
|
||||
///
|
||||
/// This uses *getTextureCache* to get the Texture Cache of the Output
|
||||
///
|
||||
/// Returns:
|
||||
/// Ouptut Texture Cache
|
||||
///
|
||||
getOutputTexture() {
|
||||
return this.getTextureCache('OUTPUT');
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: getArgumentTexture
|
||||
///
|
||||
/// This uses *getTextureCache** to get the Texture Cache of the argument supplied
|
||||
///
|
||||
/// Parameters:
|
||||
/// name {String} Name of the argument
|
||||
///
|
||||
/// Returns:
|
||||
/// Texture cache for the supplied argument
|
||||
///
|
||||
getArgumentTexture(name) {
|
||||
return this.getTextureCache(`ARGUMENT_${ name }`);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: getSubKernelTexture
|
||||
///
|
||||
/// This uses *getTextureCache* to get the Texture Cache of the sub-kernel
|
||||
///
|
||||
/// Parameters:
|
||||
/// name {String} Name of the subKernel
|
||||
///
|
||||
/// Returns:
|
||||
/// Texture cache for the subKernel
|
||||
///
|
||||
getSubKernelTexture(name) {
|
||||
return this.getTextureCache(`SUB_KERNEL_${ name }`);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: getTextureCache
|
||||
///
|
||||
/// Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument)
|
||||
///
|
||||
/// Parameters:
|
||||
/// name {String} Name of the subkernel, argument, or kernel.
|
||||
///
|
||||
/// Returns:
|
||||
/// Texture cache
|
||||
///
|
||||
getTextureCache(name) {
|
||||
if (this.outputToTexture) {
|
||||
// Don't retain a handle on the output texture, we might need to render on the same texture later
|
||||
@ -330,6 +428,15 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
return this.textureCache[name] = this._webGl.createTexture();
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: setupParams
|
||||
///
|
||||
/// Setup the parameter types for the parameters
|
||||
/// supplied to the Kernel function
|
||||
///
|
||||
/// Parameters:
|
||||
/// args {Array} The actual parameters sent to the Kernel
|
||||
///
|
||||
setupParams(args) {
|
||||
const paramTypes = this.paramTypes = [];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
@ -339,6 +446,13 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: getUniformLocation
|
||||
///
|
||||
/// Return WebGlUniformLocation for various variables
|
||||
/// related to webGl program, such as user-defiend variables,
|
||||
/// as well as, dimension sizes, etc.
|
||||
///
|
||||
getUniformLocation(name) {
|
||||
let location = this.programUniformLocationCache[name];
|
||||
if (!location) {
|
||||
@ -348,6 +462,47 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
return location;
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getFragShaderArtifactMap
|
||||
///
|
||||
/// Generate Shader artifacts for the kernel program.
|
||||
/// The final object contains HEADER, KERNEL, MAIN_RESULT, and others.
|
||||
///
|
||||
/// Parameters:
|
||||
/// args {Array} The actual parameters sent to the Kernel
|
||||
///
|
||||
/// Returns:
|
||||
/// {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)
|
||||
///
|
||||
_getFragShaderArtifactMap(args) {
|
||||
return {
|
||||
HEADER: this._getHeaderString(),
|
||||
LOOP_MAX: this._getLoopMaxString(),
|
||||
CONSTANTS: this._getConstantsString(),
|
||||
DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),
|
||||
ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),
|
||||
GET_WRAPAROUND: this._getGetWraparoundString(),
|
||||
GET_TEXTURE_CHANNEL: this._getGetTextureChannelString(),
|
||||
GET_TEXTURE_INDEX: this._getGetTextureIndexString(),
|
||||
GET_RESULT: this._getGetResultString(),
|
||||
MAIN_PARAMS: this._getMainParamsString(args),
|
||||
MAIN_CONSTANTS: this._getMainConstantsString(),
|
||||
KERNEL: this._getKernelString(),
|
||||
MAIN_RESULT: this._getMainResultString()
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _addArgument
|
||||
///
|
||||
/// Adds kernel parameters to the Argument Texture,
|
||||
/// binding it to the webGl instance, etc.
|
||||
///
|
||||
/// Parameters:
|
||||
/// value {Array|Texture|Number} The actual argument supplied to the kernel
|
||||
/// type {String} Type of the argument
|
||||
/// name {String} Name of the argument
|
||||
///
|
||||
_addArgument(value, type, name) {
|
||||
const gl = this._webGl;
|
||||
const argumentTexture = this.getArgumentTexture(name);
|
||||
@ -429,6 +584,15 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
this.argumentsLength++;
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getHeaderString
|
||||
///
|
||||
/// Get the header string for the program.
|
||||
/// This returns an empty string if no sub-kernels are defined.
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getHeaderString() {
|
||||
return (
|
||||
this.subKernels !== null || this.subKernelProperties !== null ?
|
||||
@ -438,6 +602,14 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getLoopMaxString
|
||||
///
|
||||
/// Get the maximum loop size String.
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getLoopMaxString() {
|
||||
return (
|
||||
this.loopMaxIterations ?
|
||||
@ -446,6 +618,16 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getConstantsString
|
||||
///
|
||||
/// Generate transpiled glsl Strings for constant parameters sent to a kernel
|
||||
///
|
||||
/// They can be defined by *hardcodeConstants*
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getConstantsString() {
|
||||
const result = [];
|
||||
const threadDim = this.threadDim;
|
||||
@ -465,6 +647,14 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
return this._linesToString(result);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getTextureCoordinate
|
||||
///
|
||||
/// Get texture coordinate string for the program
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getTextureCoordinate() {
|
||||
const names = this.subKernelOutputVariableNames;
|
||||
if (names === null || names.length < 1) {
|
||||
@ -474,6 +664,14 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getDecode32EndiannessString
|
||||
///
|
||||
/// Get Decode32 endianness string for little-endian and big-endian
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getDecode32EndiannessString() {
|
||||
return (
|
||||
this.endianness === 'LE' ?
|
||||
@ -482,6 +680,14 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getEncode32EndiannessString
|
||||
///
|
||||
/// Get Encode32 endianness string for little-endian and big-endian
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getEncode32EndiannessString() {
|
||||
return (
|
||||
this.endianness === 'LE' ?
|
||||
@ -490,6 +696,9 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getGetWraparoundString
|
||||
///
|
||||
_getGetWraparoundString() {
|
||||
return (
|
||||
this.wraparound ?
|
||||
@ -498,6 +707,9 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getGetTextureChannelString
|
||||
///
|
||||
_getGetTextureChannelString() {
|
||||
if (!this.floatTextures) return '';
|
||||
|
||||
@ -507,6 +719,13 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
]);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getGetTextureIndexString
|
||||
///
|
||||
/// Get generic texture index string, if floatTextures flag is true.
|
||||
///
|
||||
/// > ' index = float(int(index)/4);\n'
|
||||
///
|
||||
_getGetTextureIndexString() {
|
||||
return (
|
||||
this.floatTextures ?
|
||||
@ -515,6 +734,9 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getGetResultString
|
||||
///
|
||||
_getGetResultString() {
|
||||
if (!this.floatTextures) return ' return decode32(texel);\n';
|
||||
return this._linesToString([
|
||||
@ -525,6 +747,17 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
]);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getMainParamsString
|
||||
///
|
||||
/// Generate transpiled glsl Strings for user-defined parameters sent to a kernel
|
||||
///
|
||||
/// Parameters:
|
||||
/// args {Array} The actual parameters sent to the Kernel
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getMainParamsString(args) {
|
||||
const result = [];
|
||||
const paramTypes = this.paramTypes;
|
||||
@ -565,6 +798,13 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
return this._linesToString(result);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getMainConstantsString
|
||||
///
|
||||
/// Returns:
|
||||
/// Texture cache
|
||||
///
|
||||
_getMainConstantsString() {
|
||||
const result = [];
|
||||
if (this.constants) {
|
||||
@ -581,6 +821,15 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
return this._linesToString(result);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getKernelString
|
||||
///
|
||||
/// Get Kernel program string (in *glsl*) for a kernel.
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getKernelString() {
|
||||
const result = [];
|
||||
const names = this.subKernelOutputVariableNames;
|
||||
@ -607,6 +856,15 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
|
||||
return this._linesToString(result) + this.functionBuilder.getPrototypeString('kernel');
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getMainResultString
|
||||
///
|
||||
/// Get main result string with checks for floatOutput, graphical, subKernelsOutputs, etc.
|
||||
///
|
||||
/// Returns:
|
||||
/// result {String}
|
||||
///
|
||||
_getMainResultString() {
|
||||
const names = this.subKernelOutputVariableNames;
|
||||
const result = [];
|
||||
@ -662,6 +920,15 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
return this._linesToString(result);
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _linesToString
|
||||
///
|
||||
/// Parameters:
|
||||
/// lines {Array} An Array of strings
|
||||
///
|
||||
/// Returns:
|
||||
/// Single combined String, seperated by *\n*
|
||||
///
|
||||
_linesToString(lines) {
|
||||
if (lines.length > 0) {
|
||||
return lines.join(';\n') + ';\n';
|
||||
@ -670,6 +937,16 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _replaceArtifacts
|
||||
///
|
||||
/// Parameters:
|
||||
/// src {String} Name of the subkernel, argument, or kernel.
|
||||
/// map {String} Name of the subkernel, argument, or kernel.
|
||||
///
|
||||
/// Returns:
|
||||
/// Texture cache
|
||||
///
|
||||
_replaceArtifacts(src, map) {
|
||||
return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z])*)__;\n/g, (match, artifact) => {
|
||||
if (map.hasOwnProperty(artifact)) {
|
||||
@ -679,6 +956,11 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
});
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _addKernels
|
||||
///
|
||||
/// Adds all the sub-kernels supplied with this Kernel instance.
|
||||
///
|
||||
_addKernels() {
|
||||
const builder = this.functionBuilder;
|
||||
const gl = this._webGl;
|
||||
@ -728,6 +1010,19 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getFragShaderString
|
||||
///
|
||||
/// Get the fragment shader String.
|
||||
/// If the String hasn't been compiled yet,
|
||||
/// then this method compiles it as well
|
||||
///
|
||||
/// Parameters:
|
||||
/// args {Array} The actual parameters sent to the Kernel
|
||||
///
|
||||
/// Returns:
|
||||
/// {String} Fragment Shader string
|
||||
///
|
||||
_getFragShaderString(args) {
|
||||
if (this.compiledFragShaderString !== null) {
|
||||
return this.compiledFragShaderString;
|
||||
@ -735,6 +1030,17 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
return this.compiledFragShaderString = this._replaceArtifacts(fragShaderString, this._getFragShaderArtifactMap(args));
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: _getVertShaderString
|
||||
///
|
||||
/// Get the vertical shader String
|
||||
///
|
||||
/// Parameters:
|
||||
/// args {Array} The actual parameters sent to the Kernel
|
||||
///
|
||||
/// Returns:
|
||||
/// {String} Vertical Shader string
|
||||
///
|
||||
_getVertShaderString(args) {
|
||||
if (this.compiledVertShaderString !== null) {
|
||||
return this.compiledVertShaderString;
|
||||
@ -743,6 +1049,11 @@ module.exports = class WebGLKernel extends KernelBase {
|
||||
return this.compiledVertShaderString = vertShaderString;
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: toString
|
||||
///
|
||||
/// Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.
|
||||
///
|
||||
toString() {
|
||||
return kernelString(this);
|
||||
}
|
||||
|
||||
5
src/texture.js
vendored
5
src/texture.js
vendored
@ -1,4 +1,5 @@
|
||||
let gpu = null;
|
||||
|
||||
///
|
||||
/// Class: Texture
|
||||
///
|
||||
@ -11,6 +12,8 @@ module.exports = class Texture {
|
||||
this.webGl = webGl;
|
||||
}
|
||||
|
||||
///
|
||||
/// Function: toArray
|
||||
///
|
||||
/// Converts the Texture into a JavaScript Array.
|
||||
///
|
||||
@ -27,6 +30,8 @@ module.exports = class Texture {
|
||||
return copy(this.texture);
|
||||
}
|
||||
///
|
||||
/// Function: delete
|
||||
///
|
||||
/// Deletes the Texture.
|
||||
///
|
||||
delete() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user