Skip to content

WGSL 2020 05 19

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

:

Chair
Mehmet Oguz Derin

:𐰆𐰍𐰔 :

⌨️ Scribe
Google Meet

:

Location
https://webgpu.dev/wgsl

:

Specification
WGSL Issues

:

Open Issues
Marked Issues

:

Meeting Issues

Tentative Agenda


📋 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
  • Lukasz Pasek
  • Pelle Johnsen
  • Matijs Toonen

📐 Meta

  • Two ways to get things in meeting ‘For meeting’ or ‘MVP’ with a lot of disagreement.

⚖️ Discussion

"zero"/null of storable types, rework initializers (#764)

  • DN: Posted MR, turned out storable types were same as zero-able types. Mushed changed together which made it larger. MM suggested calling it ‘zero’ which is fine
  • MM: Content of patch seemed fine
  • RM: Fine with it too.
  • MM: Should we call it zero or null? Is the argument that none of the types are pointers so null doesn’t make sense. In the PR 3 out of 4 uses is 0, not null, so should call it zero
  • DN: The convention is memset which is zero
  • JG: Does anyone object to zero instead of null? Let’s make it zero.
  • DN: Ok. Will update PR.

Explicit layout needs more than Offset: ArrayStride and matrix attributes (#773)

  • DN: A necessary step so that any buffer data written by host and read by device must be explicitly laid out. Already discussed Offset for structure members, ArrayStride is needed for arrays. GLSL and OpenGL have STD140 and STD430 which have different array stride requirements. STD140 is array stride multiples of 16. Been an issue for folks in real life so explicitness is needed
  • MM: Willing to lump in with explicit byte offsets in structs. Seems same, either programmer tells computer or computer tells user. Byte offsets in structs is blocked on investigation of if there is one right answer
  • DN: Policy vs mechanism question. The rules that determine the constraints are policy. How those rules are stated is mechanism. The offsets are the mechanism
  • JG: So, regardless of what we find, if we have 140 or 430, this is our way of saying it
  • DN: When porting DX, more and more rules expanding the policy but the mechanism stayed the same.
  • MM: If there is one right answer we don’t need a policy or mechanism
  • JG: Strong desire from me to force people to show they understand the offsets. Expanding those to stride is more of that. If people read and obeyd the spec we wouldn’t have this issue. To make sure everyone knows what is going on having the user say explicitly what they want means they have to understand.
  • MM: There are other ways of surfacing that information. We should do the investigation before doing the argument
  • JG: We’re saying their orthogonal
  • DN: Could write out layout rule history, can do that homework to show how it evolved.
  • MM: That’s not the investigation being referred to. Is there a layout for every struct in WGSL where all 3 APIS (MSL, HLSL and SPIR-V) accept so they wouldn’t need to do byte array buffer stuff.
  • JG: Think that’s separate. Some degree of consensus earlier so folks explicitly state what they’re doing as there is no other way to get that right.
  • MM: Had this argument before. A lot of GLSL , MSL and HLSL code out there that works great without explicit byte offsets
  • DN: There was lots of inconsistency seen in drivers.
  • JG: Spent a lot of time helping folks in other orgs getting their offsets right. Just because folks made it work doesn’t mean it’s a good API.
  • MM: Another way of solving would be tooling. Think we should do the investigation first, if there is a lot of flexibility and authors can put what they want then all for it.
  • JG: THere is almost no flexibility. Thought we were further along in this discussion.
  • MM: Not my recollection
  • JG: Can talk about that now, don’t think investigation is relevant. Sounds like you want “Is there one true format where we can say this is always true and given it’s always true folks internalize by using the API. So, we don't need offset annotations as they’re implied”
  • MM: Or if all APIs are flexibility enough for byte offsets
  • JG: We know they aren’t
  • MM: Do we know that?
  • JG: Pretty sure this is true
  • DN: For example, vulkan has 3 different rules with more relaxed ness over time.
  • MM: Can i make up my own rule instead of saying this is STD140 can I say this is at offset 4 and this is at offset 104
  • JG: As long as you can inject padding
  • DN: As long as it fits the padding, can’t put vec4 at byteoffset 3 as it breaks scalar component alignment. Some of the weirdness is a vec4 at offset8, does that span a 16 byte boundary? Sometimes there are rules around that. You can make more strict constraints but not more lenient
  • MM: One way forward, codify all the rules around things like ints on 4 byte boundaries. Let authors put any numbers in their shaders as long as they conform to those rules nad the browser injects padding
  • JG: We have to pick STD140 to fit all bindings, but STD140 sucks so folks want to use STD430 where they can, but that’s not everywhere. So, talking before having STD140 for uniform buffer and 430 for storage buffers. But using one struct for both means they have different alignments and offsets. One solution is to force folks to annotate the offsets so they know where they are and it works or we’re teaching them.
  • DJ: #561 in March group agreed to have offsets for all struct members.
  • MM: Group agreed to do that but there was still an investigation
  • JG: Still an investigation to determine our actual requirements but this is a difference between policy and mechanism. Since we agreed for Offsets this provides array strides
  • DM: Do we know what platforms allow std430 on uniform buffers?
    DN: Not a requirement in vulkan so not tested. There is an extension for std430 in uniform buffers but don’t know which devices support that extension
  • KN: In OpenGL ES4.2 wasn’t able to use 430 with uniform buffers so no mobile hardware support at this point.
  • JG: Can do the investigation if it helps, just pushing back as we don’t see it as necessary.
  • MM: If we have byte offsets for structs then having stride offerts for arrays is fine. Since we have a resolution for structs then having it for arrays makes sense. Difference between having byte offsets where the programmer has to do paperwork and the programmer is telling the computer useful information
  • KN: There is a distinction on github, std140 and std430 are different between OpenGL and Vulkan. OpenGL gives a precise layout, in Vulkan they provide a set of rules. Pretty confident when we decided on explicit offsets we went with the latter. There is no single set of valid offsets we would allow padding and we'd insert fields in backends where necessary. So, not just paperwork, they have value.
  • MM: Figuring out those rules is what that investigation is. Would like to see the rules.
  • DN: For the SPIR-V env spec, there is a section cloned from the vulkan spec which has a bunch of rules. Can elaborate on that and copy in. For example. If UBO requires an array of floats having a stride of 16, you can use a stride of 32 and that’s fine. THe compiler backend would have to pad, meaning doing the indexing correctly.
  • MM: Would like to see them. This general direction is something I’m comfortable with.
  • DN: Saw a reference to another issue and will copy into that issue the ruleset I think is portable.
  • JG: You mentioned being able to supply an overly large stride, which means we have to re-calculate indices into that stride.
  • DN: Depends …
  • JG: If there is a case we have to respecify we have to think about it more. One thing to add dead members but indexing overhead is another things
  • KN: Dead members into the thing in the array you didn’t have before
  • JG: If you index into 100 and don’t have native support for a too large stride you have to index to 200
  • KN … [missed]
  • MM: You know this at compile time so can make the compiler smarter
  • JG: Don't’ think this is beneficial smartness in the compiler
  • MM: Another way to do this is, instead of adding an additional array member, make each array member smarter. Make the array element type larger instead of making the array larger.
  • DN: That’s what KN was suggesting.
  • MM: In MSL that works great.
  • JG: Unless I’m mis-understanding what stride means I don't’ think that works
  • KN: Not sure if it works in all cases
  • DM: Wanted to ask David about the rules, David is providing vulkan for 140 and 430 to consider, can we get other API rules in the same place?
  • DN: Don’t know if DX has an authoritative rules. My reading of MSL is it has an ABI it gets from the platform.
  • MM: For MSL it matches the layout of structs in C on an x86-64 Mac.
  • DM: So metal would be good with 140 or 430
  • MM: I think that’s true but have to check
  • DN: have to look at the aligned attribute
  • MM: Clang attribute applied. Once see the rules can tell if they work in MSL.
  • JG: The rules are in the OpenGL ES 3.2 spec which has sections which describe them.
  • MM: Didn’t KN say they have different rules?
  • KN: Not that they’re different, just in OpenGL you have to do something, and in vulkan it’s validated.
  • DM: Can we get D3D clarification?
  • DP: Will look into D3D rules.

Add type rules for binary operators (#772)

  • DJ: Added so folks could review
  • MM: Without a rendering, hard to read. We should accept as a base and async figure out how to get auto-rendering for pull requests.

Remove break if in favor of if () { break; }. (#643)

  • DN: The question from DM was what about if() return foo(); in a non-uniform way. My first direction, with the braces or not, not that significant. Divergant or a barrier is a function call. Not sure what else to say. The return from the function is already disruptive for control flow. If the person is doing this they should know what they’re doing.
  • RM: It should be fine, if they get it right, who cares. If they get it wrong we should be able to provide a clear error. Having the syntax guide users isn’t as required.
  • MM: This is the argument that DM gave last time we discussed. Fairly compelling.
  • DM: Concern just came to mind, so I wanted to chat. Thinking about what we’re solving here and the explanation is starting to make sense. Seems like a loophole in the solution and we need to solve one way or another
  • JG: Not sure I understand
  • DM: Introducing special syntax to have guarantees but in this case, return doesn't have that guarantee. So special syntax doesn’t make sense
  • JG: Not bad either
  • MM: Could make it not work with return
  • JG: Could if that’s what folks want, I’d like it to work with return
  • DM: Don’t think we need the special syntax but could also exclude the return.
  • JG: Is there anything to taking this and having a followup PR?
  • MM: In order to answer, someone should make a coherent statement on what we’re solving
  • JG: Trying to make it so we have an indication that breaking after an if shouldn't have more things between the if and the break.
  • MM: Why?
  • DN: Had discussions about folks writing shaders in one language and carrying over to WGSL. Don’t want to have non-portable code carried over. One thing is the analysis from RM would disallow as a compiler error. Would like to head off to the pass before folks try to do that.
  • JG: Proposal 2 pronged. Easier way to give the implications DN sees values in, also lightens the restrictions on having {}s everywhere which I like. I find in certain code control flow statements with brackets just add noise. With those 2 prongs in mind, unless there is a real objection, it’s a why not? The argument for why not is it’s cool to have braces but that’s an opinionated style thing.
  • MM: Surprised at answer from DN. If we’re considering generated code then how is additional syntax going to help code generators. Only see value in this for humans
  • DJ: He said ported, not generated.
  • MM: So, code written in one language a human translates to WGSL.
  • DM: Also find that case string. If I have GLSL which does if () { something; break; } I’m going to write it in WGSL and get the compile error. So, not a solution to the problem.
  • DN: That’s why I had break if() since it looks different and makes you think about it differently. Would like break if to be idiomatic in our examples. And if you’re porting from WGSL makes it clearer. If folks are WGSL first and then being ported to GLSL then you won’t have the error protecting you anymore.
  • MM: Worth considering case with code between the if and break. The code between if and break doesn’t have any unifiormity issues, that code seems legit, dont’ think we should disallow authors from using that code.
  • JG: Don’t think there is any more discussion we can have. Woudl like to have this change.
  • DS: I don’t want to see this as a lever for dropping braces for if all the time. I have made mistakes doing this.
  • JG: That type of error is a combination of tooling and human.
  • RM: There is an difference between linters and compilers. Most people don’t run linters.
  • DS: We drop break if, and if people do bad things then we use RM’s rules to give them compiler errors. We need those rules error.
  • JG: Why does you liking braces require everyone to use braces?
  • DM: We can postpone this.
  • JG: It isn’t a big change.
  • DS: The one that removes braces is a more significant change e.g. removes the need for braces on for loops.
  • DS: Should we allow a function without braces, just a return?
  • MM: I think if we want to go in that direction, we should match an existing popular language.
  • JG: You can do this in C++.
  • DN: Can I do a for for for for nesting?
  • JG: Yes. People do that. I don’t particularly like it.
  • GR: Lack of braces is where the most notorious C++ problems pop up, like a dangling else.
  • JG: This can be done with style guides and linters. I think my change allows what I want and still allows everyone to use braces.
  • DS: This is something we can change later.
  • JG: Sure, but I don’t want that to be code for “never come back”. I don’t want to have to remember this discussion. I think we’re close to a decision between:
    • require all braces everywhere, and
    • allow them to be omitted in a few cases
  • GR: As a matter of procedure, since there are strong opinions, I don’t think we can make the decision now.
  • JG: Is there any more information to be gained here?
  • DJ: Is the decision here locked with the decision for 705 (next)?
  • GR: I suggest we put these topics on an agenda and everyone comes prepared to make a decision.
  • DJ: Agreed. Let’s do it in 2 weeks.
  • MM: Question - do you think we have a limited budget for sugar? If so, then that impacts the decision we (Apple) would make?
  • DN: I think there is a limited footprint that affects testing. For each item, we need to thinkk about the impact on testing.
  • RM: I agree with the principle. But for sugar, I think it requires less testing because it only impacts the parser.
  • JG: I think there is a total overall budget but it is hard to judge any subpart. I don’t think this adds much complexity.

Allow e.g. if (cond) break/continue/return/kill; without brackets. (#705)

Updating loop section to include for (#757)

Workgroup Size builtin decoration restrictions. (#750)

Requiring integral-valued float literals to have .0 seems gratuitous (#739)

Assignment of swizzled values should be permitted (#737)

Add .rgba aliases to .xyzw (#754)

WGSL should have a shuffle builtin function (#748)

type foo = struct is unfamiliar (#735)

Clone this wiki locally