Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link WebGL shaders immediately after compilation #6076

Merged
merged 1 commit into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions src/platform/graphics/webgl/webgl-graphics-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -1352,15 +1352,6 @@ class WebglGraphicsDevice extends GraphicsDevice {
this.gpuProfiler?.restoreContext();
}

/**
* Called after a batch of shaders was created, to guide in their optimal preparation for rendering.
*
* @ignore
*/
endShaderBatch() {
WebglShader.endShaderBatch(this);
}

/**
* Set the active rectangle for rendering on the specified device.
*
Expand Down
35 changes: 5 additions & 30 deletions src/platform/graphics/webgl/webgl-shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,8 @@ class CompiledShaderCache {
}
}

// class used to hold a list of recently created shaders forming a batch, to allow their more optimized compilation
class ShaderBatchCache {
shaders = [];

loseContext(device) {
this.shaders = [];
}
}

const _vertexShaderCache = new DeviceCache();
const _fragmentShaderCache = new DeviceCache();
const _shaderBatchCache = new DeviceCache();

/**
* A WebGL implementation of the Shader.
Expand All @@ -58,12 +48,11 @@ class WebglShader {
constructor(shader) {
this.init();

// kick off vertex and fragment shader compilation, but not linking here, as that would
// make it blocking.
// kick off vertex and fragment shader compilation
this.compile(shader.device, shader);

// add the shader to recently created list
WebglShader.getBatchShaders(shader.device).push(shader);
// kick off linking, as this is non-blocking too
this.link(shader.device, shader);

// add it to a device list of all shaders
shader.device.shaders.push(shader);
Expand Down Expand Up @@ -91,22 +80,6 @@ class WebglShader {
this.glFragmentShader = null;
}

static getBatchShaders(device) {
const batchCache = _shaderBatchCache.get(device, () => {
return new ShaderBatchCache();
});
return batchCache.shaders;
}

static endShaderBatch(device) {

// Trigger link step for all recently created shaders. This allows linking to be done in parallel, before
// the blocking wait on the linking result is triggered in finalize function
const shaders = WebglShader.getBatchShaders(device);
shaders.forEach(shader => shader.impl.link(device, shader));
shaders.length = 0;
}

/**
* Dispose the shader when the context has been lost.
*/
Expand Down Expand Up @@ -305,6 +278,8 @@ class WebglShader {
linkStartTime = now();
});

// check the link status of a shader - this is a blocking operation waiting for the shader
// to finish compiling and linking
const linkStatus = gl.getProgramParameter(glProgram, gl.LINK_STATUS);
if (!linkStatus) {

Expand Down
3 changes: 0 additions & 3 deletions src/scene/renderer/forward-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,9 +530,6 @@ class ForwardRenderer extends Renderer {
prevLightMask = lightMask;
}

// process the batch of shaders created here
device.endShaderBatch?.();

return _drawCallList;
}

Expand Down
3 changes: 0 additions & 3 deletions src/scene/renderer/shadow-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,6 @@ class ShadowRenderer {
const passFlags = 1 << SHADER_SHADOW;
const shadowPass = this.getShadowPass(light);

// TODO: Similarly to forward renderer, a shader creation part of this loop should be split into a separate loop,
// and endShaderBatch should be called at its end

// Render
const count = visibleCasters.length;
for (let i = 0; i < count; i++) {
Expand Down