Skip to content

WGSL 2020 09 01

François Daoust edited this page Dec 2, 2020 · 1 revision
Dean Jackson


Dan Sinclair


⌨️ Scribe
Google Meet




WGSL Issues


Open Issues
Marked Issues


Meeting Issues

Tentative Agenda

  • Should we discuss camelCase naming #1016 again?
  • Should we discuss std v wgsl?
  • 2020-08-18 Action item review:
    • DJ: Will look into validating grammar on CI.
    • MM: Updated proposal for #854
  • Elaborate conversions (#983)
  • Invariant qualifier (#893)
  • Move texture methods into an import? (#1018)
  • Are entryPoints namespaces per module or per stage per module? (#1023)
  • Should the spec mention location aliasing? (#956)
  • Disallow fragment atomic ops on texture storages (#728)
  • Support pack / unpack functions (#988)
  • Bit preserving floating point conversion expressions (#1035)
  • Separate linear sampler binding type? (#1034)
  • WGSL should use thread instead of invocation (#1031)

📋 Attendance

WIP, the list of all the people invited to the meeting. In bold, the people that have been seen in the meeting:

  • Apple
    • Dean Jackson
    • Fil Pizlo
    • Myles C. Maxfield
    • Robin Morisset
  • Google
    • Dan Sinclair
    • David Neto
    • Kai Ninomiya
    • Ryan Harrison
    • Sarah Mashayekhi
  • Intel
    • Yunchao He
    • Narifumi Iwamoto
  • Microsoft
    • Damyan Pepper
    • Rafael Cintron
    • Greg Roth
    • Michael Dougherty
    • Tex Riddell
  • Mozilla
    • Dzmitry Malyshau
    • Jeff Gilbert
  • Joshua Groves
  • Mehmet Oguz Derin
  • Timo de Kort
  • Lukasz Pasek
  • Tyler Larson
  • Pelle Johnsen
  • Matijs Toonen
  • Hamada Gasmallah
  • Dominic Cerisano

⚖️ Discussion

Should we discuss camelCase naming #1016 again?

DS: resolution was camelcase functions and snake_case for types and attributes

Should we discuss std v wgsl (#1018)?

  • DS: Doesn’t matter - named at import. We should refer to it as wgsl.
  • JG: Not convinced. I think we should use std.
  • DJ: Let’s discuss next week.

2020-08-18 Action item review:

  • DJ: Will look into validating grammar on CI.
  • MM: Updated proposal for #854
  • New Action: DJ to look at bikeshed cross referencing for WebGPU

Elaborate conversions (#983)

  • DN: MR rendered gist at and the MR changes:
    • Better wording for scalar conversions
    • Adds vector conversions, using type-constructor syntax.
    • Adds section 11.4.1 describing floating point conversions with:
      • TODOs/ISSUE for rounding cases to and from floating point, and overflow case converting to integer.
  • RM: Should start by getting non-controversial cases in. For edge cases, can you force Vulkan to pick a rounding mode?
  • DN: Extension out of ~1.5years where you can force rounding mode by EntryPoint. Not universally available. Don’t know if all modes are possible. Round to Even is common on GPU. Round to zero cheap on mobile. AI to investigate how prevalent.. FYI:
  • RM: How reasonable/costly would it be to specify we always round to zero if what’s GPUs do by default.
  • DN: Good question, I don’t know.
  • MM: Two parts to question, for devices that support the extension, we can use the extension. For the rest of the devices we have to do something. Putting those together, what does the landscape look like?
  • DN: One thing to keep in mind. Builtin functions may not be controllable. Can’t remember if that’s the case, but something to be concerned about.
  • DS: Accept this for now. TODOs for the ambiguous cases.
  • RM: Agree.

Bit preserving floating point conversion expressions (#1035)

  • DS: We currently have two ways to convert - cast and the type conversions above from David. Proposal is to delete cast and use only the type conversions and the bitcast. But don’t use the name bitcast.
  • type cast is i32(x) casts to an i32.
  • DS: Make that the only one. They look like constructors. Then there is ‘as’
  • MM: These are all expressions not statements?
  • DS: Yes.
  • DS: So then what do we call ‘as’ or ‘bitCast’?
  • DM: Why are you against ‘bitcast’?
  • DS: DN made a funny face at me.
  • DN: I’m fine with it.
  • agreement not to use reinterpret_cast
  • JG: bitcast is fine
  • DM: Editors can follow conventions.
  • Resolution: Delete ‘cast’ and rename ‘as’ to ‘bitCast’.

Invariant qualifier (#893)

  • MM: If i understand correctly, we’re trying to determine if this should be the default or not. I’d like to propose this not being default. Reasoning being no other shading language including GLSL have this as the default. Using this as prior art because those languages made the performance vs correctness trade off as worth it. If there is contention, we could write benchmarks to see what the performance fall off would be. If not contentious, follow other languages
  • DM: What was the behaviour of metal prior to 2.0
  • MM: Metal was if you wrote a line of code and the same line of code exists in two different functions and you called those functions with the same arguments. You’d expect the same line would make the same result. Prior to metal 2.0 this keyword didn’t exist so there was no guarantee that would produce the same result. THe line of code’s behaviour is dependent on the code around it. So the compiler could combine * and + to an FMA. The invariant qualifier tells the compiler to not do that. Don’t make the result of this expression dependent on the code around it. You have to opt into that behaviour. In effect, this disables all optimizations.
  • DM: Question, how do we do invariant on that Metal version?
  • MM: It would have to be an extension.
  • DM: Or, is this version not needed to be supported? Is metal 2 supporting the Metal 1 hardware?
  • MM: Don’t know the answer. If the answer is yes, this can be core. If the answer is no, it’s an extension. Answer doesn’t affect the feature itself.
  • DN: Or we make it a best effort thing giving portability with differences at the edges.
  • KN: As far as I understand there are no base capability versions between metal which is why no version numbers after 2. API updates, but hardware caps not part of the version number part of the platform.
  • MM: Metal 2.0 is a publicly visible name of a framework which is not representative of engineering concerns. Wouldn't read engineering conclusions into the version numbers of publicly visible frameworks.
  • KN: There are version numbers of MSL which makes sense as it doesn’t work the same asn an OBJ-C api, so versions make sense. But, we don’t know what MSL versions can be used with which OS’s.
  • MM: That’s easy for us to figure out. We can run a test program on a bunch of OSs. Happy to do that test.
  • DJ: Surprised that isn’t documented
  • KN: That’s very important information.
  • DJ: At worst we can work it out, at best documented
  • DN: Saw tables of features, but doesn’t have bearing on shading languages
  • DJ: I would say the minimum MSL version is tied to the OS version. It’s tied to the OS framework release.
  • DM: Not a decision I’m super attached too. Fine with invariant being optional. Historically not how webgpu decisions were made. If doughnuts between perf gains and portability we had to prove it. We would default to portable behaviour. Inconsistent we’re choosing performance over portability in this case.
  • MM: Understand. Question, should I do the performance gathering. Sounds like yes?
  • DM: Would be happy to do it when get time. Want group aware of history of API decision making
  • KN: Agree, but moot if we can’t have invariant in core.
  • DM: Yes, is that question still open or can we say we always use Metal 2?
  • KN: Need to figure out what our minimum metal shading language version is before we decide to do a bunch of work
  • JG: Off cuff, recommendation is to have in core and UAs would decide if they offer WebGPU on backends which don’t support it. Invariant is not something which is optional in a graphics API in 2020.
  • MM: Third option, have it in the language but have it not mean anything. A hint.
  • JG: Think it’s better to tell a lie that’s closer to the truth then to tell the truth which is confusing. The truth which is confusing is telling people invariant might do what you want but maybe not. The lie that’s closer is that invariant works and if it doesn’t it’s a bug. UA can decide if that want the buggy or non-buggy version vs supporting on a platform
  • KN: Found docs for languages on docs. Enum called metal language version and each member has OS availability attached to it.
  • GR: Troubled by phrasing there, what do you mean by buggy
  • JG: If invariant is not invariant on old versions of metal
  • DM: Wonder if we could compile shader without optimizations if we know the invariant wont work
  • DN: Comes down to what the driver does when it post - optimizes. I mentioned the 3rd option but wouldn’t be happy with it.
  • JG: Seems like natural choice is put it in core and as part of MVP exploration we find it is not implementable on hardware we care about we come back to the table before MVP is over
  • MM: Agree that’s a good place to start. Likely all versions of Mac and iOS that are relevant support the invariant keyword. Will take AI to make sure that’s true
  • DN: Hearing, add it to the core language. Write CTS tests to see if it’s in effect (if the FMAs are being generated for things that shouldn’t) and then we’ll have pass fail data.
  • MM: Yup.
  • DN: Want to be clear which expressions and how far back. Lots of things that are fuzzy that need to be nailed down.
  • MM: One other thing to discuss, should we, and if so who, will determine the perf loss.
  • DM: Would love to but overloaded.
  • MM: Me too …. How about we proceed with a plan of record and add to the queue of stuff and at some point we get the data … Don’t make the data blocking on adding.
  • DM: Sounds good..
  • DN: The primary use case is in computing position. Don’t know how often that is going to be a meaningful critical path. Benchmarking has to take that into account it’s the position computing path.
  • MM: Am i remembering correctly some APIs it only works when computing position. You can’t put it on anything else?
  • DN: Thought that was the claim for metal.
  • MM: Would have to see, don’t remember. More work to be done to figure out how this will work.
  • KN: I am hesitant to require Metal 2. That's macOS 10.13. Dropped 11, but not sure about dropping 12.
  • MM: Could also not offer WebGPU on 12.
  • JG: That would be ok.
  • KN: Looking for stats on mac version users, but couldn’t find them.
  • JG: Would suck, but limited for roll out for years. Nice to not make it too bad but in another year, won’t matter so much. Our products will all drop support eventually
  • KN: Eventually, we support 10.9 or something.
  • DM: Invariant is available from metal 2.1 and must be used with position.
  • KN: If 2.1 then requiring 10.14.
  • GR: Understanding in SPIR-V there is invariant and precise. Are there similar levels in metal? Was there a precise before 2.1
  • MM: Not that i know of
  • GR: No invariant in DXIL, there is precise.
  • JG: Did we link to the language metal uses for this?
  • MM: Will dig it up.
    • Table 5.3:
      • “Marks the output position such that if the sequence of operations used to compute the output position in multiple vertex shaders is identical, there is a high likelihood that the resulting output position computed by these vertex shaders are the same value. Requires users to pass -fpreserve-invariance. Please see description below for more information.”
    • “In previous versions of Metal, invariant was a best effort analysis to mark which operations need to be invariant and may fail in certain cases. This is replaced with a conservative invariant model where the compiler marks operations that doesn’t go into an invariant calculation. This will guarantee anything that is invariant calculation remains invariant. This option may reduce performance as it may prevent certain optimizations to preserve invariance.”
  • DC: Question, have extreme exposure to various GPUs and we’re looking for a precision guarantee front he workers depending on the hardware they’re on. Exposed to lots of hardware. Seems like there might be a way to specify through WGSL or WebGPU API to say you have to have this level of precision. TO be able to query the GPU and look at the precision and reject jobs based on the response. Looking for a way to guarantee a minimum or exact level of precision we get consistent results regardless of hardware and hardware which can’t mean gets rejected. If WebGPU doesn’t provide we’ll make tests that send a render to determine if the expected answer is returned and we can use the compute unit. Otherwise can’t guarantee consistent rendering or ML. These issues add up in distributed systems. So, is there a way for core to provide a minimum precision guarantee and report back the hardware does not provide.
  • DN: Few factors. Invariant is about permutation and re-arranging of arth. Guarantee provided by API to make sure hta t2 or multiple instances of expression will be consistent with itself. Nothing across implementations which guarantees that. Second issue, haven’t discussed error bounds on math functions. Some API’s give stricter bounds on Sin for example. Have not got there, but suspect we’ll get to a precise statement modulo rounding. The error bounds and other things are yet to be discussed would like a consistent set of bounds over all WebGpu but will be worst cse. That work is yet to be done. Hear you that you want a known state before able to run.
  • DC: We could just send test computations to determine. A sufficiently complex computation we compare against a known answer. Would be nice if core provided a way to query the minimum precision.
  • DN: Hans Bohem presented at PLDI “towards an API for the real numbers” how infinite precision approximations have (missed) quality. To test accuracy of java library. Gives x number of ULPs. All code in java but open source. Would be nice if we could have precise statements about underlying ops. So we have known correct error bounds on math functions and run tests to see what we get on target implementations and put in the spec
  • KN: Would like to see that for blending and sampling and things. Super precise this man ULPs of precision.
  • KN: Did more Metal digging, Invariant does not appear until MSL 2.2. Says it became available in Metal 2.1 (but Metal no longer has version numbers). MSL 2.2 is not available until macOS 10.15 or iOS 13. That’s pushing it a lot.
  • MM: Sounds like an extension.
  • JG: It’s implausible to draw certain scenes correctly without invariance. So, metal saying it doesn’t have it before 2.1 says to me it was either always done or they had a different name for it.
  • MM: Neither of those is correct. You get buggy results. That’s why we added the keyword.
  • KN: Invariance is not assumed for a long time. OpenGL ES got to 3.0 before they added it. OpenGL went quite a long time without invariant.
  • JG: ES2 had it I believe.
  • MM: Don’t think more discussion will effect the outcome. Have our homework.
  • KN: You’re right Jeff.

Should the spec mention location aliasing? (#956)

  • DN: Seems to have gone in different directions from resource and location bindings. In resource you want uniqueness in the tree of code for an entry point. For locations I think we can adopt the same rule. Satisfies what JohnK said about desktop GL has done. Can have variables with overlapping locations as long as they are used in different shaders.
  • DM: Sounds fine.
  • DN: Want to resolve this as I’m going to write about the shader interface.
  • MM: Sounds fine.
  • DJ: Agreement!

Separate linear sampler binding type? (#1034)

  • DM: Sampling with linear addressing mode of integer texture is something that was forbidden in opengl but open gl didn’t have separate samplers and textures. Failing to find concrete information on native api outcomes. Is it defined, is it a crash. Does the universe end? Remember it caused problems on D3D11 AMD. Don’t know situation today. If it isn’t strictly defined, need a good way to validate this never happens. Proposal add a sampler type in WGSL and binding type in WebGPU that fits the ones with linear addressing modes only.If you have a linear address ode you must have this sampler type as it can’t be used with integer textures. Three sides. Does anyone know how to find this info on native APIs? Difficult to find as could be over multiple docs
  • DN: Would be Vulkan attribute. Will look up. All sampling state is API side, not SPIR_V. Parameter on image type. Signed int, unsigned int or floating.
  • JG: And you just promise they match?
    DN: I think the API would introspect and do the right thing if there are restrictions.
  • JG: In OpenGL it’s undefined.
  • KN: For attaching a texture object to texture bind point could check. Not necessarily for combining samplers with textures. If a sampler state object has filtering and you use it with an integer typed texture the shader doesn’t know. Doesn’t know hte sampler until it’s been bound. Not validated in vulkan as it would be draw time validation.
  • JG: In OpenGL if you get it wrong it’s Undefined Values.
  • DM: Metal has the filter capability in the features tables. Says filter is not there for integertypes. Doesn’t say what happens if you try to use it. Assume it’s undefined but not sure. That was the first part. Other one is conserving theAPI change to add a new sampler type with regular and comparison sampler. Having separate type seems only way to validate early.
  • JG: One thing we discussed is having a nearest sampler type with understanding most samplers people want to use with filtering and only certain formats like ints where you can’t do this and you’d want to opt in to a sampler type that only supports nearest and doesn’t support linear filtering
  • KN: First glance, adding binding and shader type are good ideas. Worry it’s going to cause headaches for adopters.
  • DM: Hopefully only people who use integer textures.
  • MM: Why add a new type in shading language. Compiler knows what it's used with.
  • DM: Doesn’t know state of sampler, just knows there is a sampler
  • MM: Can know if it’s being used with which texture. You can’t copy samplers or textures so compiler knows what is used with what. So don’t think you get anything by adding a new type as compiler already knows,.
  • DM: If the compiler knows, but sampler doesn’t know sampler contents. Gets association and passes to API and API can only validate at draw time when exactly bound.
  • JG: Example is if you compile a shader you know …
  • KN: Can look at each sampler binding point and determine if used by non-filterable format (any integer formats) and if it was you require the binding type to be nearest samplers. Otherwise can be either one.
  • MM: Not saying to not have it as part of the bind group layout, just not a new type in the shading language.
  • KN: In principle i agree but there are open questions if there are things other then integers which can’t be filtered. Like 32 bit float types. Can’t check that in shader compilation so separate topic.
  • DM: Third thing, class of undefined result problem. Not as severe as sampling behaviour as UB. R32s on iOS is one of those formats. Also depth sampling may not produce proper linear sampling result. Separate discussion. Myles says you’ don’t need separate type because we know what it will be from the outside.
  • KN: Combination of samplers and textures in shaders has to be static.
  • DM: Seems like we could make the WGSL grammar stronger if we had that separation and wouldn’t limit anything that’s possible with current API.
  • MM: Understand argument from perspective of expert but someone who isn’t a WGSL expert, keeping the set of types down is a good thing to do.
  • KN: Having the error at shader compilation isn’t that much more useful then at bind group compatibility tme.
  • DM: Could have a shader that is wrong which you never use but it’s allowed. Shader could be using sampler with both float and int textures and you can’t validate it at the shader creation time.
  • KN: At bind group layout compatibility time would check sampler is non-filitering
  • DM: Only if code is statically reachable from entry point you’re compiling
  • KN: That seems ok to me. Don’t want to validate code that’s been pre-processed out either. Kinda the same. Other concern is SPIR-V to this if we added another binding type as you’d have to go through the spirv module to find static usage before creating the type
  • GR: Have we defined what is statically reachable and what isn’t? Some cases it’s ambiguous
  • DN: Any mention in any function which is itself statically reachable. Textually look at function calls. Don’t worry about constants or branches follow all branches.
  • MM: So even if(false) it’s still part
  • DN: Yes.
  • GR: if (false) is a good example which seems silly but can save a lot of headache
  • MM: Needed for web specs, having this be the simple thing is more important here.
  • KN: We rely on this a lot for figuring out what bindings are used and what locations are used. Necessary to do this extracting a function point and all the stuff it uses for more then this.

Are entryPoints namespaces per module or per stage per module? (#1023)

Disallow fragment atomic ops on texture storages (#728)

Support pack / unpack functions (#988)

WGSL should use thread instead of invocation (#1031)

Clone this wiki locally