WHLSL: Web High Level Shading Language
webkit.org
webkit.org
> Last year, Apple established the WebGPU Community Group inside the W3C to standardize a new 3D graphics API which provides the benefits of these native APIs, but is also suitable for the Web environment. <...> All of the major browser vendors are participating and contributing to the standardization effort.
The browser vendors negotiated and agreed to proceed with W3C group (as opposed to Khronos/WebGLNext). It's a collaborative effort from day one (where all of Google, Mozilla, and Apple had prototypes), not exactly Apple-led like the article attempts to present it.
> Forking the SPIR-V language means developers would have to recompile their shaders, possibly being forced to rewrite their source code anyway.
This (and the whole section about SPIR-V) reads like FUD to me.
> Weirdly, this would mean on those two platforms, the starting point and the ending point are both human readable, but the bit in between is obfuscated with no benefit.
Inaccurate. The end point is always GPU machine code, and on the way there all the APIs introduced their own intermediate binary formats (SPIR-V, DXBC, DXIL, AIR). It's just that not all of them are clearly specified. We should be able to convert SPIR-V to DXBC/DXIL without going through HLSL, and the AIR limitations are up to Apple to unblock.
It's really not. These are legit arguments:
- SPIR-V does not yet have a documented security story that is suitable for the web. Maybe it could have one eventually, but this does not exist right now.
- There is not yet a story for what web-SPIR-V would do about all those optional capabilities and other issues of SPIR-V that are a bad fit for the web. That includes, for example, SPIR-V's underspecification of most operations to allow for UB-style optimizations.
- It's easier to write a code generator that targets a text-based language than a binary one. If I want to write a JS program, or even an offline program, that emits shader code that a browser can run, then: (A) to emit WHLSL all I would need is strings and appending; (B) to emit SPIR-V, realistically I would need some SPIR-V library. Sure there are many SPIR-V libraries, but string appending is easier every time.
It's not FUD. It's just arguments that you don't agree with.
> Inaccurate. The end point is always GPU machine code, and on the way there all the APIs introduced their own intermediate binary formats (SPIR-V, DXBC, DXIL, AIR). It's just that not all of them are clearly specified. We should be able to convert SPIR-V to DXBC/DXIL without going through HLSL, and the AIR limitations are up to Apple to unblock.
Binary formats that are underspecified. What a shocker. Maybe it's because text-based languages are easier to clearly specify.
Creating a clear specification of a text-based language is easier for lots of reasons. Probably the biggest is that the specification has an easy way of citing code examples. Binary specs always have a hard time with that. No question in my mind that trying to glean the C/JS/Java syntaxes from those specs is easier than trying to do the same for x86/arm/wasm/spir-v "syntax".
Let's take the biggest offender (that I quoted):
> developers would have to recompile their shaders, possibly being forced to rewrite their source code anyway
Those are likely to hit WHLSL harder than SPIR-V, given that WHLSL is attempting to be a whole new specification of the format and execution model, while SPIR-V is only missing the execution model for the Web. The compatibility story of WHLSL (towards HLSL) is still to be figured out, yet the blog focuses on the issue only in the context of SPIR-V (compatibility of existing SPIR-V versus WebSPIR-V)...
I agree there is work to be done for SPIR-V to be adopted on the Web. From the last call, I thought there is also work to be done on WHLSL. This blog post tries to show it as the latter is ready, and SPIR-V is likely to fail, hence I called it FUD.
> It's easier to write a code generator that targets a text-based language than a binary one.
It's easier to s/one/two/, but if you are doing anything more complex, you'd still build a logical representation in memory that is non-textual (hello, AST). From there, emitting binary output isn't more complex. Needless to say, there is already a large ecosystem around SPIR-V, which can be targeted from other SLs like HLSL and GLSL, and even output directly from Rust.
> Binary formats that are underspecified. What a shocker. Maybe it's because text-based languages are easier to clearly specify.
Is HLSL specified? Is MSL? They are documented, but not strictly specified. I only see an actual specification for SPIR-V (among the current-gen graphics shading languages), which is binary. So I don't buy the argument that text-based languages are easier to specify. Let's take a floating point number for example. In binary, you'd just say here come 32bits denoting IEEE 754 float (basically, piggy back on the existing spec). In text you need to say what symbols are accepted (exponent form, dot-based form, sign, how many digits are allowed, etc), which doesn't appear simpler to me.
> Probably the biggest is that the specification has an easy way of citing code examples.
Examples are not required to specify a format, they are basically documentation. In that sense, I agree with you - text formats are easier to document.
The in-memory representation in any interesting compiler for some source language that is neither HLSL nor SPIR-V is unlikely to be either HLSL or SPIR-V. It’s going to be something that requires some effort to convert to whatever shader format the browser injests.
I’m saying that it’s easier to write a converter to text because you don’t need any special tooling to get started.
> In binary, you'd just say here come 32bits denoting IEEE 754 float (basically, piggy back on the existing spec). In text you need to say what symbols are accepted (exponent form, dot-based form, sign, how many digits are allowed, etc), which doesn't appear simpler to me.
Programs are about a lot more than floating point literals. The parts that cause friction are control flow structure, variable scoping rules, etc. WHLSL goes with conservative choices that are easy to describe to anyone familiar with C. This makes it easy to understand both for folks who just want to use the thing without other tooling and for folks who want to build tooling.
If it was the case that the dominant part (in terms of execution time, memory, security, or any other metric) of a shader compiler was parsing the text then it would be interesting to look at binary as an alternative. I just don’t think that’s the case:
- most of the time and memory footprint of compilation is the backend so binary input is not better.
- binary parsers have no security advantages. I would guess that they tend to have more bugs because they tend to have to use integers in the input as indices in lookup tables.
- I haven’t seen data to suggest that binary parsers are less complicated, though I’ve heard folks express that as a feeling. For sure, parsing of full C is harder than parsing most other formats regardless of whether they are text or binary. But WHLSL is not full C. I don’t think it’s any harder to parse than SPIR-V.
Unfortunately it seems many developers have interpreted the blog post to mean that WHLSL has been selected as the ingestion format, which is incorrect.
Let programmers work with whatever high-level language they prefer, and compile it down to a consistent, compact assembly representation to transmit it over the network.
WHLSL is a great compilation target so it doesn’t prevent you from using whatever language you like.
Also the page they link to is not just measuring parse time but also compilation time.
sorry wat ? https://trends.google.com/trends/explore?q=glsl,hlsl
GLSL is used for multimedia apps, user interfaces (Qt at least uses it quite a bit), 3D authoring apps. ISF (Interactive Shader Format https://www.interactiveshaderformat.com/spec), fairly used in all the software chain around audio-visual installations, is based on GLSL. It's used on android, on embedded devices, etc etc...
> GLSL is the language used by WebGL, and was adopted by WebGL for the web platform. However, reaching cross-browser interoperability was extremely difficult due to incompatibilities in GLSL compilers. There remains a long tail of security and portability bugs with GLSL still being investigated
and how will implementing a whole new set of compilers for WHLSL solve this ?
> And since Windows and macOS/iOS don’t support Vulkan,
now this is just FUD. you can entirely write vulkan code and have it run on windows and apple platforms.
> the incoming SPIR-V would still need to be translated/compiled into another language
yes, that's the freakin point of SPIR-V
Also...
> In Metal Shading Language, you could, for example, write a shader that casts a pointer to an integer, adds 17, casts it back to a pointer, and dereferences it. This is a security problem because it means the shader could access any resource that happens to be in the address space of the application, which is contrary to the Web’s security model. Theoretically, it could be possible to specify a dialect of Metal Shading Language that doesn’t have raw pointers, but pointers are so fundamental to the C and C++ languages that the result would be completely unfamiliar. C++ also heavily relies on undefined behavior, so any effort to fully specify each of C++’s numerous features would be unlikely to be successful.
followed by
> The first is the safe pointer. Some form of reference semantics, which is the behavior pointers allow for, are used in almost every CPU-side programming language. Including pointers in WHLSL will make it easier for developers to migrate existing CPU-side code to the GPU
so instead of reusing an existing thing and just add one tiny dot of safety semantics on top of it, well no let's just NIH and reimplement a whole new language. Seriously, they don't want to use a "safe metal" because "pointers are so fundamental to the C and C++ languages that the result would be completely unfamiliar".
So instead, they write a freakin new language - why the hell do they use the familiarity argument then ?
Google and Samsung are developing HLSL compiler for Vulkan, because a large majority of game studios don't want to bother with Vulkan on Android if they cannot port their shaders.
There are plenty of HLSL compiler status talks at the Khronos web site and YouTube channel.
> > And since Windows and macOS/iOS don’t support Vulkan,
> now this is just FUD. you can entirely write vulkan code and have it run on windows and apple platforms.
On the contrary, this is quite true.
Apple does not support Vulkan, you need VulkanMK, which is basically a Vulkan portability layer making use of Metal API, and only supports the subset common to both APIs.
Microsoft does not allow OpenGL ICDs on UWP/Store Apps, which is the mechanism used by Vulkan drivers on Windows, thus it is not possible to run either OpenGL or Vulkan code on UWP and Store apps.
Which is why Microsoft ported Angle for UWP, however they haven't bothered with similar support for Vulkan.
It's worth noting that MoltenVK supports a very large, useful subset of Vulkan which has been used in production in widely played games like DOTA 2.
It's not some toy project, Vulkan on Mac is very real.
I'm not against new standards, but I'd rather stick with something already adopted. Vulkan seems better than metal (proprietary). And I really don't have enough experience with HLSL and GLSL but they seemed fine both.
I'm also quite sure there will be translation tools to translate WHLSL to HLSL, GLSL and MetalSL (probably going through SPIRV as IR, see for instance https://github.com/KhronosGroup/SPIRV-Cross)
> sorry wat ? https://trends.google.com/trends/explore?q=glsl,hlsl
Pretty much all "big" game engines use HLSL (or their own custom variant of HLSL) for shader authoring and cross-compile to platform-specific shader languages.
The problem with GLSL is that there are many versions that are completely incompatible to each other for no apparent reason. The GLSL used in WebGL is incompatible with the GLSL used for desktop GL, it's even incompatible with WebGL2. GLSL for OpenGL 2 is incompatible with the GLSL for OpenGL 3. There are different versions of HLSL too, but the compatibility between different versions of D3D and HLSL is better.
Apart from that GLSL and HLSL are similar enough in spirit that using one or the other as a blueprint for a new language doesn't really matter.
> And since Windows ... don’t support Vulkan
Vulkan is not supported by Microsoft, it's only supported on Win32 (not UWP) through 3rd party drivers. Having a browser API rely on 3rd party drivers is a bad idea (same with OpenGL on Windows, and that's the reason why WebGL implementations on Windows run on top of D3D).
If you ask me, W3C should create a single low-level standard for how to interact with graphics hardware from the web, and leave it up to 3rd parties to solve the problem of how developers should interface with it.
That said the binary formats usually have more features, and if you invent a byte code it's not hard to assemble/disassemble or allow delivering it in text form.
What I find unfortunate is that GLSL should be usable here, but every OpenGL variant really does have an wildly incompatible GLSL for no reason.
WebAssembly has been widely supported for a while now. So the fact that it isn't catching on should tell you something about how great binary formats are.
Text formats are more natural in every way:
- They are more natural to specify.
- They are more natural to codegen. It's easier to write a tool that emits a text format (just use printf) than to emit a binary format (usually need some library).
- They are more natural to parse. Parsing text is super clearly understood, and there are off-the-shelf tools to do it. In particular, WHLSL is designed to have a simple-enough grammar that you can use an off-the-shelf parser generator like antlr.
- They are easier to introspect. View Source is important on the web.
what makes you say that ? unity uses WASM, Qt uses wasm, Rust uses wasm, autocad uses WASM, SDL uses WASM... or do you expect every JS code to convert to WASM overnight too ?
I could argue that this also has a lot to do with inertia: the relative effort of implementing a web application in WASM is not comparable to using Javascript. It's not clear to me that things would be in the same state if there were also decades of work on tooling and libraries for WASM.
> They are easier to introspect. View Source is important on the web.
In theory yes, but is this really the case in practice? How often can you view source on a modern website and meaningfully understand the javascript? More likely it has been minified and uglified. Besides, it's possible to provide a source-map with binary formats to make source available if the author chooses to do so.
As to your other points, it is true that high-level languages are nicer to work with from a developer perspective, but the question is whether the fundamental web interfaces should be optimized for developer experience. I would argue that since web is the most prevalent way that people use software on the planet, web technologies should be optimized for performance and flexibility over developer experience.
The advantage of a low-level interface is that it's not opinionated. It's just a thin abstraction layer on top of what the hardware can do, it's not making assumptions about what use-cases should be optimized over what others. The situation with Javascript in that regard is insane: each browser vendor is constantly optimizing their JIT compilers in response to how people use Javascript most often. So the ones writing the code, and the ones optimizing the code are two disconnected groups, each with moving targets. A low level interface lets the end software developer have a consistent baseline to optimize against.
Also you don't lose any of the advantages you mentioned with a low-level binary interface. Inevitably there would quickly be tools released to compile HLSL or GLSL down to WSPIRV or whatever the low-level format would be. So if you want to work with a high-level language instead of WSPIRV, you could easily choose another high-level shader language as your target. However you do lose the advantages of a low-level language if you start with a high-level one.
It's easy to build nice tooling on top of a low-level interface. But if you require every application to have a nice-tooling-layer as part of its stack, you're essentially incurring a performance penalty on all software whether the application requires it or not.
Are you saying that WHLSL will be compatible with HLSL? The quote above seems to imply it's merely "inspired by" it, in which case GLSL's compatibility issues aren't a valid counterpoint.