Revision R1: 2018-01-01
Revision R2: 2018-01-03
WebGPU should directly ingest SPIR-V, and it should not ingest a human-writable shading language. [R2] The WebGPU group should bless HLSL and fully maintain a complete development path to enable development with HLSL.
SPIR-V is a smaller and simpler implementation and verification target than any human-writable shading language.
During the development of WebGL, hundreds of bugs and edge cases have been encountered which are exclusive to the ingestion of a human-writable shading language. Note that these can not be dismissed as simply bugs in the browser's shader translator; these types of bugs are inherent to ingesting a text-based language. Ingesting SPIR-V categorically eliminates bugs in these areas (example bugs provided):
This bug list, curated from the ANGLE and Chromium repositories, illustrates the classes of bugs that have been encountered during the development of the WebGL shading language specification, and which would be categorically eliminated by ingesting only the SPIR-V binary format.
Ingesting SPIR-V does add a few new concepts:
The benefits of ingesting a less complex verification target are significant:
SPIR-V is tightly specified. The complexity of the format is much lower than GLSL/HLSL, so its prose specification is able to be more precise. Lower complexity also leaves fewer holes for underspecification or self-contradiction.
Since SPIR-V is less complex, a conformance test suite of the same "size" should intuitively be able to cover more cases and thus more effectively complement the prose spec. (We don't have data to go with this, since it's very hard to compare the size and coverage of SPIR-V in the Vulkan CTS with the size and coverage of GLSL in the OpenGL CTS.)
If we need to add a feature to SPIR-V, it can be done so as an Extension to SPIR-V. The WebGPU group can effectively own these Extensions.
There are ~four categories of engine development:
| Options if browser ingests HLSL | Options if browser ingests SPIR-V |
| 1. Online cross-compile GLSL to HLSL with a third-party library. (shaderc+SPIRV-Cross?) | 1. Online cross-compile GLSL to SPIR-V with a third-party library. (shaderc) |
| 2. Maintain, in parallel with GLSL code, a separate library of HLSL and an HLSL-text-snipping engine. | 2. Maintain a separate library of some SL, and offline compile it to SPIR-V (shaderc or DXC). Do online linking and specialization with a JS library. |
| 3. An HLSL library and HLSL-text-snipping engine (as above), plus online-compile HLSL to GLSL (if maintaining WebGL as a "slower fallback path") with a third-party library. | 3. An SL library compiled SPIR-V (as above), plus online-compile SPIR-V to GLSL (if maintaining WebGL as a "slower fallback path"). (Aside: offline compilation from SPIR-V to GLSL may even be possible, with a simple JS implementation of linking and specialization for GLSL.) |
Obviously, application developers will not normally write SPIR-V by hand. Instead, they will compile to SPIR-V (either online or offline) from a human-writable shading language. The WebGPU working group should bless a single such language, HLSL, and take responsibility for the HLSL development path.
For developers with existing content in GLSL, we should also ensure the ecosystem includes a well-supported GLSL path (for example via shaderc).
One thing we didn't really discuss above: we also think that the WebGPU group should bless HLSL and fully maintain a complete development path to enable development with HLSL. We will revise the document to express this more clearly.
Revision posted. Changes marked with [R2].
Today I saw a warning on the OpenGL wiki:
Warning: Implementations sometimes get the std140 layout wrong for vec3 components. You are advised to manually pad your structures/arrays out and avoid using vec3 at all.
which made me think of another way in which SPIR-V is more simply specified: SPIR-V has no such concept as memory layout algorithms (std140/std430) - the offsets are explicitly specified for every member (OpMemberDecorate _ _ Offset _, etc.) The overlap rules are validatable offline (and are no more complex than the layout(offset=x) overlap rules in GLSL).
I think SPIR-V is the only formally specified binary shader language.
HLSL does not have a thorough and formal specification.
You will be open to less bugs and issues, especially security bugs when using a binary intermediate representation for which there are multiple compilers available including cross-compilers.
You need an ~AST~ CFG anyway to reason about a shader's security, frankly I think it would be far easier to transform a SPIR-V shader's ~AST~ CFG to prevent out-of-bounds reads and writes for robustness.
HLSL to SPIR-V compilation is currently badly broken ( by ShaderConductor, SPIRV-Cross does a better job), ask any graphics developer who's looked into it.
The WebGPU working group is expected to own specification, conformance, and development of HLSL or an evolution thereof.
Lawsuits anyone?
Not ingesting SPIR-V by default will make the web slower, one of the most painful parts of video-game development is the shader compilation
We actually have to kickoff compilation in multiple threads and how the CPU for a number of seconds to get all of the shaders in the scene to compile and optimize.
Some platforms (Mali) didn't use to do optimization to save on load times and power-usage, that ended up with sub-optimal framerates and mobile developers such as Aras P. had to write their own optimizers to make sure that the shipped shaders actually received optimization on mobile!
Most helpful comment
Not ingesting SPIR-V by default will make the web slower, one of the most painful parts of video-game development is the shader compilation
We actually have to kickoff compilation in multiple threads and how the CPU for a number of seconds to get all of the shaders in the scene to compile and optimize.
Some platforms (Mali) didn't use to do optimization to save on load times and power-usage, that ended up with sub-optimal framerates and mobile developers such as Aras P. had to write their own optimizers to make sure that the shipped shaders actually received optimization on mobile!