Skip to content

WGSL 2020 06 02

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

  • Remove break if in favor of if () { break; }. (#643)
  • Allow e.g. if (cond) break/continue/return/kill; without brackets. (#705)
  • Remove "unless" statement (#577)
  • WGSL should have a shuffle builtin function (#748)
  • should be logical right shift and >> should be arithmetic right shift (#790)

  • type foo = struct is unfamiliar (#735)
  • Requiring integral-valued float literals to have .0 seems gratuitous (#739)
  • entry_point_decl should be an annotation on the function (#662)
  • C-like declaration order (#677)
  • Add 0/1 swizzle syntax (#732)

📋 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


⚖️ Discussion

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

  • DS: My last comment was about “unless”, but we just resolved (below) to remove that and add it to the reserved keywords. So this becomes close to accepting as is, and leaves it as whether or not to require braces. Which could be a follow-on from #705 (that starts that).
  • DS: We’re fine with removing break if and continue if. Does anyone want to keep them?
  • DN: There is a rule about exiting continuing blocks that requires a break inside a conditional. That might require a break if.
  • MM: Can we see an example of doing it wrong
  • DN: …. A lot of code in words ….. Escaping from a blob in the middle ..
continuing {
   // stuff
   if (something) break;
   // more stuff
}

  • JG: Like the end of the block has to go back to continue or break
  • MM: So, there can be only one exit point? I guess an if and an else would be valid
  • DN: Yup, and we'll have tests for it
  • DM: Is it a general issue, not having anything after the return like if your function has to return a type
  • RM: Not too concerned, we have these rules for the return because everything in a switch has rules on how it has to end. It’s a bit of spec test but, in my experience aren't’ too tricky to write
  • MM: I think David's rules don’t naturally fit into those rules. A big block with an if break in the middle would be illegal, but our rules would make it legal
  • RM: Rule that you can’t have an if with a break in the middle of the case.
  • DN: Did that with grammar, but we can do it. Let's take off line, spec test is a bit more subtle but we can get it done.
  • JG: Resolved.

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

  • DJ: What should we do here now?
  • JG: Goes into a holding pattern. Would be nice to have this flexibility but would have to resolve the dangling else issue.
  • GR: Came to the conclusion that it wasn’t an issue, as you couldn’t have if followed by if as you’d need a {} intervening.
  • JG: Sounds correct, one of the resolutions, no curly braces for if in the same vein.
  • GR: We talked about maybe expanding this to the broader case
  • JG: Some discussion, but I dont’ think there was tonne of appetite, Kinda opinionated but we’ve done other opinionated stuff.
  • GR: Opinionated because it’s different
  • JG: Yea, some code styles wouldn’t be allowed, some want a minimum number of braces. I think needing braces in general isn’t a bad idea, but requiring in all cases is opinionated
  • MM: What about GLSL and HLSL
  • GR: Curly braces are not required, same as C.
  • MM: GLSL?
    GR: It’s true for both.
  • JG: So, not to drag this on, I don’t think we need to spend group time. I’m going to fixup to make sense in a post #643 world and leave for now.
  • DJ: Ok.

Remove "unless" statement (#577)

  • MM: There is an unless statement. If I understand correctly, in SPIR-V if you have a conditional you have an if and a then label. Someone else should explain
  • DN: So, unless appears in perl and says if the condition is false do the thing. That’s what it means in WGSL. Sometimes it’s the nicer way to say something. For example, the desugaring of for desugars the breaking out of the loop, where you want the while condition to be not true, so it’s unless (condition). Sometimes what you want to do. Symmetric case to if and symmetric to branch conditional. Later there were suggestions on how to map. There are two natural ways, 1. emit the negation of the condition and use an if, or 2. use an if() with an empty true case and put the body in the else case. Working on bidirectional translations so don't have data on how complicated this code is. Just getting control flow into tint, so we should have some data soon.
  • MM: The reason it’s worth considering if it should be in the language, 2 arguments. 1- don’t think it affects performance. You can compile an unless to switch the two labels of the conditional. 2- As far as readability, no popular shading language has unless. The implicit negation, I find, is more confusing than not having it because of how it distributes over || and &&.
  • PJ: I’d say, learning as a new language, the simpler the syntax the better, so removing unless means one less keyword to learn.
  • JG: Feel like we could ship without unless and it wouldn't be an issue. Maybe it adds value, but we can ship without it.
  • DJ: Is anyone arguing for keeping the unless statement.
  • DN: I’m the proponent and I believe in symmetries. I buy the argument if we miss it we can add it later. Working with the translation both ways, getting used to having some amount of complexity. The if/else turned out cleaner then expected.
  • DS: Removing it from now is fine, but let’s add ‘unless’ to the reserved keywords

WGSL should have a shuffle builtin function (#748)

  • DN: A lot of conversation after I stopped commenting. I think this originally forked from Myles’s assigning to multi-letter swizzles. Which requires a variable and I’m allergic, want to work in the value domain. Shuffle2 is a simple way to select between 2 vectors to assemble a new vector. An alternate way to use the select builtin, with select you can do dynamic selection of the indices, which you don’t get with the SPIRV shuffle primitive. But, you could special case when you do have the constants. I’d land on having the select priminitive, in language or library, but I don’t think the constant case is the only ohne we care about.
  • RM: I also think select is better then shuffle since both would look like functions but select would actually be a function which can be called with actual arguments so less tricky to explain. When compiling to a language with shuffle the compiler can do the right thing
  • MM: Bar for new standard library functions is low, if it’s a function lets lump it in
  • DN: I’d like to have select and I’d like more experience doing the translations. So, we can put a few things on ice.
  • MM: Another piece of info, looking in the HLSL corpus for multi letter swizzle assignment, the number of lines which do that divided by the total is 0.1%. So, not super common, so willing to defer multi letter swizzle assignments until later. I thought they were more common.
  • DJ: Issue number? So with the builtin shuffle, do you want to close and open later if we want it, or change into an issue that adds select to the standard library?
  • DN: Close this to add a select. We can then have a proposal there.

>>> should be logical right shift and >> should be arithmetic right shift (#790) (<- this is a spec bug, not a discussion topic. Discussion split to #825. -KN)

Should logical-right-shift have a distinct spelling from arithmetic-right-shift? (#825)

  • KN: Split because the discussion was on the wrong issue. Did Not' close 790, it’s a spec bug, we just typed the wrong thing to each operator. The thing to discuss here is, should there be a >>> operator or not. Should we use the java style where >> always means arithmetic and >>> means logical, or the c style where the signedness of the LHS decides what >> does so you have to cast if you want the other.
  • MM: We have prior art where if the author wants other behaviour they can add casts.
  • RM: Concerned by the Java approach because C, C++, MSL and I think GLSL do things one way, so I’d expect our developers to not necessarily read the spec in detail and if we have the >> shift which in rare cases which is valid but different from those languages then I’d expect quite a few porting bugs.
  • KN: Good point, 2 options. 1- if you use the wrong operator with the wrong signidness or 2- it casts to the right type. I think java casts but don’t know.
  • RM: Having an error would be fine, but not sure what it buys us over a single operator. Doing the cast silently sounds like it would give porting issues
  • KN: I do buy explicit syntax does give us explicit syntax. Being able to read what will happen without knowing the types but fairly simple
  • MM: So >>> with a sign error would be an error?
  • KN: yes
  • GR: I agree. Consistent with requiring explicit casts.
  • MM: So, the GLSL developer would use the >> shift operator because that’s what they’re used to and they'd’ get a compile error to use >>> and they'd use a >>>.
  • KN: Exactly
  • GR: Big fan of differentiating logical and arithmetic shifts that I think the pain is worth it
  • JG: Isn’t an arith shift the same as a logical but cast to unsigned?
  • GR: Depends on the sign
  • JG: But if you cast it and cast back it’s the same?
  • MM: That’s what I was alluding to. If we didn't’ have >>> and >> had different behaviour on sign then you get the effect of >>> you just have to type casts.
  • DN: Fine with >>> as a distinct spelling.
  • GR: Weakly for it, won’t inist but think it's a good idea.
  • DJ: Don’t think there is anyone arguing against it?
  • GR: Sounded like the proposal of >> with casts is the counterpoint
  • JG: For simplicity that’s all we need, do we want the >>> when we have the behaviour already?
  • RN: If we have >>> then it would change the meaning of >> failures. It’s not just adding, it’s adding and restricting.
  • MM: I’m fine with the >>>, that’s a reasonable answer. Would like some kind of overarching plan on why it was fine for different floating behaviour to have authors to write extra code, but here we don’t
  • KN: Couple easy arguments. This is much more common. People typically don’t do unordered comparisons at that frequency, so the overhead is small. The second is that unordered compares are described precisely by the expression with the inversion. In this case, we’d need explicit syntax to precisely describe the situation.
  • JG: Unclear on the proposal for restricting any of this is?
  • RM: If you have a >> on signed integers it’s arth shift. If you have >>> on unsigned it's a logical shift. If you have anything else it’s a compiler error.
  • KN: In the middle of typing a proposal and just posted it to the issue.
  • GR: A little clarity, is it only signed or unsigned we care about on the LHS? Or do we care about RHS as well?
  • JG: LHS
  • GR: Don’t want to throw an extra wrench but what if you shift with a negative? (Greg will open the issue)
  • JG: New issue.
  • RM: And also if you shift too much
  • JG: So, having different shift operators folks will call these signed and unsigned shifts and maybe it’s more explicit. Seems unnecessary to me, a well trodden failure case, if we can make it better maybe we should
  • MM: Define better?
    JG: Failure case is people will think of >> as bit shifts and won’t remember that sometimes they’re arithmetic which means different things if value is signed. And proposal here is the compiler will yell at you, or, no it wouldn't because you could >> on integers and people would fall into that pit, but we’d stop >> on unsigned in which doesn’t save anything
  • KN: Hence, alternate proposal to allow on unsigned
  • PJ: Torn, like explicitness but just one operator that deals with signed and unsigned, what about + and * as they don’t have special versions
  • KN: With + and - they have the same behaviour on signed and unsigned if you use 2s complement.
  • DN: Division and remainder are differentiated. I have an open issue for documenting the binary operators. The proposal for the binary ops is that the types have to match which cuts down the number of cases.
  • MM: I guess that makes sense.
  • DN: Trying to see if there is a signed vs unsigned issue. I’m fine going either way.
  • MM: If no-one has strong opinions ….
  • DM: Is there a strong use case for unsigned shift on a signed negative int? If not a strong use case, then ask users to case and have a single operator with semantics defined for signed and unsigned. I think I agree with Jeff it doesn’t make sense to be more complex than it needs to be.
  • RM: I’m with both
  • JG: Makes sense to have arithmetic shift and if you want logical shift you can cast it. Have to support arith for signed and for unsigned it’s a logical shift.
  • RM: Find it’s confusing what you're saying. In theory you can have logical shift on signed and arith on signed.
  • JG: They’re the same shift
  • RM: No
  • JG: Teach me…
  • RM: Arith replicates the top bit. Logical puts 0 in the top bits
  • JG: Even for unsigned?
  • RM: Yes. In assembly yes. The definition of arith and logical is you have one operator which always does logical shift with signed and arith with unsigned.
  • MM: Oh, cool because registers don’t have types so you just use the right call.
  • JG: Still wouldn't’ call that an arithmetic shift, I’d call that a signed arithmetic shift.
  • RM: Not sure exactly what Java would do, there was a comment it has >> and >>> can you do >> on an unsigned in java?
  • KN: I think you can and I don’t think it does sign extension but I’d have to look it up.
  • RM: Sounds more confusing
  • JG: Hard to tell, that’s what I’m used to, my understanding >> is that sign extends any sign bit and if there is no sign bit it doesn’t extend it. That’s the general model we work with and the general model for other languages. If you could restart everything, maybe doing something else would be better?
    RM: Makes sense.
  • PJ: Javascript also has >>>.
  • RM: For having implemented it, the javascript semantics for shift are different for numbers and big ints
  • KN: Java doesn’t have an unsigned int type.
  • DM: Rust originally had >>> and removed it and now they derive based on the type. Strongly in favour of this position
  • RM: Sounds like a strong argument.
  • DJ: Anyone deeply wanting >>> or more logic on the handling?
  • JG: Devils advocate, if you had a >>> that was always logical and developers formed best practices to always use >>> you might get a soft reboot of signed vs unsigned confusion
  • JG: We can choose to reserve >>> so we can use it later.
  • DN: I’m fine with that but it’s not an identifier someone could use.
  • MM: So define it as an operator but if it appears it’s an error?
  • JG: If we thought it would give better error messages, but if we don’t have >>> in the grammar then there is no recognizable text that has a triple arrow so the grammar would reject. We could modify the grammar to accept late.r
  • DS: Leaving it out of the grammar makes more sense since if it is in for vectors we’d have to split.
  • MM: Users can’t define operators, so I don’t think this matters.
  • JG: I was trying to cover our bases by suggesting we reserve it, but it was a mistake.
  • DS: Resolve this and wait for the spec text to argue it again.

type foo = struct is unfamiliar (#735)

  • MM: Internal request at Apple from a team looking to use WGSL is that this is ugly and doesn’t match any other language. Looks like a typedef but kinda isn’t, just assigning a regular name. Can we just call this struct name like any other language?
  • JG: Grammar wise would be fine?
  • DN: I think it’s a bug to associate a name to a thing that doesn’t need a name. Kai has examples of anonymous structs which are in GLSL extended language for a reason. From an orthogonality perspective don’t like using a name for no reason?
  • MM: Where can you use an anonymous struct in WGSL? Structs can only be defined at the top level
  • DS: Yes, they all have to be named in WGSL.
  • MM: Don’t want us to have anonymous structs.
  • JG: They are more useful with type inference. Then you don’t have to name them. Can use them as return types and auto construct.
  • DS: This came out when I wrote the grammar - DN didn’t want to have to type struct everywhere and this is where we ended up.
  • MM: Is there a solution where we have this but without having people type struct.
  • DS: There was, but not any more. I would like to keep the type foo = struct
  • MM: Yes, we need this
  • JG: If you have a uniform block with a structure, and you have some variable which is an array of structures. In C and C++ there is conflation between the name of the struct type and the value.
  • MM: THose are distinct in WGSL because they are distinct in SPIR-V
  • JG: Unnamed types would allow you to produce e.g. an array of 2-ints, without naming the struct that has two ints.
  • RM: [missed]
  • DS: WOuld this help if we annotated the stride through the struct
  • MM: That would be a different struct.
  • DS: I’m ok with struct name as long as we define it in the grammar
  • JG: WHy would we want to make the grammar more complex? [gives example]
  • DS: Today, struct is never a type declaration. We’d have to declare the structure elsewhere.
  • JG: I am suspicious of this. Looking forward to having anonymous structs.
  • MM: I’m not sure this restricts it. C has both.
  • JG: That makes parsing difficult. Worried about adopting this now into the grammar, and making future things more difficult. Having to deal with named and unnamed structs.
  • MM: At least in MSL, anon structs are not very common. I expect this is true in GLSL and HLSL also.
  • JG: Agree they are probably not super common.
  • DN: I only use this in unions, and unions are not in WGSL
  • JG: I imagine it being used as a uniform block helper. e.g. struct of flags - doesn’t really need a name
  • MM: That pattern in MSL is often represented as a pattern of N ints. They are not named inside the struct declaration.
  • KN: I think that’s not the same thing. That would be an array. In JG’s usecase it would be common for those flags to have different types.
  • MM: Metal is flexible so the surrounding code can reinterpret.
  • KN: If writing that code, I would just name a struct and use that as a member.
  • GR: I want to note that just because we don’t have union now, doesn’t mean we can’t find a reason to add it later.
Clone this wiki locally