From 573eee7ee2ce02b2a3fc58303385c2dd10f87461 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Fri, 24 May 2019 21:35:05 +0100
Subject: [PATCH 01/18] WIP demo parallel compile
---
src/renderers/WebGLRenderer.js | 25 ++++-
src/renderers/webgl/WebGLProgram.js | 166 ++++++++++++++++++----------
2 files changed, 129 insertions(+), 62 deletions(-)
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index 2bc6744bf912f..bb910a607233d 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -714,6 +714,8 @@ function WebGLRenderer( parameters ) {
var program = setProgram( camera, fog, material, object );
+ if ( ! program.ready ) return;
+
var updateBuffers = false;
if ( _currentGeometryProgram.geometry !== geometry.id ||
@@ -1417,6 +1419,8 @@ function WebGLRenderer( parameters ) {
var program = setProgram( camera, scene.fog, material, object );
+ if ( ! program.ready ) return;
+
_currentGeometryProgram.geometry = null;
_currentGeometryProgram.program = null;
_currentGeometryProgram.wireframe = false;
@@ -1462,13 +1466,14 @@ function WebGLRenderer( parameters ) {
// changed glsl or parameters
releaseMaterialProgramReference( material );
- } else if ( lightsHash.stateID !== lightsStateHash.stateID ||
+ } else if ( program.ready && (
+ lightsHash.stateID !== lightsStateHash.stateID ||
lightsHash.directionalLength !== lightsStateHash.directionalLength ||
lightsHash.pointLength !== lightsStateHash.pointLength ||
lightsHash.spotLength !== lightsStateHash.spotLength ||
lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength ||
lightsHash.hemiLength !== lightsStateHash.hemiLength ||
- lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) {
+ lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) ) {
lightsHash.stateID = lightsStateHash.stateID;
lightsHash.directionalLength = lightsStateHash.directionalLength;
@@ -1480,7 +1485,7 @@ function WebGLRenderer( parameters ) {
programChange = false;
- } else if ( parameters.shaderID !== undefined ) {
+ } else if ( program.ready && parameters.shaderID !== undefined ) {
// same glsl and uniform list
return;
@@ -1528,6 +1533,13 @@ function WebGLRenderer( parameters ) {
}
+ if (! program.ready && ! program.isLinked( _this, material ) ) {
+
+ materialProperties.lightsHash = {};
+ return;
+
+ }
+
var programAttributes = program.getAttributes();
if ( material.morphTargets ) {
@@ -1691,8 +1703,11 @@ function WebGLRenderer( parameters ) {
var refreshMaterial = false;
var refreshLights = false;
- var program = materialProperties.program,
- p_uniforms = program.getUniforms(),
+ var program = materialProperties.program;
+
+ if ( ! program.ready ) return false;
+
+ var p_uniforms = program.getUniforms(),
m_uniforms = materialProperties.shader.uniforms;
if ( state.useProgram( program.program ) ) {
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index 177fc82f07f68..d05e9722e834e 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -607,6 +607,8 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
}
+ var parallelShaderExt = extensions.get( 'KHR_parallel_shader_compile' );
+
var vertexGlsl = prefixVertex + vertexShader;
var fragmentGlsl = prefixFragment + fragmentShader;
@@ -632,70 +634,30 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
}
- gl.linkProgram( program );
-
- // check for link errors
- if ( renderer.debug.checkShaderErrors ) {
-
- var programLog = gl.getProgramInfoLog( program ).trim();
- var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
- var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
- var vertexErrors = getShaderErrors( gl, glVertexShader );
- var fragmentErrors = getShaderErrors( gl, glFragmentShader );
-
- var runnable = true;
- var haveDiagnostics = true;
-
- if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
-
- runnable = false;
-
- console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors );
-
- } else if ( programLog !== '' ) {
-
- console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
-
- } else if ( vertexLog === '' || fragmentLog === '' ) {
-
- haveDiagnostics = false;
-
- }
-
- if ( haveDiagnostics ) {
-
- this.diagnostics = {
-
- runnable: runnable,
- material: material,
-
- programLog: programLog,
-
- vertexShader: {
+ this.program = program;
+ this.vertexShader = glVertexShader;
+ this.fragmentShader = glFragmentShader;
+ this.parallelShaderExt = parallelShaderExt;
+ this.prefixVertex = prefixVertex;
+ this.prefixFragment = prefixFragment;
- log: vertexLog,
- prefix: prefixVertex
+ gl.linkProgram( program );
- },
+ this.ready = true;
- fragmentShader: {
+// var status = gl.getProgramParameter( program, parallelShaderExt.COMPLETION_STATUS_KHR );
- log: fragmentLog,
- prefix: prefixFragment
+ if ( parallelShaderExt === null ) {
- }
+ // check for link errors
+ this.checkLink( renderer, material );
- };
+ } else {
- }
+ this.ready = false;
}
- // clean up
-
- gl.deleteShader( glVertexShader );
- gl.deleteShader( glFragmentShader );
-
// set up caching for uniform locations
var cachedUniforms;
@@ -768,12 +730,102 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
this.id = programIdCount ++;
this.code = code;
this.usedTimes = 1;
- this.program = program;
- this.vertexShader = glVertexShader;
- this.fragmentShader = glFragmentShader;
return this;
}
+Object.assign( WebGLProgram.prototype, {
+
+ isLinked: function ( renderer, material ) {
+
+ var gl = renderer.context;
+
+ if ( gl.getProgramParameter( this.program, this.parallelShaderExt.COMPLETION_STATUS_KHR ) == true ) {
+
+ this.checkLink( renderer, material );
+ this.ready = true;
+
+ } else {
+
+ console.log( 'not ready' );
+
+ }
+
+ return this.ready;
+
+ },
+
+ checkLink: function ( renderer, material ) {
+
+ // check for link errors
+
+ var gl = renderer.context;
+ var program = this.program;
+ var glVertexShader = this.vertexShader;
+ var glFragmentShader = this.fragmentShader;
+
+ if ( renderer.debug.checkShaderErrors ) {
+
+ var programLog = gl.getProgramInfoLog( program ).trim();
+ var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
+ var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
+ var vertexErrors = getShaderErrors( gl, glVertexShader );
+ var fragmentErrors = getShaderErrors( gl, glFragmentShader );
+
+ var runnable = true;
+ var haveDiagnostics = true;
+
+ if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
+
+ runnable = false;
+
+ console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors );
+
+ } else if ( programLog !== '' ) {
+
+ console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
+
+ } else if ( vertexLog === '' || fragmentLog === '' ) {
+
+ haveDiagnostics = false;
+
+ }
+
+ if ( haveDiagnostics ) {
+
+ this.diagnostics = {
+
+ runnable: runnable,
+ material: material,
+
+ programLog: programLog,
+
+ vertexShader: {
+
+ log: vertexLog,
+ prefix: this.prefixVertex
+
+ },
+
+ fragmentShader: {
+
+ log: fragmentLog,
+ prefix: this.prefixFragment
+
+ }
+
+ };
+
+ }
+
+ }
+
+ gl.deleteShader( glVertexShader );
+ gl.deleteShader( glFragmentShader );
+
+ }
+
+} );
+
export { WebGLProgram };
From 2d30ed58772302420cd9a8bcb8cb3e16706168f4 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Sat, 25 May 2019 16:09:02 +0100
Subject: [PATCH 02/18] WIP
---
src/renderers/WebGLRenderer.js | 2 +-
src/renderers/webgl/WebGLCapabilities.js | 5 ++++-
src/renderers/webgl/WebGLProgram.js | 11 ++++-------
src/renderers/webgl/WebGLShader.d.ts | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index bb910a607233d..3e7c84d711a2e 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -1533,7 +1533,7 @@ function WebGLRenderer( parameters ) {
}
- if (! program.ready && ! program.isLinked( _this, material ) ) {
+ if ( ! program.ready && ! program.isLinked( _this, material ) ) {
materialProperties.lightsHash = {};
return;
diff --git a/src/renderers/webgl/WebGLCapabilities.js b/src/renderers/webgl/WebGLCapabilities.js
index 4eafd2132f9ce..7d1a0e9c93282 100644
--- a/src/renderers/webgl/WebGLCapabilities.js
+++ b/src/renderers/webgl/WebGLCapabilities.js
@@ -85,6 +85,7 @@ function WebGLCapabilities( gl, extensions, parameters ) {
var floatVertexTextures = vertexTextures && floatFragmentTextures;
var maxSamples = isWebGL2 ? gl.getParameter( gl.MAX_SAMPLES ) : 0;
+ var parallelShaderCompile = extensions.get( 'KHR_parallel_shader_compile' );
return {
@@ -110,7 +111,9 @@ function WebGLCapabilities( gl, extensions, parameters ) {
floatFragmentTextures: floatFragmentTextures,
floatVertexTextures: floatVertexTextures,
- maxSamples: maxSamples
+ maxSamples: maxSamples,
+
+ parallelShaderCompile: parallelShaderCompile
};
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index d05e9722e834e..43e138119dfd6 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -607,7 +607,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
}
- var parallelShaderExt = extensions.get( 'KHR_parallel_shader_compile' );
+ var parallelShaderExt = capabilities.parallelShaderCompile;
var vertexGlsl = prefixVertex + vertexShader;
var fragmentGlsl = prefixFragment + fragmentShader;
@@ -615,8 +615,8 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
// console.log( '*VERTEX*', vertexGlsl );
// console.log( '*FRAGMENT*', fragmentGlsl );
- var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl, renderer.debug.checkShaderErrors );
- var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl, renderer.debug.checkShaderErrors );
+ var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
+ var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
gl.attachShader( program, glVertexShader );
gl.attachShader( program, glFragmentShader );
@@ -643,14 +643,11 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
gl.linkProgram( program );
- this.ready = true;
-
-// var status = gl.getProgramParameter( program, parallelShaderExt.COMPLETION_STATUS_KHR );
-
if ( parallelShaderExt === null ) {
// check for link errors
this.checkLink( renderer, material );
+ this.ready = true;
} else {
diff --git a/src/renderers/webgl/WebGLShader.d.ts b/src/renderers/webgl/WebGLShader.d.ts
index 8ff468bfe72a2..f02159dc86a7e 100644
--- a/src/renderers/webgl/WebGLShader.d.ts
+++ b/src/renderers/webgl/WebGLShader.d.ts
@@ -1,3 +1,3 @@
export class WebGLShader {
- constructor(gl: any, type: string, string: string, debug: boolean);
+ constructor(gl: any, type: string, string: string);
}
From bc791346426cbcb3ec803c73c29ec8ea79c86293 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Thu, 30 May 2019 17:05:49 +0100
Subject: [PATCH 03/18] adjust to lhash
---
src/renderers/WebGLRenderer.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index 05e7e2512e6b6..d271333f58c24 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -1524,7 +1524,6 @@ function WebGLRenderer( parameters ) {
if ( ! program.ready && ! program.isLinked( _this, material ) ) {
- materialProperties.lightsHash = {};
return;
}
From 756ab0274a131e6ab7b424da2d4be8e8517c8d68 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Thu, 30 May 2019 22:55:51 +0100
Subject: [PATCH 04/18] make material specific
---
src/renderers/webgl/WebGLProgram.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index e12afa99b9b1e..06ceea7a86ebb 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -643,15 +643,15 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
gl.linkProgram( program );
- if ( parallelShaderExt === null ) {
+ if ( parallelShaderExt !== null && material.parallelCompile ) {
- // check for link errors
- this.checkLink( renderer, material );
- this.ready = true;
+ this.ready = false;
} else {
- this.ready = false;
+ // check for link errors
+ this.checkLink( renderer, material );
+ this.ready = true;
}
From 4359c68e13bf647e53c3570a35a4b48711a5f887 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Thu, 30 May 2019 22:56:46 +0100
Subject: [PATCH 05/18] WIP shared programs etc
---
src/renderers/WebGLRenderer.js | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index d271333f58c24..f50958b7a696a 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -1468,7 +1468,7 @@ function WebGLRenderer( parameters ) {
// changed glsl or parameters
releaseMaterialProgramReference( material );
- } else if ( materialProperties.lightsStateVersion !== lightsStateVersion ) {
+ } else if ( program.ready && materialProperties.lightsStateVersion !== lightsStateVersion ) {
materialProperties.lightsStateVersion = lightsStateVersion;
@@ -1524,10 +1524,13 @@ function WebGLRenderer( parameters ) {
if ( ! program.ready && ! program.isLinked( _this, material ) ) {
+ materialProperties.retry = true;
return;
}
+ materialProperties.retry = false;
+
var programAttributes = program.getAttributes();
if ( material.morphTargets ) {
@@ -1660,7 +1663,7 @@ function WebGLRenderer( parameters ) {
}
- if ( material.needsUpdate ) {
+ if ( material.needsUpdate || materialProperties.retry ) {
initMaterial( material, fog, object );
material.needsUpdate = false;
From 60bce20e884512d0b9ec0f63b684495e360a3da9 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Thu, 30 May 2019 22:57:04 +0100
Subject: [PATCH 06/18] default to no parallel compile
---
src/materials/Material.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/materials/Material.js b/src/materials/Material.js
index 53686cecd415f..326a015696777 100644
--- a/src/materials/Material.js
+++ b/src/materials/Material.js
@@ -61,6 +61,7 @@ function Material() {
this.premultipliedAlpha = false;
this.visible = true;
+ this.parallelCompile = false;
this.userData = {};
From adff02299fe7ca0f543d402288776f4c1166c891 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Fri, 31 May 2019 14:32:58 +0100
Subject: [PATCH 07/18] testing
---
src/materials/MeshStandardMaterial.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/materials/MeshStandardMaterial.js b/src/materials/MeshStandardMaterial.js
index cbbe32dc34d1c..57bde8635dcf7 100644
--- a/src/materials/MeshStandardMaterial.js
+++ b/src/materials/MeshStandardMaterial.js
@@ -109,6 +109,7 @@ function MeshStandardMaterial( parameters ) {
this.skinning = false;
this.morphTargets = false;
this.morphNormals = false;
+ this.parallelCompile = true;
this.setValues( parameters );
From eb44c9ad29c0180cb8a68e82cf804ea676d8b897 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 3 Jun 2019 10:48:05 +0100
Subject: [PATCH 08/18] remove testing parts
---
src/materials/MeshStandardMaterial.js | 1 -
src/renderers/webgl/WebGLProgram.js | 4 ----
2 files changed, 5 deletions(-)
diff --git a/src/materials/MeshStandardMaterial.js b/src/materials/MeshStandardMaterial.js
index 57bde8635dcf7..cbbe32dc34d1c 100644
--- a/src/materials/MeshStandardMaterial.js
+++ b/src/materials/MeshStandardMaterial.js
@@ -109,7 +109,6 @@ function MeshStandardMaterial( parameters ) {
this.skinning = false;
this.morphTargets = false;
this.morphNormals = false;
- this.parallelCompile = true;
this.setValues( parameters );
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index 06ceea7a86ebb..e22435ec13128 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -743,10 +743,6 @@ Object.assign( WebGLProgram.prototype, {
this.checkLink( renderer, material );
this.ready = true;
- } else {
-
- console.log( 'not ready' );
-
}
return this.ready;
From 368e91b270afd34bb22484188daaa6b405d752ff Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 3 Jun 2019 12:25:49 +0100
Subject: [PATCH 09/18] add sync mode to preserve .compile() behaviour
---
src/renderers/WebGLRenderer.js | 10 +++++-----
src/renderers/webgl/WebGLProgram.js | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index f50958b7a696a..48b7adfecdde3 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -1044,13 +1044,13 @@ function WebGLRenderer( parameters ) {
for ( var i = 0; i < object.material.length; i ++ ) {
- initMaterial( object.material[ i ], scene.fog, object );
+ initMaterial( object.material[ i ], scene.fog, object, true );
}
} else {
- initMaterial( object.material, scene.fog, object );
+ initMaterial( object.material, scene.fog, object, true );
}
@@ -1441,7 +1441,7 @@ function WebGLRenderer( parameters ) {
}
- function initMaterial( material, fog, object ) {
+ function initMaterial( material, fog, object, sync ) {
var materialProperties = properties.get( material );
@@ -1522,7 +1522,7 @@ function WebGLRenderer( parameters ) {
}
- if ( ! program.ready && ! program.isLinked( _this, material ) ) {
+ if ( ! program.ready && ! program.isLinked( _this, material, sync ) ) {
materialProperties.retry = true;
return;
@@ -1665,7 +1665,7 @@ function WebGLRenderer( parameters ) {
if ( material.needsUpdate || materialProperties.retry ) {
- initMaterial( material, fog, object );
+ initMaterial( material, fog, object, false );
material.needsUpdate = false;
}
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index e22435ec13128..22fb191d502b2 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -734,11 +734,11 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
Object.assign( WebGLProgram.prototype, {
- isLinked: function ( renderer, material ) {
+ isLinked: function ( renderer, material, sync ) {
var gl = renderer.context;
- if ( gl.getProgramParameter( this.program, this.parallelShaderExt.COMPLETION_STATUS_KHR ) == true ) {
+ if ( gl.getProgramParameter( this.program, this.parallelShaderExt.COMPLETION_STATUS_KHR ) == true || sync ) {
this.checkLink( renderer, material );
this.ready = true;
From 2a88ce0750aad5b596d69def6ed10a816c33fb42 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Tue, 4 Jun 2019 21:29:16 +0100
Subject: [PATCH 10/18] limit simultaneous compiles
---
src/renderers/webgl/WebGLProgram.js | 97 ++++++++++++++++++++---------
1 file changed, 69 insertions(+), 28 deletions(-)
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index 22fb191d502b2..090efce470c03 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -8,6 +8,8 @@ import { ShaderChunk } from '../shaders/ShaderChunk.js';
import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, EquirectangularRefractionMapping, CubeRefractionMapping, SphericalReflectionMapping, EquirectangularReflectionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, ACESFilmicToneMapping, CineonToneMapping, Uncharted2ToneMapping, ReinhardToneMapping, LinearToneMapping, GammaEncoding, RGBDEncoding, RGBM16Encoding, RGBM7Encoding, RGBEEncoding, sRGBEncoding, LinearEncoding } from '../../constants.js';
var programIdCount = 0;
+var maxParallel = 1;
+var currentParallel = 0;
function addLineNumbers( string ) {
@@ -609,47 +611,36 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
var parallelShaderExt = capabilities.parallelShaderCompile;
- var vertexGlsl = prefixVertex + vertexShader;
- var fragmentGlsl = prefixFragment + fragmentShader;
-
- // console.log( '*VERTEX*', vertexGlsl );
- // console.log( '*FRAGMENT*', fragmentGlsl );
-
- var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
- var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
+ this.prefixVertex = prefixVertex;
+ this.prefixFragment = prefixFragment;
- gl.attachShader( program, glVertexShader );
- gl.attachShader( program, glFragmentShader );
+ this.vertexShader = vertexShader;
+ this.fragmentShader = fragmentShader;
- // Force a particular attribute to index 0.
+ this.program = program;
+ this.parameters = parameters;
+ this.parallelShaderExt = parallelShaderExt;
+ this.pending = false;
- if ( material.index0AttributeName !== undefined ) {
+ if ( parallelShaderExt !== null && material.parallelCompile ) {
- gl.bindAttribLocation( program, 0, material.index0AttributeName );
+ if ( currentParallel < maxParallel ) {
- } else if ( parameters.morphTargets === true ) {
+ this.compileAndLink( renderer, material );
+ currentParallel ++;
- // programs with morphTargets displace position out of attribute 0
- gl.bindAttribLocation( program, 0, 'position' );
+ } else {
- }
+ this.pending = true;
- this.program = program;
- this.vertexShader = glVertexShader;
- this.fragmentShader = glFragmentShader;
- this.parallelShaderExt = parallelShaderExt;
- this.prefixVertex = prefixVertex;
- this.prefixFragment = prefixFragment;
-
- gl.linkProgram( program );
-
- if ( parallelShaderExt !== null && material.parallelCompile ) {
+ }
this.ready = false;
} else {
// check for link errors
+ this.compileAndLink( renderer, material );
this.checkLink( renderer, material );
this.ready = true;
@@ -734,14 +725,64 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
Object.assign( WebGLProgram.prototype, {
+ compileAndLink: function ( renderer, material ) {
+
+ var gl = renderer.context;
+
+ var program = this.program;
+ var vertexGlsl = this.prefixVertex + this.vertexShader;
+ var fragmentGlsl = this.prefixFragment + this.fragmentShader;
+
+ this.startFrame = renderer.info.render.frame;
+
+ // console.log( '*VERTEX*', vertexGlsl );
+ // console.log( '*FRAGMENT*', fragmentGlsl );
+
+ var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
+ var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
+
+ gl.attachShader( program, glVertexShader );
+ gl.attachShader( program, glFragmentShader );
+
+ // Force a particular attribute to index 0.
+
+ if ( material.index0AttributeName !== undefined ) {
+
+ gl.bindAttribLocation( program, 0, material.index0AttributeName );
+
+ } else if ( this.parameters.morphTargets === true ) {
+
+ // programs with morphTargets displace position out of attribute 0
+ gl.bindAttribLocation( program, 0, 'position' );
+
+ }
+
+ gl.linkProgram( program );
+
+ this.vertexShader = glVertexShader;
+ this.fragmentShader = glFragmentShader;
+
+ },
+
isLinked: function ( renderer, material, sync ) {
var gl = renderer.context;
- if ( gl.getProgramParameter( this.program, this.parallelShaderExt.COMPLETION_STATUS_KHR ) == true || sync ) {
+ if ( this.pending && currentParallel < maxParallel ) {
+
+ this.compileAndLink( renderer, material );
+ currentParallel ++;
+ this.pending = false;
+
+ }
+
+ if ( ( ! this.pending && gl.getProgramParameter( this.program, this.parallelShaderExt.COMPLETION_STATUS_KHR ) == true ) || sync ) {
this.checkLink( renderer, material );
this.ready = true;
+ currentParallel --;
+
+ console.log( 'done', this.startFrame, renderer.info.render.frame - this.startFrame );
}
From 774b5c8383d1c9fb0e2d63fd62c1c2ef4da5ed21 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 16 Sep 2019 10:55:39 +0100
Subject: [PATCH 11/18] document capability
---
docs/api/en/renderers/WebGLRenderer.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/api/en/renderers/WebGLRenderer.html b/docs/api/en/renderers/WebGLRenderer.html
index fbf2f2c39d90e..b8eac906a6bf3 100644
--- a/docs/api/en/renderers/WebGLRenderer.html
+++ b/docs/api/en/renderers/WebGLRenderer.html
@@ -133,6 +133,7 @@ [property:Object capabilities]
- [page:Integer maxVertexUniforms]: The value of *gl.MAX_VERTEX_UNIFORM_VECTORS*.
The maximum number of uniforms that can be used in a vertex shader.
- [page:String precision]: The shader precision currently being used by the renderer.
+ - [page:Boolean parallelShaderCompile]: whether the context supports the [link:https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/ KHR_parallel_shader_compile] extension..
- [page:Boolean vertexTextures]: *true* if [property:Integer maxVertexTextures] is greater than 0 (i.e. vertext textures can be used).
From b2f5822ec6cdc1d8c8e87a93259b7e331b9de53c Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 16 Sep 2019 11:00:49 +0100
Subject: [PATCH 12/18] doc update
---
docs/api/en/renderers/WebGLRenderer.html | 2 +-
docs/api/zh/renderers/WebGLRenderer.html | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/api/en/renderers/WebGLRenderer.html b/docs/api/en/renderers/WebGLRenderer.html
index b8eac906a6bf3..b54691120afd8 100644
--- a/docs/api/en/renderers/WebGLRenderer.html
+++ b/docs/api/en/renderers/WebGLRenderer.html
@@ -132,8 +132,8 @@ [property:Object capabilities]
The number of textures that can be used in a vertex shader.
- [page:Integer maxVertexUniforms]: The value of *gl.MAX_VERTEX_UNIFORM_VECTORS*.
The maximum number of uniforms that can be used in a vertex shader.
- - [page:String precision]: The shader precision currently being used by the renderer.
- [page:Boolean parallelShaderCompile]: whether the context supports the [link:https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/ KHR_parallel_shader_compile] extension..
+ - [page:String precision]: The shader precision currently being used by the renderer.
- [page:Boolean vertexTextures]: *true* if [property:Integer maxVertexTextures] is greater than 0 (i.e. vertext textures can be used).
diff --git a/docs/api/zh/renderers/WebGLRenderer.html b/docs/api/zh/renderers/WebGLRenderer.html
index d2f9b026c3893..1d03718690940 100644
--- a/docs/api/zh/renderers/WebGLRenderer.html
+++ b/docs/api/zh/renderers/WebGLRenderer.html
@@ -113,6 +113,7 @@ [property:Object capabilities]
- [page:Integer maxVaryings]: *gl.MAX_VARYING_VECTORS*的值,着色器可使用矢量的数量
- [page:Integer maxVertexTextures]: *gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS*的值,顶点着色器可使用的纹理数量。
- [page:Integer maxVertexUniforms]: *gl.MAX_VERTEX_UNIFORM_VECTORS*的值,顶点着色器可使用的全局变量(uniforms)数量
+ - [page:Boolean parallelShaderCompile]: whether the context supports the [link:https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/ KHR_parallel_shader_compile] extension..
- [page:String precision]: 渲染器当前使用的着色器的精度
- [page:Boolean vertexTextures]: 如果[property:Integer maxVertexTextures]大于0,此值为*true* (即可以使用顶点纹理)
From 715f6f3c6cd67bf2eb95b9c6663dbf300022aaa2 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 16 Sep 2019 11:06:07 +0100
Subject: [PATCH 13/18] use getContext()
---
src/renderers/webgl/WebGLProgram.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index 0efb306aefd23..a2695cc34e0e0 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -686,7 +686,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
this.pending = false;
this.numMultiviewViews = numMultiviewViews;
- if ( parallelShaderExt !== null && material.parallelCompile ) {
+ if ( parallelShaderExt !== null && renderer.parallelCompile ) {
if ( currentParallel < maxParallel ) {
@@ -766,7 +766,7 @@ Object.assign( WebGLProgram.prototype, {
compileAndLink: function ( renderer, material ) {
- var gl = renderer.context;
+ var gl = renderer.getContext();
var program = this.program;
var vertexGlsl = this.prefixVertex + this.vertexShader;
@@ -805,7 +805,7 @@ Object.assign( WebGLProgram.prototype, {
isLinked: function ( renderer, material, sync ) {
- var gl = renderer.context;
+ var gl = renderer.getContext();
if ( this.pending && currentParallel < maxParallel ) {
@@ -833,7 +833,7 @@ Object.assign( WebGLProgram.prototype, {
// check for link errors
- var gl = renderer.context;
+ var gl = renderer.getContext();
var program = this.program;
var glVertexShader = this.vertexShader;
var glFragmentShader = this.fragmentShader;
From c04a23172e83f32b4bad1c12625d25e2e495a0ab Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 16 Sep 2019 11:06:28 +0100
Subject: [PATCH 14/18] remove Material.parallelCompile
---
src/materials/Material.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/materials/Material.js b/src/materials/Material.js
index b0cb3e0d2692a..ee22bec3fa1c7 100644
--- a/src/materials/Material.js
+++ b/src/materials/Material.js
@@ -70,7 +70,6 @@ function Material() {
this.premultipliedAlpha = false;
this.visible = true;
- this.parallelCompile = false;
this.toneMapped = true;
From 810c9c21032eb8613a6676818f5595753c7cc4e0 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 16 Sep 2019 14:49:26 +0100
Subject: [PATCH 15/18] move switch back to material
---
src/materials/Material.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/materials/Material.js b/src/materials/Material.js
index ee22bec3fa1c7..c134bd31a7304 100644
--- a/src/materials/Material.js
+++ b/src/materials/Material.js
@@ -69,6 +69,7 @@ function Material() {
this.alphaTest = 0;
this.premultipliedAlpha = false;
+ this.parallelCompile = false;
this.visible = true;
this.toneMapped = true;
From 9ac963f23206940b544027b64ac0eb2b8a643996 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Mon, 16 Sep 2019 14:52:54 +0100
Subject: [PATCH 16/18] fix race on destruction and tidy
---
src/renderers/webgl/WebGLProgram.js | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index a2695cc34e0e0..9945c961c082b 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -686,7 +686,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
this.pending = false;
this.numMultiviewViews = numMultiviewViews;
- if ( parallelShaderExt !== null && renderer.parallelCompile ) {
+ if ( parallelShaderExt !== null && material.parallelCompile ) {
if ( currentParallel < maxParallel ) {
@@ -746,6 +746,14 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
this.destroy = function () {
+ if ( ! this.ready && ! this.pending ) {
+
+ // parallel compilation incomplete
+
+ currentParallel --;
+
+ }
+
gl.deleteProgram( program );
this.program = undefined;
@@ -810,8 +818,8 @@ Object.assign( WebGLProgram.prototype, {
if ( this.pending && currentParallel < maxParallel ) {
this.compileAndLink( renderer, material );
- currentParallel ++;
this.pending = false;
+ currentParallel ++;
}
@@ -821,7 +829,7 @@ Object.assign( WebGLProgram.prototype, {
this.ready = true;
currentParallel --;
- console.log( 'done', this.startFrame, renderer.info.render.frame - this.startFrame );
+ console.log( 'THREE.WebGLProgram: parallel compile frame count', renderer.info.render.frame - this.startFrame );
}
From 25d3707095eff0ac5c10e76879e7ae57086c35b4 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Tue, 17 Sep 2019 11:11:51 +0100
Subject: [PATCH 17/18] Add global default
---
src/materials/Material.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/materials/Material.js b/src/materials/Material.js
index c134bd31a7304..54fb7b7ac87be 100644
--- a/src/materials/Material.js
+++ b/src/materials/Material.js
@@ -69,7 +69,7 @@ function Material() {
this.alphaTest = 0;
this.premultipliedAlpha = false;
- this.parallelCompile = false;
+ this.parallelCompile = Material.DefaultParallelCompile;
this.visible = true;
this.toneMapped = true;
@@ -80,6 +80,8 @@ function Material() {
}
+Material.DefaultParallelCompile = false;
+
Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
constructor: Material,
From e8ddd765e09236f08e990744bd3569f4134e68a4 Mon Sep 17 00:00:00 2001
From: aardgoose
Date: Fri, 20 Sep 2019 10:55:56 +0100
Subject: [PATCH 18/18] pass extension in parameters
---
src/renderers/webgl/WebGLProgram.js | 2 +-
src/renderers/webgl/WebGLPrograms.js | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index f000fffc02c47..5a42cb3c6f77f 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -721,7 +721,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
}
- var parallelShaderExt = capabilities.parallelShaderCompile;
+ var parallelShaderExt = parameters.parallelShaderCompile;
this.prefixVertex = prefixVertex;
this.prefixFragment = prefixFragment;
diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js
index e8dadaa580cd5..9079ad5a90016 100644
--- a/src/renderers/webgl/WebGLPrograms.js
+++ b/src/renderers/webgl/WebGLPrograms.js
@@ -139,6 +139,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
precision: precision,
isWebGL2: capabilities.isWebGL2,
supportsVertexTextures: capabilities.vertexTextures,
+ parallelShaderCompile: capabilities.parallelShaderCompile,
outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),
map: !! material.map,
mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),