Merge branch 'develop' into 261-webgl2

This commit is contained in:
Robert Plummer 2018-03-01 15:59:37 -05:00
commit 3b839b37b0
8 changed files with 150 additions and 73 deletions

View File

@ -4,8 +4,8 @@
*
* GPU Accelerated JavaScript
*
* @version 1.2.0
* @date Wed Feb 28 2018 21:59:32 GMT-0500 (EST)
* @version 1.0.4
* @date Thu Mar 01 2018 15:56:51 GMT-0500 (EST)
*
* @license MIT
* The MIT License
@ -161,7 +161,15 @@ var UtilsCore = function () {
throw new Error('Invalid canvas object - ' + canvasObj);
}
return canvasObj.getContext('webgl2', UtilsCore.initWebGlDefaultOptions());
var webGl = canvasObj.getContext('experimental-webgl', UtilsCore.initWebGlDefaultOptions()) || canvasObj.getContext('webgl', UtilsCore.initWebGlDefaultOptions());
if (webGl) {
webGl.OES_texture_float = webGl.getExtension('OES_texture_float');
webGl.OES_texture_float_linear = webGl.getExtension('OES_texture_float_linear');
webGl.OES_element_index_uint = webGl.getExtension('OES_element_index_uint');
}
return webGl;
}
}]);
@ -172,7 +180,17 @@ var UtilsCore = function () {
var _isCanvasSupported = typeof document !== 'undefined' ? UtilsCore.isCanvas(document.createElement('canvas')) : false;
var _testingWebGl = UtilsCore.initWebGl(UtilsCore.initCanvas());
var _isWebGlSupported = UtilsCore.isWebGl(_testingWebGl);
var _isWebGlDrawBuffersSupported = _isWebGlSupported;
var _isWebGlDrawBuffersSupported = _isWebGlSupported && Boolean(_testingWebGl.getExtension('WEBGL_draw_buffers'));
if (_isWebGlSupported) {
UtilsCore.OES_texture_float = _testingWebGl.OES_texture_float;
UtilsCore.OES_texture_float_linear = _testingWebGl.OES_texture_float_linear;
UtilsCore.OES_element_index_uint = _testingWebGl.OES_element_index_uint;
} else {
UtilsCore.OES_texture_float = false;
UtilsCore.OES_texture_float_linear = false;
UtilsCore.OES_element_index_uint = false;
}
module.exports = UtilsCore;
},{}],3:[function(require,module,exports){

6
bin/gpu-core.min.js vendored
View File

@ -4,12 +4,12 @@
*
* GPU Accelerated JavaScript
*
* @version 1.2.0
* @date Wed Feb 28 2018 21:59:32 GMT-0500 (EST)
* @version 1.0.4
* @date Thu Mar 01 2018 15:56:51 GMT-0500 (EST)
*
* @license MIT
* The MIT License
*
* Copyright (c) 2018 gpu.js Team
*/
"use strict";!function e(n,t,r){function i(u,a){if(!t[u]){if(!n[u]){var l="function"==typeof require&&require;if(!a&&l)return l(u,!0);if(o)return o(u,!0);var f=new Error("Cannot find module '"+u+"'");throw f.code="MODULE_NOT_FOUND",f}var c=t[u]={exports:{}};n[u][0].call(c.exports,function(e){var t=n[u][1][e];return i(t?t:e)},c,c.exports,e,n,t,r)}return t[u].exports}for(var o="function"==typeof require&&require,u=0;u<r.length;u++)i(r[u]);return i}({1:[function(e,n,t){function r(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(n,t,r){return t&&e(n.prototype,t),r&&e(n,r),n}}();e("./utils-core");n.exports=function(){function e(){r(this,e)}return i(e,null,[{key:"validateKernelObj",value:function(e){if(null===e)throw"KernelObj being validated is NULL";if("string"==typeof e){try{e=JSON.parse(e)}catch(n){throw console.error(n),"Failed to convert KernelObj from JSON string"}if(null===e)throw"Invalid (NULL) KernelObj JSON string representation"}if(e.isKernelObj!==!0)throw"Failed missing isKernelObj flag check";return e}},{key:"loadKernelObj",value:function(e,n){e=validateKernelObj(e)}}]),e}()},{"./utils-core":2}],2:[function(e,n,t){function r(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(n,t,r){return t&&e(n.prototype,t),r&&e(n,r),n}}(),o=function(){function e(){r(this,e)}return i(e,null,[{key:"isCanvas",value:function(e){return null!==e&&e.nodeName&&e.getContext&&"CANVAS"===e.nodeName.toUpperCase()}},{key:"isCanvasSupported",value:function(){return u}},{key:"initCanvas",value:function(){if(!u)return null;var e=document.createElement("canvas");return e.width=2,e.height=2,e}},{key:"isWebGl",value:function(e){return e&&"function"==typeof e.getExtension}},{key:"isWebGlSupported",value:function(){return l}},{key:"isWebGlDrawBuffersSupported",value:function(){return f}},{key:"initWebGlDefaultOptions",value:function(){return{alpha:!1,depth:!1,antialias:!1}}},{key:"initWebGl",value:function(n){if(("undefined"!=typeof u||null===n)&&!u)return null;if(!e.isCanvas(n))throw new Error("Invalid canvas object - "+n);return n.getContext("webgl2",e.initWebGlDefaultOptions())}}]),e}(),u="undefined"!=typeof document&&o.isCanvas(document.createElement("canvas")),a=o.initWebGl(o.initCanvas()),l=o.isWebGl(a),f=l;n.exports=o},{}],3:[function(e,n,t){var r=e("./core/gpu-core");"undefined"!=typeof n&&(n.exports=r),"undefined"!=typeof window&&(window.GPUCore=r,null===window.GPU&&(window.GPU=r))},{"./core/gpu-core":1}]},{},[3]);
"use strict";!function e(n,t,r){function i(u,a){if(!t[u]){if(!n[u]){var l="function"==typeof require&&require;if(!a&&l)return l(u,!0);if(o)return o(u,!0);var f=new Error("Cannot find module '"+u+"'");throw f.code="MODULE_NOT_FOUND",f}var c=t[u]={exports:{}};n[u][0].call(c.exports,function(e){var t=n[u][1][e];return i(t?t:e)},c,c.exports,e,n,t,r)}return t[u].exports}for(var o="function"==typeof require&&require,u=0;u<r.length;u++)i(r[u]);return i}({1:[function(e,n,t){function r(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(n,t,r){return t&&e(n.prototype,t),r&&e(n,r),n}}();e("./utils-core");n.exports=function(){function e(){r(this,e)}return i(e,null,[{key:"validateKernelObj",value:function(e){if(null===e)throw"KernelObj being validated is NULL";if("string"==typeof e){try{e=JSON.parse(e)}catch(n){throw console.error(n),"Failed to convert KernelObj from JSON string"}if(null===e)throw"Invalid (NULL) KernelObj JSON string representation"}if(e.isKernelObj!==!0)throw"Failed missing isKernelObj flag check";return e}},{key:"loadKernelObj",value:function(e,n){e=validateKernelObj(e)}}]),e}()},{"./utils-core":2}],2:[function(e,n,t){function r(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(n,t,r){return t&&e(n.prototype,t),r&&e(n,r),n}}(),o=function(){function e(){r(this,e)}return i(e,null,[{key:"isCanvas",value:function(e){return null!==e&&e.nodeName&&e.getContext&&"CANVAS"===e.nodeName.toUpperCase()}},{key:"isCanvasSupported",value:function(){return u}},{key:"initCanvas",value:function(){if(!u)return null;var e=document.createElement("canvas");return e.width=2,e.height=2,e}},{key:"isWebGl",value:function(e){return e&&"function"==typeof e.getExtension}},{key:"isWebGlSupported",value:function(){return l}},{key:"isWebGlDrawBuffersSupported",value:function(){return f}},{key:"initWebGlDefaultOptions",value:function(){return{alpha:!1,depth:!1,antialias:!1}}},{key:"initWebGl",value:function(n){if(("undefined"!=typeof u||null===n)&&!u)return null;if(!e.isCanvas(n))throw new Error("Invalid canvas object - "+n);var t=n.getContext("experimental-webgl",e.initWebGlDefaultOptions())||n.getContext("webgl",e.initWebGlDefaultOptions());return t&&(t.OES_texture_float=t.getExtension("OES_texture_float"),t.OES_texture_float_linear=t.getExtension("OES_texture_float_linear"),t.OES_element_index_uint=t.getExtension("OES_element_index_uint")),t}}]),e}(),u="undefined"!=typeof document&&o.isCanvas(document.createElement("canvas")),a=o.initWebGl(o.initCanvas()),l=o.isWebGl(a),f=l&&Boolean(a.getExtension("WEBGL_draw_buffers"));l?(o.OES_texture_float=a.OES_texture_float,o.OES_texture_float_linear=a.OES_texture_float_linear,o.OES_element_index_uint=a.OES_element_index_uint):(o.OES_texture_float=!1,o.OES_texture_float_linear=!1,o.OES_element_index_uint=!1),n.exports=o},{}],3:[function(e,n,t){var r=e("./core/gpu-core");"undefined"!=typeof n&&(n.exports=r),"undefined"!=typeof window&&(window.GPUCore=r,null===window.GPU&&(window.GPU=r))},{"./core/gpu-core":1}]},{},[3]);

View File

@ -4,8 +4,8 @@
*
* GPU Accelerated JavaScript
*
* @version 1.2.0
* @date Wed Feb 28 2018 21:59:32 GMT-0500 (EST)
* @version 1.0.4
* @date Thu Mar 01 2018 15:56:51 GMT-0500 (EST)
*
* @license MIT
* The MIT License
@ -15,6 +15,8 @@
"use strict";(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
@ -36,6 +38,11 @@ module.exports = function (_FunctionBuilderBase) {
return _this;
}
_createClass(CPUFunctionBuilder, [{
key: 'polyfillStandardFunctions',
value: function polyfillStandardFunctions() {}
}]);
return CPUFunctionBuilder;
}(FunctionBuilderBase);
},{"../function-builder-base":6,"./function-node":2}],2:[function(require,module,exports){
@ -1227,6 +1234,11 @@ module.exports = function () {
}
return this.getStringFromFunctionNames(Object.keys(this.nodeMap), opt);
}
}, {
key: 'polyfillStandardFunctions',
value: function polyfillStandardFunctions() {
throw new Error('polyfillStandardFunctions not defined on base function builder');
}
}]);
return FunctionBuilderBase;
@ -1836,6 +1848,7 @@ module.exports = function () {
this.functionBuilder = functionBuilder;
this.fnString = null;
this.endianness = utils.systemEndianness();
this.functionBuilder.polyfillStandardFunctions();
}
@ -1896,6 +1909,8 @@ module.exports = function () {
},{"../core/utils":25,"./kernel-run-shortcut":9}],11:[function(require,module,exports){
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
@ -1906,19 +1921,40 @@ var FunctionBuilderBase = require('../function-builder-base');
var WebGLFunctionNode = require('./function-node');
module.exports = function (_FunctionBuilderBase) {
_inherits(WebGLFunctionBuilder, _FunctionBuilderBase);
_inherits(WebGLFunctionBuilder, _FunctionBuilderBase);
function WebGLFunctionBuilder() {
_classCallCheck(this, WebGLFunctionBuilder);
function WebGLFunctionBuilder() {
_classCallCheck(this, WebGLFunctionBuilder);
var _this = _possibleConstructorReturn(this, (WebGLFunctionBuilder.__proto__ || Object.getPrototypeOf(WebGLFunctionBuilder)).call(this));
var _this = _possibleConstructorReturn(this, (WebGLFunctionBuilder.__proto__ || Object.getPrototypeOf(WebGLFunctionBuilder)).call(this));
_this.Node = WebGLFunctionNode;
return _this;
}
_this.Node = WebGLFunctionNode;
return _this;
}
return WebGLFunctionBuilder;
_createClass(WebGLFunctionBuilder, [{
key: 'polyfillStandardFunctions',
value: function polyfillStandardFunctions() {
this.addFunction('round', _round);
}
}], [{
key: 'round',
value: function round(a) {
return _round(a);
}
}]);
return WebGLFunctionBuilder;
}(FunctionBuilderBase);
function _round(a) {
return Math.floor(a + 0.5);
}
},{"../function-builder-base":6,"./function-node":12}],12:[function(require,module,exports){
'use strict';
@ -2793,9 +2829,10 @@ module.exports = function (_KernelBase) {
_this.subKernelOutputTextures = null;
_this.subKernelOutputVariableNames = null;
_this.argumentsLength = 0;
_this.ext = null;
_this.compiledFragShaderString = null;
_this.compiledVertShaderString = null;
_this.drawBuffersMap = null;
_this.extDrawBuffersMap = null;
_this.outputTexture = null;
_this.maxTexSize = null;
if (!_this._webGl) _this._webGl = utils.initWebGl(_this.getCanvas());
@ -2808,9 +2845,11 @@ module.exports = function (_KernelBase) {
key: 'validateOptions',
value: function validateOptions() {
var isFloatReadPixel = utils.isFloatReadPixelsSupported();
if (this.floatOutput === true && this.floatOutputForce !== true && !isFloatReadPixel) {
if (this.floatTextures === true && !utils.OES_texture_float) {
throw new Error('Float textures are not supported on this browser');
} else if (this.floatOutput === true && this.floatOutputForce !== true && !isFloatReadPixel) {
throw new Error('Float texture outputs are not supported on this browser');
} else if (this.floatTextures === undefined) {
} else if (this.floatTextures === undefined && utils.OES_texture_float) {
this.floatTextures = true;
this.floatOutput = isFloatReadPixel;
}
@ -2846,13 +2885,9 @@ module.exports = function (_KernelBase) {
}
this.texSize = utils.clone(this.output);
} else if (this.floatOutput === undefined) {
} else if (this.floatOutput === undefined && utils.OES_texture_float) {
this.floatOutput = true;
}
if (this.floatOutput || this.floatOutputForce) {
this._webGl.getExtension('EXT_color_buffer_float');
}
}
}, {
key: 'updateMaxTexSize',
@ -3019,7 +3054,7 @@ module.exports = function (_KernelBase) {
var subKernelOutputTexture = this.subKernelOutputTextures[i];
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, subKernelOutputTexture, 0);
}
gl.drawBuffers(this.drawBuffersMap);
this.ext.drawBuffersWEBGL(this.extDrawBuffersMap);
}
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
@ -3106,7 +3141,7 @@ module.exports = function (_KernelBase) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
if (this.floatOutput) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
} else {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
}
@ -3118,12 +3153,12 @@ module.exports = function (_KernelBase) {
value: function _setupSubOutputTextures(length) {
var gl = this._webGl;
var texSize = this.texSize;
var drawBuffersMap = this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];
var extDrawBuffersMap = this.extDrawBuffersMap = [gl.COLOR_ATTACHMENT0];
var textures = this.subKernelOutputTextures = [];
for (var i = 0; i < length; i++) {
var texture = this._webGl.createTexture();
textures.push(texture);
drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
extDrawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);
gl.activeTexture(gl.TEXTURE0 + this.paramNames.length + i);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
@ -3131,7 +3166,7 @@ module.exports = function (_KernelBase) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
if (this.floatOutput) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);
} else {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
}
@ -3176,12 +3211,10 @@ module.exports = function (_KernelBase) {
}, {
key: 'getUniformLocation',
value: function getUniformLocation(name) {
var location = this.programUniformLocationCache[name];
if (!location) {
location = this._webGl.getUniformLocation(this.program, name);
this.programUniformLocationCache[name] = location;
if (this.programUniformLocationCache.hasOwnProperty(name)) {
return this.programUniformLocationCache[name];
}
return location;
return this.programUniformLocationCache[name] = this._webGl.getUniformLocation(this.program, name);
}
@ -3239,7 +3272,7 @@ module.exports = function (_KernelBase) {
var buffer = void 0;
if (this.floatTextures) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, size[0], size[1], 0, gl.RGBA, gl.FLOAT, valuesFlat);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.FLOAT, valuesFlat);
} else {
buffer = new Uint8Array(valuesFlat.buffer);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size[0], size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
@ -3288,7 +3321,7 @@ module.exports = function (_KernelBase) {
}
if (this.floatTextures) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, _size[0], _size[1], 0, gl.RGBA, gl.FLOAT, inputArray);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0], _size[1], 0, gl.RGBA, gl.FLOAT, inputArray);
} else {
var _buffer = new Uint8Array(inputArray.buffer);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, _size[0], _size[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, _buffer);
@ -3334,7 +3367,8 @@ module.exports = function (_KernelBase) {
}, {
key: '_getHeaderString',
value: function _getHeaderString() {
return '';
return this.subKernels !== null || this.subKernelProperties !== null ?
'#extension GL_EXT_draw_buffers : require\n' : '';
}
@ -3366,7 +3400,7 @@ module.exports = function (_KernelBase) {
value: function _getTextureCoordinate() {
var names = this.subKernelOutputVariableNames;
if (names === null || names.length < 1) {
return 'in highp vec2 vTexCoord;\n';
return 'varying highp vec2 vTexCoord;\n';
} else {
return 'out highp vec2 vTexCoord;\n';
}
@ -3481,12 +3515,11 @@ module.exports = function (_KernelBase) {
var names = this.subKernelOutputVariableNames;
if (names !== null) {
result.push('highp float kernelResult = 0.0');
result.push('layout(location = 0) out highp vec4 data0');
for (var i = 0; i < names.length; i++) {
result.push('highp float ' + names[i] + ' = 0.0', 'layout(location = ' + (i + 1) + ') out highp vec4 data' + (i + 1));
result.push('highp float ' + names[i] + ' = 0.0');
}
} else {
result.push('out highp vec4 data0');
result.push('highp float kernelResult = 0.0');
}
@ -3505,7 +3538,7 @@ module.exports = function (_KernelBase) {
}
if (this.graphical) {
result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' data0 = actualColor');
result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = actualColor');
} else if (this.floatOutput) {
var channels = ['r', 'g', 'b', 'a'];
@ -3514,13 +3547,13 @@ module.exports = function (_KernelBase) {
result.push(' kernel()');
if (names) {
result.push(' data0.' + channels[i] + ' = kernelResult');
result.push(' gl_FragData[0].' + channels[i] + ' = kernelResult');
for (var j = 0; j < names.length; ++j) {
result.push(' data' + (j + 1) + '.' + channels[i] + ' = ' + names[j]);
result.push(' gl_FragData[' + (j + 1) + '].' + channels[i] + ' = ' + names[j]);
}
} else {
result.push(' data0.' + channels[i] + ' = kernelResult');
result.push(' gl_FragColor.' + channels[i] + ' = kernelResult');
}
if (i < channels.length - 1) {
@ -3530,12 +3563,12 @@ module.exports = function (_KernelBase) {
} else if (names !== null) {
result.push(' threadId = indexTo3D(index, uOutputDim)');
result.push(' kernel()');
result.push(' data0 = encode32(kernelResult)');
result.push(' gl_FragData[0] = encode32(kernelResult)');
for (var _i3 = 0; _i3 < names.length; _i3++) {
result.push(' data' + (_i3 + 1) + ' = encode32(' + names[_i3] + ')');
result.push(' gl_FragData[' + (_i3 + 1) + '] = encode32(' + names[_i3] + ')');
}
} else {
result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' data0 = encode32(kernelResult)');
result.push(' threadId = indexTo3D(index, uOutputDim)', ' kernel()', ' gl_FragColor = encode32(kernelResult)');
}
return this._linesToString(result);
@ -3588,13 +3621,15 @@ module.exports = function (_KernelBase) {
}, this.paramNames, this.paramTypes);
if (this.subKernels !== null) {
this.subKernelOutputTextures = [];
var ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
if (!ext) throw new Error('could not instantiate draw buffers extension');
this.subKernelOutputVariableNames = [];
this.subKernels.forEach(function (subKernel) {
return _this2._addSubKernel(subKernel);
});
} else if (this.subKernelProperties !== null) {
this.subKernelOutputTextures = [];
var _ext = this.ext = gl.getExtension('WEBGL_draw_buffers');
if (!_ext) throw new Error('could not instantiate draw buffers extension');
this.subKernelOutputVariableNames = [];
Object.keys(this.subKernelProperties).forEach(function (property) {
return _this2._addSubKernel(_this2.subKernelProperties[property]);
@ -3692,11 +3727,11 @@ module.exports = function (_RunnerBase) {
},{"../../core/utils":25,"../runner-base":10,"./function-builder":11,"./kernel":14}],16:[function(require,module,exports){
"use strict";
module.exports = "#version 300 es\n__HEADER__;\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nconst float LOOP_MAX = __LOOP_MAX__;\n#define EPSILON 0.0000001;\n\n__CONSTANTS__;\n\nin highp vec2 vTexCoord;\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nhighp float integerMod(highp float x, highp float y) {\n highp float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nhighp int integerMod(highp int x, highp int y) {\n return int(integerMod(float(x), float(y)));\n}\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nhighp float decode32(highp vec4 rgba) {\n __DECODE32_ENDIANNESS__;\n rgba *= 255.0;\n vec2 gte128;\n gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n rgba.b = rgba.b - 128.0 * gte128.x;\n res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nhighp vec4 encode32(highp float f) {\n highp float F = abs(f);\n highp float sign = f < 0.0 ? 1.0 : 0.0;\n highp float exponent = floor(log2(F));\n highp float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n rgba.rg = integerMod(rgba.rg, 256.0);\n rgba.b = integerMod(rgba.b, 128.0);\n rgba.a = exponent*0.5 + 63.5;\n rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n rgba = floor(rgba);\n rgba *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return rgba;\n}\n// Dragons end here\n\nhighp float index;\nhighp vec3 threadId;\n\nhighp vec3 indexTo3D(highp float idx, highp vec3 texDim) {\n highp float z = floor(idx / (texDim.x * texDim.y));\n idx -= z * texDim.x * texDim.y;\n highp float y = floor(idx / texDim.x);\n highp float x = integerMod(idx, texDim.x);\n return vec3(x, y, z);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float z, highp float y, highp float x) {\n highp vec3 xyz = vec3(x, y, z);\n xyz = floor(xyz + 0.5);\n __GET_WRAPAROUND__;\n highp float index = round(xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z));\n __GET_TEXTURE_CHANNEL__;\n highp float w = round(texSize.x);\n vec2 st = vec2(integerMod(index, w), float(int(index) / int(w))) + 0.5;\n __GET_TEXTURE_INDEX__;\n highp vec4 texel = texture(tex, st / texSize);\n __GET_RESULT__;\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float y, highp float x) {\n return get(tex, texSize, texDim, 0.0, y, x);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float x) {\n return get(tex, texSize, texDim, 0.0, 0.0, x);\n}\n\nhighp vec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\n__MAIN_PARAMS__;\n__MAIN_CONSTANTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}";
module.exports = "__HEADER__;\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nconst float LOOP_MAX = __LOOP_MAX__;\n#define EPSILON 0.0000001;\n\n__CONSTANTS__;\n\nvarying highp vec2 vTexCoord;\n\nvec4 round(vec4 x) {\n return floor(x + 0.5);\n}\n\nhighp float round(highp float x) {\n return floor(x + 0.5);\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nhighp float integerMod(highp float x, highp float y) {\n highp float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nhighp int integerMod(highp int x, highp int y) {\n return int(integerMod(float(x), float(y)));\n}\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nhighp float decode32(highp vec4 rgba) {\n __DECODE32_ENDIANNESS__;\n rgba *= 255.0;\n vec2 gte128;\n gte128.x = rgba.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = rgba.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * rgba.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n rgba.b = rgba.b - 128.0 * gte128.x;\n res = dot(rgba, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nhighp vec4 encode32(highp float f) {\n highp float F = abs(f);\n highp float sign = f < 0.0 ? 1.0 : 0.0;\n highp float exponent = floor(log2(F));\n highp float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 rgba = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n rgba.rg = integerMod(rgba.rg, 256.0);\n rgba.b = integerMod(rgba.b, 128.0);\n rgba.a = exponent*0.5 + 63.5;\n rgba.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n rgba = floor(rgba);\n rgba *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return rgba;\n}\n// Dragons end here\n\nhighp float index;\nhighp vec3 threadId;\n\nhighp vec3 indexTo3D(highp float idx, highp vec3 texDim) {\n highp float z = floor(idx / (texDim.x * texDim.y));\n idx -= z * texDim.x * texDim.y;\n highp float y = floor(idx / texDim.x);\n highp float x = integerMod(idx, texDim.x);\n return vec3(x, y, z);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float z, highp float y, highp float x) {\n highp vec3 xyz = vec3(x, y, z);\n xyz = floor(xyz + 0.5);\n __GET_WRAPAROUND__;\n highp float index = round(xyz.x + texDim.x * (xyz.y + texDim.y * xyz.z));\n __GET_TEXTURE_CHANNEL__;\n highp float w = round(texSize.x);\n vec2 st = vec2(integerMod(index, w), float(int(index) / int(w))) + 0.5;\n __GET_TEXTURE_INDEX__;\n highp vec4 texel = texture2D(tex, st / texSize);\n __GET_RESULT__;\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float y, highp float x) {\n return get(tex, texSize, texDim, 0.0, y, x);\n}\n\nhighp float get(highp sampler2D tex, highp vec2 texSize, highp vec3 texDim, highp float x) {\n return get(tex, texSize, texDim, 0.0, 0.0, x);\n}\n\nhighp vec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\n__MAIN_PARAMS__;\n__MAIN_CONSTANTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = floor(vTexCoord.s * float(uTexSize.x)) + floor(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}";
},{}],17:[function(require,module,exports){
"use strict";
module.exports = "#version 300 es\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nin highp vec2 aPos;\nin highp vec2 aTexCoord;\n\nout highp vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}";
module.exports = "precision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\nattribute highp vec2 aPos;\nattribute highp vec2 aTexCoord;\n\nvarying highp vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}";
},{}],18:[function(require,module,exports){
'use strict';
@ -3725,7 +3760,6 @@ module.exports = function (_WebGLKernel) {
value: function validateOptions() {
this._webGl.getExtension('EXT_color_buffer_float');
this.texSize = utils.dimToTexSize({
floatTextures: this.floatTextures,
floatOutput: this.floatOutput
@ -4189,7 +4223,15 @@ var UtilsCore = function () {
throw new Error('Invalid canvas object - ' + canvasObj);
}
return canvasObj.getContext('webgl2', UtilsCore.initWebGlDefaultOptions());
var webGl = canvasObj.getContext('experimental-webgl', UtilsCore.initWebGlDefaultOptions()) || canvasObj.getContext('webgl', UtilsCore.initWebGlDefaultOptions());
if (webGl) {
webGl.OES_texture_float = webGl.getExtension('OES_texture_float');
webGl.OES_texture_float_linear = webGl.getExtension('OES_texture_float_linear');
webGl.OES_element_index_uint = webGl.getExtension('OES_element_index_uint');
}
return webGl;
}
}]);
@ -4200,7 +4242,17 @@ var UtilsCore = function () {
var _isCanvasSupported = typeof document !== 'undefined' ? UtilsCore.isCanvas(document.createElement('canvas')) : false;
var _testingWebGl = UtilsCore.initWebGl(UtilsCore.initCanvas());
var _isWebGlSupported = UtilsCore.isWebGl(_testingWebGl);
var _isWebGlDrawBuffersSupported = _isWebGlSupported;
var _isWebGlDrawBuffersSupported = _isWebGlSupported && Boolean(_testingWebGl.getExtension('WEBGL_draw_buffers'));
if (_isWebGlSupported) {
UtilsCore.OES_texture_float = _testingWebGl.OES_texture_float;
UtilsCore.OES_texture_float_linear = _testingWebGl.OES_texture_float_linear;
UtilsCore.OES_element_index_uint = _testingWebGl.OES_element_index_uint;
} else {
UtilsCore.OES_texture_float = false;
UtilsCore.OES_texture_float_linear = false;
UtilsCore.OES_element_index_uint = false;
}
module.exports = UtilsCore;
},{}],25:[function(require,module,exports){

15
bin/gpu.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -572,12 +572,10 @@ module.exports = function (_KernelBase) {
}, {
key: 'getUniformLocation',
value: function getUniformLocation(name) {
var location = this.programUniformLocationCache[name];
if (!location) {
location = this._webGl.getUniformLocation(this.program, name);
this.programUniformLocationCache[name] = location;
if (this.programUniformLocationCache.hasOwnProperty(name)) {
return this.programUniformLocationCache[name];
}
return location;
return this.programUniformLocationCache[name] = this._webGl.getUniformLocation(this.program, name);
}
/**

View File

@ -533,12 +533,10 @@ module.exports = class WebGLKernel extends KernelBase {
*
*/
getUniformLocation(name) {
let location = this.programUniformLocationCache[name];
if (!location) {
location = this._webGl.getUniformLocation(this.program, name);
this.programUniformLocationCache[name] = location;
if (this.programUniformLocationCache.hasOwnProperty(name)) {
return this.programUniformLocationCache[name];
}
return location;
return this.programUniformLocationCache[name] = this._webGl.getUniformLocation(this.program, name);
}
/**

View File

@ -57,5 +57,6 @@
<script src="../src/issues/259-atan2.js"></script>
<script src="../src/issues/263-to-string.js"></script>
<script src="../src/issues/267-immutable-sub-kernels.js"></script>
<script src="../src/issues/270-cache.js"></script>
</body>
</html>

View File

@ -0,0 +1,9 @@
QUnit.test('Issue #270 WebGlKernel getUniformLocation caches falsey - gpu', () => {
const kernel = new GPU.WebGLKernel('', {});
kernel.programUniformLocationCache.test = false;
kernel._webGl = {};
kernel._webGl.getUniformLocation = () => {
throw new Error('tried to get getUniformLocation when falsey');
};
QUnit.assert.equal(kernel.getUniformLocation('test'), false);
});