/webgl-parallel_shader_compile

Testing of KHR_parallel_shader_compile extension for WebGL

Primary LanguageHTMLMIT LicenseMIT

webgl-parallel_shader_compile

A simple WebGL application, to test the performance and behaviour of KHR_parallel_shader_compile across platforms and browsers.

Live Example

https://htmlpreview.github.io/?https://github.com/mvaligursky/webgl-parallel_shader_compile/blob/main/index.html Open a development javascript console and observe the logs with timings.

Screenshot 2023-01-25 at 10 54 57

The program creates a WebGL 2 instance, and renders a simple spinning triangle, which allows us to see the rendering being blocked.

On top of the web page, there are buttons to compile 10 or 50 instances of a shader. A large shader was generated by PlayCanvas Engine, which implements PBR / clustered lighting / area lights. There is a random number added in the source code of the fragment shader to avoid possibility of some caching behind the scenes.

Overall implementation

  1. prepare fragment and vertex shader source code for all shaders
  2. [COMPILE STEP] trigger compile step on all vertex and fragment shaders
  3. [LINK STEP] create programs, linking vertex and fragment shades, and trigger link step on all programs
  4. inside requestAnimationFrame which executes each frame, for each shader which has not been fully processed yet:
  • [COMPLETION STEP] test COMPLETION_STATUS_KHR using the extension. This should be a non-blocking call, and return true if the shader is done linking.
  • [LINK STATUS STEP] get shaders LINK_STATUS if [COMPLETION STEP] has returned true - this is a blocking call if the shader has not been done linking yet.

Expectation

  • on platforms that implement the mentioned extension, the triangle rotates smootly with no blocking during the shader compilation.

Test Results

None of the tested browser / OS combination delivered smooth triangle rotation while the compilation takes place.

Chrome MacOS 13.1

  • compilation, linking, COMPLETION_STATUS_KHR and LINK_STATUS are fast, the extension is working well.
  • on multiple occasions, requestAnimationFrame is not being called for 1s or more, and so the bottleneck seems to have just moved to be inside the browser, instead of [LINK STATUS STEP]. It seems all shareds are completed during the same frame. The result is that the triangle still does not smoothly rotate at all.

Safari MacOS 13.1 (Metal backend)

  • compilation is instant, all the time is taken by [LINK STEP] during which all the works seems to take place. [COMPLETION STEP] and [LINK STATUS STEP] are instant, as shader has already been fully processed. So there does not seem to be any advantage in using the extension here.

Firefox MacOS 13.1

  • extension is not implemented, all time is taken by [LINK STATUS STEP]

Chrome Windows 10

  • 10 shaders seem to get processed nicely, almost as if extension worked perfectly (some DTs are slightly longer). When compiling 50 shaders, similarly to MacOS, we get multiple 1s or longer intervals when requestAnimationFrame is not called.

Firefox Windows 10

  • extension is not implemented, all time is taken by [LINK STATUS STEP]

Separate note

  • the PBR/clustered/area lights shader has a compilation time on Windows considerably longer than on MacOS.

Created browser issues:

References

[1] - Basic WebGl spinning triangle application is based on https://www.tutorialspoint.com/webgl/webgl_rotation.htm