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

Update to WebGL shader compilation and linking #4964

Merged
merged 3 commits into from Jan 16, 2023

Conversation

mvaligursky
Copy link
Contributor

@mvaligursky mvaligursky commented Jan 10, 2023

Fixes #3559

Situation before:

  • when a shader is created (which happens at a point the mesh using it needs to be rendered), it would internally compile both vertex and fragment shaders, and then it would immediate link them and wait for the result, blocking the main thread till the shaders are compiled.

Situation now:

  • The way forward renderer mesh drawing loop was refactored months ago is that we loop over the meshes in two passes. In the first loop, we just create shaders if those are missing. The second loop uses those shaders for rendering. With this PR, the shader creation was changed to only trigger their compilation. The shader linking takes place when a batch of shaders is created by forward renderer - basically after shaders for a layer are created (so one batch for shadows, one for forward pass for example). This only kicks off linking of all those new shaders, without waiting for the results, so they can link in parallel. Waiting on the result is done when the shader is set up for rendering.

What this delivers is conceptually this (2 meshes with 2 shaders):

Before:

shader1.vertex.compile
shader1.fragment.compile
shader1.link
shader1.finalize **(blocking)**
shader2.vertex.compile
shader2.fragment.compile
shader2.link
shader2.finalize **(blocking)**

Now:

shader1.vertex.compile
shader1.fragment.compile
shader2.vertex.compile
shader2.fragment.compile
shader1.link
shader2.link
shader1.finalize **(blocking)**
shader2.finalize **(blocking)**

Note that those loops execute per render layer / render pass, so shadows would do compile/link/finalize on shaders before main forward pass woud.

The actual log from multi-view engine example (the number is unique ID of the shader):
Screenshot 2023-01-10 at 17 32 34

In a larger project, I see a lot more shaders getting compiled before any linking, for example
Screenshot 2023-01-10 at 17 38 34

So in theory, this does the right thing, but in practise, on few projects I have tried, I cannot see a performance difference (using Chrome on both MacOS and Windows).

@mvaligursky mvaligursky marked this pull request as draft January 10, 2023 17:49
@mvaligursky mvaligursky marked this pull request as ready for review January 11, 2023 12:04
@mvaligursky
Copy link
Contributor Author

I'll follow this up with additional experiments and possibly PR to try and get shader link steps to run in parallel as well.

@mvaligursky mvaligursky self-assigned this Jan 11, 2023
@mvaligursky mvaligursky added performance Relating to load times or frame rate area: graphics Graphics related issue labels Jan 11, 2023
@Maksims
Copy link
Contributor

Maksims commented Jan 11, 2023

Could it be that when you call link it actually triggers compilation which is not blocking, but then checking link status is blocking. So if you call link for all awaiting shaders and only then check their statuses - it might do the trick.

@mvaligursky
Copy link
Contributor Author

Could it be that when you call link it actually triggers compilation which is not blocking, but then checking link status is blocking. So if you call link for all awaiting shaders and only then check their statuses - it might do the trick.

Yep that is exactly what I'm experimenting with now. Code is ready, but trying to add some reliable way to measure the impact.

@mvaligursky
Copy link
Contributor Author

mvaligursky commented Jan 13, 2023

I made link calls to execute in parallel, before waiting for them by calling

        const linkStatus = gl.getProgramParameter(glProgram, gl.LINK_STATUS);

but I still do not see any improvement.

@mvaligursky mvaligursky merged commit 08909c4 into main Jan 16, 2023
@mvaligursky mvaligursky deleted the mv-shader-compilation-linking branch January 16, 2023 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: graphics Graphics related issue performance Relating to load times or frame rate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Investigate parallel shader compilation
3 participants