WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.

This commit is contained in:
Richard Davey 2020-07-15 16:52:26 +01:00
parent fd305591ec
commit c0504e4fc1
2 changed files with 94 additions and 73 deletions

View file

@ -1,58 +0,0 @@
// From Pixi v5
function GenerateSrc (maxIfs)
{
var src = '';
for (var i = 0; i < maxIfs; ++i)
{
if (i > 0)
{
src += '\nelse ';
}
if (i < maxIfs - 1)
{
src += 'if(test == ' + i + '.0){}';
}
}
return src;
}
var CheckShaderMax = function (gl, maxIfs)
{
var shader = gl.createShader(gl.FRAGMENT_SHADER);
var fragTemplate = [
'precision mediump float;',
'void main(void){',
'float test = 0.1;',
'%forloop%',
'gl_FragColor = vec4(0.0);',
'}'
].join('\n');
// eslint-disable-next-line no-constant-condition
while (true)
{
var fragmentSrc = fragTemplate.replace(/%forloop%/gi, GenerateSrc(maxIfs));
gl.shaderSource(shader, fragmentSrc);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
{
maxIfs = (maxIfs / 2) | 0;
}
else
{
// valid!
break;
}
}
return maxIfs;
};
module.exports = CheckShaderMax;

View file

@ -1,10 +1,37 @@
/** /**
* @author Richard Davey <rich@photonstorm.com> * @author Richard Davey <rich@photonstorm.com>
* @author Felipe Alfonso <@bitnenfer> * @author Felipe Alfonso <@bitnenfer>
* @author Matthew Groves <@doormat>
* @copyright 2020 Photon Storm Ltd. * @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License} * @license {@link https://opensource.org/licenses/MIT|MIT License}
*/ */
/**
* Generate shader source to test maximum ifs.
*
* @private
* @param {number} maxIfs - The number of if statements to generate
*/
function GenerateSrc (maxIfs)
{
var src = '';
for (var i = 0; i < maxIfs; ++i)
{
if (i > 0)
{
src += '\nelse ';
}
if (i < maxIfs - 1)
{
src += 'if(test == ' + i + '.0){}';
}
}
return src;
}
/** /**
* @namespace Phaser.Renderer.WebGL.Utils * @namespace Phaser.Renderer.WebGL.Utils
* @since 3.0.0 * @since 3.0.0
@ -16,12 +43,12 @@ module.exports = {
* *
* @function Phaser.Renderer.WebGL.Utils.getTintFromFloats * @function Phaser.Renderer.WebGL.Utils.getTintFromFloats
* @since 3.0.0 * @since 3.0.0
* *
* @param {number} r - Red component in a range from 0.0 to 1.0 * @param {number} r - Red component in a range from 0.0 to 1.0
* @param {number} g - Green component in a range from 0.0 to 1.0 * @param {number} g - Green component in a range from 0.0 to 1.0
* @param {number} b - Blue component in a range from 0.0 to 1.0 * @param {number} b - Blue component in a range from 0.0 to 1.0
* @param {number} a - Alpha component in a range from 0.0 to 1.0 * @param {number} a - Alpha component in a range from 0.0 to 1.0
* *
* @return {number} The packed RGBA values as a Uint32. * @return {number} The packed RGBA values as a Uint32.
*/ */
getTintFromFloats: function (r, g, b, a) getTintFromFloats: function (r, g, b, a)
@ -40,10 +67,10 @@ module.exports = {
* *
* @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha
* @since 3.0.0 * @since 3.0.0
* *
* @param {number} rgb - Uint24 representing RGB components * @param {number} rgb - Uint24 representing RGB components
* @param {number} a - Float32 representing Alpha component * @param {number} a - Float32 representing Alpha component
* *
* @return {number} Packed RGBA as Uint32 * @return {number} Packed RGBA as Uint32
*/ */
getTintAppendFloatAlpha: function (rgb, a) getTintAppendFloatAlpha: function (rgb, a)
@ -54,15 +81,15 @@ module.exports = {
/** /**
* Packs a Uint24, representing RGB components, with a Float32, representing * Packs a Uint24, representing RGB components, with a Float32, representing
* the alpha component, with a range between 0.0 and 1.0 and return a * the alpha component, with a range between 0.0 and 1.0 and return a
* swizzled Uint32 * swizzled Uint32
* *
* @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap
* @since 3.0.0 * @since 3.0.0
* *
* @param {number} rgb - Uint24 representing RGB components * @param {number} rgb - Uint24 representing RGB components
* @param {number} a - Float32 representing Alpha component * @param {number} a - Float32 representing Alpha component
* *
* @return {number} Packed RGBA as Uint32 * @return {number} Packed RGBA as Uint32
*/ */
getTintAppendFloatAlphaAndSwap: function (rgb, a) getTintAppendFloatAlphaAndSwap: function (rgb, a)
@ -80,10 +107,10 @@ module.exports = {
* *
* @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB * @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB
* @since 3.0.0 * @since 3.0.0
* *
* @param {number} rgb - RGB packed as a Uint24 * @param {number} rgb - RGB packed as a Uint24
* *
* @return {array} Array of floats representing each component as a float * @return {array} Array of floats representing each component as a float
*/ */
getFloatsFromUintRGB: function (rgb) getFloatsFromUintRGB: function (rgb)
{ {
@ -99,10 +126,10 @@ module.exports = {
* *
* @function Phaser.Renderer.WebGL.Utils.getComponentCount * @function Phaser.Renderer.WebGL.Utils.getComponentCount
* @since 3.0.0 * @since 3.0.0
* *
* @param {array} attributes - Array of attributes * @param {array} attributes - Array of attributes
* @param {WebGLRenderingContext} glContext - WebGLContext used for check types * @param {WebGLRenderingContext} glContext - WebGLContext used for check types
* *
* @return {number} Count of 32 bit attributes in vertex * @return {number} Count of 32 bit attributes in vertex
*/ */
getComponentCount: function (attributes, glContext) getComponentCount: function (attributes, glContext)
@ -112,7 +139,7 @@ module.exports = {
for (var index = 0; index < attributes.length; ++index) for (var index = 0; index < attributes.length; ++index)
{ {
var element = attributes[index]; var element = attributes[index];
if (element.type === glContext.FLOAT) if (element.type === glContext.FLOAT)
{ {
count += element.size; count += element.size;
@ -124,6 +151,58 @@ module.exports = {
} }
return count; return count;
},
/**
* Check to see how many texture units the GPU supports, based on the given config value.
* Then tests this against the maximum number of iterations GLSL can support.
*
* @function Phaser.Renderer.WebGL.Utils.checkShaderMax
* @since 3.25.0
*
* @param {WebGLRenderingContext} gl - The WebGLContext used to create the shaders.
* @param {number} maxTextures - The Game Config maxTextures value.
*
* @return {number} The number of texture units that is supported by this browser and GPU.
*/
checkShaderMax: function (gl, maxTextures)
{
if (!maxTextures || maxTextures === -1)
{
maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
}
var shader = gl.createShader(gl.FRAGMENT_SHADER);
var fragTemplate = [
'precision mediump float;',
'void main(void){',
'float test = 0.1;',
'%forloop%',
'gl_FragColor = vec4(0.0);',
'}'
].join('\n');
// eslint-disable-next-line no-constant-condition
while (true)
{
var fragmentSrc = fragTemplate.replace(/%forloop%/gi, GenerateSrc(maxTextures));
gl.shaderSource(shader, fragmentSrc);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
{
maxTextures = (maxTextures / 2) | 0;
}
else
{
// valid!
break;
}
}
return maxTextures;
} }
}; };