Skip to content

WGSL 2020 05 05

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


Mehmet Oguz Derin
  1. Scribe’s Preface: I am new to scribing, and I tend to write using telegraphic sentences. Please let me know or edit where needed.

:𐰆𐰍𐰔 :

⌨️ Scribe
Google Meet




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

📑 Prior Cheat Sheet

Aggressively summarizes (strictly) only the updates from YYYY MM DD - 6 to YYYY MM DD.

This cheat sheet was built by the scribe who would hugely appreciate and improve based on feedback, contact using

❓ Issues ❗️ Pulls
📣 Author 📢 Opinions
  1. No Update
  1. A: Opinion A
  2. B: Opinion B
📣 Author 📢 Opinions
  1. No Update
  1. A: Opinion A
  2. B: Opinion B

📐 Meta

  • DS: With one commit to come, Tint can now compile and validate “Compute Boids” to SPIR-V.
  • DS: We’re waiting for the group to decide on array decorations.
  • DS: The source is in the repository.
  • DM: Congratulations

⚖️ Discussion

Rule for mixed-signedness operands to integer div, rem, less-than, greater-than, less-or-equal, greater-or-equal (#707)

  • DJ: My mistake. This was resolved.

Syntax for "the zero value" for bool type, numeric types, and compositions of them (#685)

  • DN: not sure if any progress has been made….
  • DM: adding zero semantics is a future compatible change, not blocked on resolving
  • DN: True, could always write out the full initializer and can defer this
  • MM: Didn’t realize vector constructors have different overloads. Like vec4(vec3, float) and there are a bunch of those. Because we have all those, having one that takes zero arguments seems natural.
  • DM: It also doesn’t provide as much. Talking about vectors but the issue is all types
  • JG: But if we have for vectors why not all types, so a default float constructor
  • MM: The compiler already generates these things. A var of type float without an = will have the compiler generate the 0. So, if you have a vector, the compiler is doing it for all types already, may as well have default constructors. Shouldn't' be hard to implement. Value for users is you get default init any place you have an r-value, so calling a function
  • DM: Are we going to be passing in samplers and textures
  • DN: UYea, samples, textures and buffer resources. Samplers and textures get complicated with function args, will have to review.
  • DM: So, zero init isn’t good for everything
  • DN: Only for certain types
  • MM: As I understand, this is why textures are globals, so you can’t pass around as arguments.
  • JG: I think you can pass them?
  • DN:Image atomics you can pass. When translating from metal to vulkan you have to do call site specialization. That’s a level of extra work and complexity.
  • MM: Would be happy if it was illegal to pass textures as arguments to functions. Do it the GLSL way.
  • DN: The null value is not for textures, but is for numeric types, matrices of those things and arrays of structures.
  • JG: Difference between value and ref types, the value types make sense, but we don’t have those but include sampler objects but can’t have them in an intermediary state. If you can’t declare something without a value then you can’t default construct. But there are those 2 categories of types, so would be nice to have explicit constructors for all value types
  • DM: In spec, an aggregate of this has a default constructor if all types inside the aggregate have default constructors
  • MM: Yup
  • DN: Can’t remember if a null type is in the spec, but at the top of the issue, but can make it clear in the spec, there is the concept of a storable type. We’ll need a type where you share the memory with the host and you have to lay it out. Can always invent categories in spec to match types you need
  • DM: Not strictly opposed. As a syntax feature it’s unnecessary. Would be fine if we had it.
  • JG: Not entirely unnecessary. Makes it a pain if you want to have a defaulted r-value passed to a function. You either have to write it out explicitly or make a variable with the default type. Would be weird if that was the only way to get a default value. Was a fan from the beginning if the types are inferred from the right hand side. We decided not to require that.
  • KN: Did you decide that concretely? I’m in favour
  • DN: We didn't’ settle it
  • JG: Can agree most default values have a type so you could default construct it.
  • DM: Theoretically passing a struct to a function you default init is possible, but in my experience this never happens
  • JG: Not as interested in structs, more concerned about a matrix or vector
  • MM: See this in C code, like in D3D12 there are a bunch of structs and it’s common to default initialize the contents of the structs.
  • JG: Difference between default and zero init which isn't’ always the same in C++. An important decision to make. We make it easy to zero initialize, but do we want non-zero defaulting constructors?
  • MM: In D3D 12 sample code, there are a number of structs declared as FOO = {0}.
  • DN: The idea behind zero init is you don’t have field by field setting, you have memset or calloc. The zero case is easy if all the default values map to zero.
  • JG: Is that true in spirv?
  • DN: If you choose the false to map to zero then it’s true in zero. SPIR-V got OpConstantNull because LLVM has zero initializer and … something … and it happens to be useful. Maybe at the LLVM level it happens to be useful and you could build up but it’s more verbiage you’d need
  • DM: So, that’s something that maps to hardware/driver work and is fairly useful. It’s something we could follow up with later and we don't know the proper syntax, correct?
  • DN: If we had it we’d use vec4<f32>().
  • DM: So that’s the syntax you agree with
  • DN: Yea, fine with me.
  • DN: Will take a crack at the spec language.

Should all expressions have known types? (#723)

  • KN: Do think it provides a lot of nice benefits. Gets rid of type annots on variable declarations. Should simplify implementations but excludes us from doing certain features we may want which I personally don’t find appealing
  • MM: Filed issue around literals. Literals are the place this is a hard sell. Seems natural for an author to say float a = 1; an int a = 1 and have those work. Mostly understand the benefits. Not going to push for literals now but will wait for feedback from authors and we may want to revisit. For now, a temporary resolution for all r-values to have a type seems like a good place to start.
  • DN: One weird place is a variable in isolation, where it’s being isolated can change the type. Can be seen as a dichotomy from r-and l value or it’s a pointer to storage. Don’t want to tie up in this, but it can be an issue. You know what you want by context which solves the problem but is a compartmentalized thing to deal with.
  • DJ: Resolves issue/question from Kai.
  • DN: Probably ends up as a design guideline not spec text. If we get it right, every statement will have this principle true. Maybe in the preamble stating the intent is ‘y and it will be easier to read’
  • MM: THere are other places in the repo, like a design folder. Maybe makes more sense to go there.
  • KN: Think useful to have in the spec even if it isn’t part of the spec. Makes it easier to understand the language
  • DJ: Kai can you take an action to draft a PR.
  • KN: Can, haven’t looked at spec at all, but can do it.
  • DJ: Issue is resolved, any editor that gets it can do it.

Add unordered float compares (#706)

  • DN: A bit of exotica, float compares are usually normal numbers, with NaN all comparisons end up as false. From when you try to push an inversion through an ordinary comparison. Would classify this as exotica, can take advice that normal folks don’t do that, if you want the comparison of the negation of the opposite then do that. Willing to take off the table and hide in canonicalization.
  • MM: Sounds great. So, if you want the other behaviour you write a longer expression that accurately describes the behaviour you want?
  • DN: Right
  • MM: That sounds fine.
  • DN: Jeff’s comment in the bug captures it.
  • DP: Ever the case where you would not want canonicalization to affect it
  • DN: You would not want to do the unordered one if you’re targeting a language which doesn’t support it. Targeting MSL and HLSL pass it through, for DXIL you have to push the negation in
  • DP: But ….
  • DN: There is nothing that requires you to do the unordered comparison. I can keep the negation they’re identical
  • JG: Is the question what if the application wanted to use a negation and an unordered compare and the negation would force the code to use the unordered compare?
    DN: No-one is obliged to use the canonicalized form. This expressiveness can be hidden in the cannonicalization so can still do the fidelity tests and not worry about it
  • JG: Question is if there is hardware which has ordered compare as faster then the negation version
  • DN: Then it’s the job of person mapping to that hardware to do the optimization
  • DJ: Will close issue.

Implicit conversion to bool? (#733)

  • JG: Came up in bitwise negation operator. One proposal was to do the rust thing and have ! expr be bitwise on an int integer type and one of the points is this is surprising to folks not familiar with the behaviour. Most languages folks writing graphics code the ! would be an explicitly coercion of int to bool. Same as if (3) is true and isn’t an error about testing bool-ness of an int. Proposal is, the thing I and a lot of people expect is you have implicit int conversion to bool. We came out against general implicit conversion but I think conversion to bool is expected by many devs. So if you have if (foo) it would be surprising for the compiler to force you to cast to a bool. The same is true for any logical ops.
  • GR: Different categories of surprises in which you get an error and you fix it vs where you do a ! and get a bitwise flip and just get an unexpected result.
  • JG: That’s the surprise I’m most afraid of.
  • MM: One question, are we doing to have bool constructors that accept scalar values of each type.
  • JG: We should, we’d want for perf reasons for compiling to our targets.
  • DN: Dan and I thought differently about how to convert. In the type checking I used the type constructor and he’s been using the cast<f32>(...) to do that and I think I forgot the type rules. I’m not sure if we’d have auto convert to bool by bool constructor
  • MM: as doesn’t do re-interpret.
  • DN: THere is as and cast. One is re-interpret and one is to convert the value.
  • MM: So, rephrase so will we have a cast to the type
  • JG: Bitwise or … cast
  • MM: Logical cast
  • KN: Not == 0 right?
    MM: Yes
  • KN: Such a thing should be in there, but in practice would rather write != 0
  • JG: What if you didn’t do that
  • KN: I would say you have to do that or cast
  • DN: I write code like that and dan rejection
  • DS: I like the explicit ness
  • DM: I like not having implicit conversions at all and have 751 to discuss that and this Bool thing is one of the points on the road
  • GR: Doesn’t sound like anyone is championing the implicit cast argument
  • JG: I like implicit casts. I’d be surprised to come into a language and need to specify explicitly int foo != 0
  • KN: I think for int it would be slightly surprising but you’re not going to be surprised either way. It isn't a pointer with an obvious sentinel value. So reasonable either way.
  • GR: If our guiding principle is if we don’t want implicit casts the bar is higher to say why this is necessary. If you get an error when you do that you won’t be surprised for long
  • JG: Channeling c++ world advice where you don’t cast int types implicitly but are encouraged by many style guides have you do implicit bool conversions. Surprising but only at compile time and that’s not so bad. And, we can add it later, no implicit conversions now and can talk about it later. So, what about resolving to have no-implicit conversions including to bool. Conditionals must take a bool type and if they don’t that’s a type error
  • DS: I think that’s there now
  • KN: Speaking of conditionals it would be less dangerous to all values that aren’t booleans in conditionals but not implicit bool conversions. Later, not now.If we added a feature where you didn’t need a cast maybe we do it only for conditionals and we do it for bool float and int.
  • MM: So if a function takes a boola nd we pass a 3 it fails, but I can do if (3)
  • JG: Would not be in favour
  • DJ: Question, what happens with if (!x)
  • KN: Good question
  • JG: Without implicit conversion to bool, having ! as bitwise negation is more open.
  • MM: Before moving on, shouldn’t close as no change. Only makes sense to have explicit conversion if there are actual cast casts between the types.
  • JG: Value or bitwise cast
  • MM: Value cast. THe same behaviour you were advocating for, if we're’ going to make them type it they have to be able to type it.
  • KN: They can type == 0 or != 0 instead of a cast
  • MM: That’s true
  • DN: In nay cast, the value cast to bool should be the same as != 0
  • KN: I agree.
  • MM: My proposal is not close as no-change, but close as make sure you can cast from all scalar types to bool and they behave as if you’re doing != 0.
  • JG: I can note that.
  • KN: We should open a separate issue as it’s orthogonal
  • DJ: I think it’s a separate issue.
  • DN: Have to fixup type rules for my cast vs type conversion confusion and I’ll probably patch the spec when I get there
  • MM: I’ll file an issue.
  • DN: You aren’t listed as an editor but you’re writing 80-90% of it. Let’s think about making David an editor.

Consider adding sugar for familiar loop constructs (#569)

  • DS: Scores 1 == 20 , 2 == 28, 3 == 24, 4 ==19
  • DJ: Wasn't trying to make this a popularity contest, was trying to see where the majority of folks were, don’t think we should decide on the most popular. Doesn’t look like there is a strong winner.
  • MM: Not sure how relevant or valued, in the twitter pole there was a strong winner, understand if no-one cares
  • GR: Can’t hurt ot have more info
  • JG: Can hurt to treat all info as equally valuable. One issue with doing the poles this way I’d be shocked if the twitter pole came out with anything other then all the loops
  • MM: It didn’t come up with that. I ran the pole twice, first time didn't’ have same options, first one had all the loops and it didn't’ win. (loop loop, for loop and while loop) winner by > 50% was just for and while. Won in both poles.
  • DJ: Don’t know how to resolve. One is to accept all and at a later time decide if we dont’ want one. Later time is rapidly approaching. It would be a subtraction not an addition.
  • JG: Not a requirement, would love to just have loop primitive
  • DJ: That only had a “loop” and nothing else?
  • JG: I’d be disappointed if we ended up without a loop keyword, If i had to write while(true)
  • MM: From an authors point of view?
    JG: From the author point of view. I have a lot of code i’d like to not have to write while(true)
  • DJ: Would it be a disaster to have all 3. Is it a large amount of engineering work?
  • DN: I think it’s unwise to add too many constructors. You blow up testing. I would say given the mix of results I’d like loop and simple for.
  • JG: I think that's my compromise vote
  • MM: We’d accept loop with a simple for.
  • DJ: Then would like to hear microsoft opinion?
    GR: Our focus is to make this work with our tools and all these options seem fine.
  • DP: Agree with Greg, want language as simple as possible in the interest of success
  • GR: Non-Microsoft hat, this seems like a good compromise.
  • MM: One question, if we do resolve, the for loop would not have a continuing block
  • DN: Need a continuing block if you have a loop that can’t be expressed. THe continuing depends on if you’re using a value in the continue code that isn't’ available. The need for continuing is only certain cases
  • DS: for doesn’t need a continuing keyword. it is only needed in loop.
  • GR: JohnK just expressed interest in continuing.

Resolved: We will have “loop continuing” and simple “for”.

  • RM: Another related thing is if we want simple blocks in the language. Like {}. It would make it easier to express for loops as a pure sugaring thing. Also useful for programmers to make new scopes for variables to be alive. So, wondering if folks are interested in that.
  • DS: Tied if we have lexicling scoping
  • DN: So everywhere you have a stagement you could have a compound statement but not in the 3rd clause of a for loop
  • RM: Not saying that but easier to express the de-sugared for initializer scoping.
  • MM: If you don't have these blocks the for is not desugared
  • RM: With a pathological block it’s a desugar
  • DN: It’s a good idea and probably just an oversight.

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

Add 0/1 swizzle syntax (#732)

Follow-up: Using the void type (#743)

🗓 Next Week

Clone this wiki locally