Skip to content

Commit

Permalink
Tech to allow async shader compilation, disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Valigursky committed Feb 23, 2024
1 parent d807226 commit 287ec79
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/platform/graphics/graphics-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ class GraphicsDevice extends EventHandler {
this.vertexBuffers = [];
this.shader = null;
this.shaderValid = undefined;
this.shaderAsyncCompile = false;
this.renderTarget = null;
}

Expand Down
2 changes: 1 addition & 1 deletion src/platform/graphics/null/null-graphics-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class NullGraphicsDevice extends GraphicsDevice {
draw(primitive, numInstances = 1, keepBuffers) {
}

setShader(shader) {
setShader(shader, asyncCompile = false) {
}

setBlendState(blendState) {
Expand Down
57 changes: 46 additions & 11 deletions src/platform/graphics/webgl/webgl-graphics-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
draw(primitive, numInstances, keepBuffers) {
const gl = this.gl;

this.activateShader();
this.activateShader(this);
if (!this.shaderValid)
return;

Expand Down Expand Up @@ -2749,9 +2749,19 @@ class WebglGraphicsDevice extends GraphicsDevice {
*
* @param {Shader} shader - The shader to assign to the device.
*/
setShader(shader) {

/**
* Sets the active shader to be used during subsequent draw calls.
*
* @param {Shader} shader - The shader to assign to the device.
* @param {boolean} asyncCompile - If true, rendering will be skipped until the shader is
* compiled, otherwise the rendering will wait for the shader compilation to finish. Defaults to
* false.
*/
setShader(shader, asyncCompile = false) {
if (shader !== this.shader) {
this.shader = shader;
this.shaderAsyncCompile = asyncCompile;
this.shaderValid = undefined; // need to run activation / validation

// #if _PROFILER
Expand All @@ -2760,21 +2770,46 @@ class WebglGraphicsDevice extends GraphicsDevice {
}
}

activateShader() {
activateShader(device) {

const { shader } = this;
const { impl } = shader;
if (this.shaderValid === undefined) {
const { shader } = this;

if (shader.failed) {
this.shaderValid = false;
} else if (!shader.ready && !shader.impl.finalize(this, shader)) {
shader.failed = true;
this.shaderValid = false;
} else {
// Set the active shader
this.gl.useProgram(shader.impl.glProgram);
this.shaderValid = true;
} else if (!shader.ready) {

// if the shader is async compiled and can be skipped if not ready
if (this.shaderAsyncCompile) {

// if the shader is linked, finalize it
if (impl.isLinked(device)) {
if (!impl.finalize(this, shader)) {
shader.failed = true;
this.shaderValid = false;
}
} else {
// skip the async shader rendering
this.shaderValid = false;
}

} else {

// this cannot be skipped, wait for the shader to be ready
if (!impl.finalize(this, shader)) {
shader.failed = true;
this.shaderValid = false;
}
}
}
}

if (this.shaderValid === undefined) {
// Set the active shader
this.gl.useProgram(impl.glProgram);
this.shaderValid = true;
}
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/platform/graphics/webgl/webgl-shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,23 @@ class WebglShader {
return true;
}

/**
* Check the linking status of a shader.
*
* @param {import('./webgl-graphics-device.js').WebglGraphicsDevice} device - The graphics device.
* @returns {boolean} True if the shader is already linked, false otherwise. Note that unless the
* device supports the KHR_parallel_shader_compile extension, this will always return true.
*/
isLinked(device) {

const { extParallelShaderCompile } = device;
if (extParallelShaderCompile) {
return device.gl.getProgramParameter(this.glProgram, extParallelShaderCompile.COMPLETION_STATUS_KHR);
}

return true;
}

/**
* Truncate the WebGL shader compilation log to just include the error line plus the 5 lines
* before and after it.
Expand Down
2 changes: 1 addition & 1 deletion src/platform/graphics/webgpu/webgpu-graphics-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ class WebgpuGraphicsDevice extends GraphicsDevice {
}
}

setShader(shader) {
setShader(shader, asyncCompile = false) {

if (shader !== this.shader) {
this.shader = shader;
Expand Down
3 changes: 2 additions & 1 deletion src/scene/renderer/forward-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,8 @@ class ForwardRenderer extends Renderer {

if (newMaterial) {

device.setShader(shaderInstance.shader);
const asyncCompile = false;
device.setShader(shaderInstance.shader, asyncCompile);

// Uniforms I: material
material.setParameters(device);
Expand Down

0 comments on commit 287ec79

Please sign in to comment.