Skip to content

WGSL 2020 10 06

François Daoust edited this page Dec 2, 2020 · 1 revision
Clone this wiki locally


Dan Sinclair and everyone


⌨️ Scribe
Google Meet




WGSL Issues


Open Issues
Marked Issues


Meeting Issues

Tentative Agenda

  • Admin
  • PRs from Last Week
  • Add arrayLength builtin method. (#1121)
  • Define the interface of an entry point in a WGSL program (#774)
  • Add read_only decoration to variables. (#1120)
  • Which storage classes do we need? (#1105)
  • Elaborate storage classes section (#1093)
  • Allow identity conversion of vectors. (#1103)
  • Issue with type converting module scoped variables (#1104)
  • Query size of texture (#1107)
  • Is Input/Output access one-way? (#1113)
  • Invariant qualifier (#893)
  • Method of ensuring GPUShaderModules can contain MTLLibraries (#1064)

📋 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
    • Greg Roth
    • Michael Dougherty
    • Rafael Cintron
    • Tex Riddell
  • Mozilla
    • Dzmitry Malyshau
    • Jeff Gilbert
  • Kings Distributed Systems
    • Daniel Desjardins
    • Dominic Cerisano
    • Hamada Gasmallah
    • Wes Garland
  • Joshua Groves
  • Kris & Paul Leathers
  • Lukasz Pasek
  • Matijs Toonen
  • Mehmet Oguz Derin
  • Pelle Johnsen
  • Timo de Kort
  • Tyler Larson

⚖️ Discussion


  • [Absent DJ: There is going to be a WebGPU virtual F2F. Please fill in the Doodle to help choose times.]

PR reminders

Following up from last week…

This appears ready to land: \

  • No explicit grammar for decorations (#689) - Updated by Jeff, Reviewed by Dan
  • DS: Merge conflicts, otherwise good to go

Does this need to go back on the agenda? \

  • Add bit-complement operator ~ (#727)
  • JG: Probably.
  • JG: Discussing PR from DN, idea from DM is to use Rust style ! for bit-complement in addition to logical negation. Given it is not ambiguous
  • MM: And other proposal is ~ for integral and ! for bool types (and vectors of those), possibly matrices?
  • JG: There are uint matrices?
  • DN: In HLSL but not GLSL or SPIR-V.
  • DM: SPIR-V is only float?
  • DN: Yes.
  • DM: Arguments have all been voiced, understand group is steering towards ~, so that’s the way we’re going. I think having a not operator would help like DN suggested.
  • DN: I suggested builtin function, don’t want an operator
  • MM: So, a function that takes integral or bool?
  • DN: Sure. Mainly thinking integral but would be fine with both
  • MM: In addition or instead of operators?
  • DN: Either way
  • MM: In addition would be fine. Barrier stdlib is low, so adding a not in there is fine.
  • JG: Can talk about not builtin later if we want, unless it changes mind on this issue.
  • MM:Wouldn’t change my mind.
  • JG: Sounds like consensus for ! and ~. Resolved. This PR can be merged and this reflects the decision.
  • DN: I’ll make sure there are no conflicts and merge
  • JG: Ready to merge after conflicts resolved.


Int and float literals don't include leading minus (#1092)

  • We didn’t finish the discussion last week (we had consensus on most of it). Since then it’s been moved to Post MVP. Just want to check everyone is ok with that.
  • DN: DS convinced we can add later without breaking programs. It’s an annoyance but it’s an error and we can enhance later on to accept the nicer thing.
  • MM:Disagree with this direction but won’t hold it up.
  • JG: Is there a particular thing to see addressed?
    MM: Nothing more narrow then the proposal. Can defer to after MVP.

Add arrayLength builtin method. (#1121)

  • DS: I think this is good, to merge. We can open a new issue for extending to other arrays
  • DM: What about Metal?
  • DS: We’ll need to pass it in
  • MM: The usefulness of this is greater then the effort of passing in
  • JG: We’ll also already have this information
  • MM: Do we have to pass in a unsigned?
  • DS: Not spec’d in WGSL
  • DN: In SPIR-V it’s a signed integer
  • MM: So -1 is before the array?
  • DN: Correct. -1 is useful in c languages if you want to go back. Range you lose isn’t something we really care about so having signed arith seemed fine for graphics
  • MM: We don’t have raw pointers, just types. You can’t be at index 5 and go back to index 2.
  • DN: Yes, talking about all indexing into any kind of object is treated as signed
  • JG: Would prefer unsigned for this so we can make the types enforce things.
  • MM: Important for metal as 2 bounds checks get turned into 1
  • JG: As you don’t have to clamp against 0, just against max
  • MM: Right.
  • MM: If it’s undefined in WGSL we don't’ have to decide now but would prefer indexes into buffers to be unsigned when we get there. Probably same with vectors and matrices
  • DN: So, if you do an indexing operation the argument has to be unsigned?
  • MM: Goal is the bound only has to do one side of the check. 1 way, the argument the programmer provides must be unsigned. Other way is the argument can be signed and the implementation does a conversion. Prefer the first, but could be arguments for the second.
  • DN: From user perspective, when phrased as unsigned, the index can’t be larger then 2 billion.
  • JG: This is something that would be true if we had buffers that big.
  • MM: If we say indices are unsigned we could have buffers > 2gig. GPUs have this much memory
  • JG: Wouldn’t be 2gig as they’re all dwords …
  • KN: What would SPIRV do? Index to 2 billion, take pointer and index again?
  • DN: Can’t do that, no way to slide along the array. If you need to address more than 2 billion objects, need 64bit types.
  • MM: Getting hung up on how things work now. All apis have or will have issue indexing large arrays. We’ll want this in the future so we should think about it.
  • KN: Only gives arrays between certain sizes
  • JG: If we took u64 instead and converts u32 or we take both. Would work in the future for large addressing.
  • MM: Will open an issue about this.
  • JG: Approved and will merge this PR.

Define the interface of an entry point in a WGSL program (#774)

  • [Absent DJ: This obviously essential topic has been sitting in the “under discussion” section for a while, and has spawned a few follow-up issues. What extra work is needed? Should we file more sub-issues?]
  • DN: Have WIP in that starts talking about inputs and outputs and describes builtin variables. Has prelim statement that the shader interface is “blah blah blah”
  • DS: Can defer this for this week as DN fills out PR.

Add read_only decoration to variables. (#1120)

  • DS: Would putting up a PR help?
    MM: Without an annotation would it be sampled?
  • DS: Don’t know?
  • DN: Readwrite samplers in the future
  • JG: Feels like part of the type?
  • MM: So either a space or underscore between the things
  • JG: Overloaders which only work for some of these
  • DM: Question of putting on type or variable. Different variables with same type and different access modifiers
  • MM: Would like to see samples of code that works one way but not the other.
  • DN: For textures, need to know what ops apply (what buildings) having annotation on variable, it’s a different way of accounting for type checking. What overloads are available. For me buffers are different as I’ll have pointers to the insides of the buffers. Can do different things on the pointers based on that. Seems like read_only is just a weird/different way for something being on the type.
  • MM: Do you envision 10 years from now WGSL will have raw pointers like MSL has raw pointers?
  • DN: There is a vulkan extension which has pointer-like abilities in storage buffers. Constrained to certain storage classes. Think it will become more mainstream. More qualified yes.
  • GR: 2 tiers allowing pointers into storage buffers and c++ pointers, big jump between the two
  • JG: Suspect we’ll have the former
  • MM: Right, so a typesystem now which doesn’t seem terrible when we add them would be good
  • JG: Would be nice, but seems big enough that we could rev the language if we needed too
  • GR: Would say, don’t know if we want to foreclose on c++ style pointers but it’s a big undertaking.
  • DN: Prefer having on variable, when adding read/write textures just repeating in the spec methods with write only or write read would be annoying. Would be nice to just say write only or read/write
  • MM: Types are like a data structure. One of those fields could be which set of functions work.
  • DN: The split for me is a sampled vs storage texture. See ro, rw, wo as a qualification on the storage texture. Coords are integers and no sampling, no filtering.
  • JG: So part of the type parameterization.
  • DN: Storage texture and sampled texture are first divide then read/write is parameterization of the type. Like MSL does with access qualifier as extra decoration on the parameter.
  • DM: But metal doesn’t have separate types
  • DN: Correct
  • DM Fine with your proposal.
  • MM: Not sure the actual difference to the programmer, what can they write with one that they couldnt’ with the other.
  • JG: As far as typing is concerned, could be an annotation on var and still part of the type.Same way you can’t convert const to non-const in c-like types. You have to type const if you want to receive a const.
  • DN: Right, grammatically we put the type of the variable after the : so may as well make it an explicit parameter.
  • DM: Isnt’ about what they can/can’t type will validate the same code paths. May just be on a different level. It’s about how pretty/concise the spec is. DN’s proposal is nice because it’s an access qualifier same with API where uniform buffers don’t have the qualifier.
  • MM: Sounds like you said there is no program you can write with the qualifier on the type but woudlnt’ work with it on the variable so this is all editorial so no difference to the programmer?
  • DM: If the programmer needs to express something they can do it either of those ways
  • DN: Would say if you have a helper which takes a pointer to one of those can you do something . If qualification on variable instead of type call inot helper may not care, or helper promises to only read so is compatible with read/only read/write parameter.
  • JG: The type is still annotated but doing it on the variable is you do an implicit coercion between the readonly/readwrite types. Readwrite can decay into readonly.
  • MM: Type breaker is picking which overloads are available, that’s a type operation. If the set of overloads is effected must be part of the type as that’s the input to the function in the compiler.
  • DN: Agreed.
  • JG: So, sounds like direction is having parameter on the real type.
  • DS: so texture<access::Read>, texture<access::ReadWrite>, texture<access:Write> ?
  • MM: Sounds like right direction someone should write up so we see what it looks like to see if it’s awful or reasonable.
  • DS: So, close 1120. Make PR to change texture types. Then decide if we want to do this on the type here as well
  • DN: So buffers as well?
  • JG: I think so
  • MM: We should look at it first, but that’s my inclination.
  • DN: Right now we have block decorated struct, do we add it to the struct type or at the point of declaration?
  • JG: On the type I think
  • DS: Yea, so another annotation like block on struct.

Which storage classes do we need? (#1105)

  • DN: In PR for #1093 has table describing names and properties. Was pointed out by DM we have textures/samples, uniform buffers and storage buffers in 3 buckets. If we’re distinguishing textures and samplers by type, why have storage class to also group them since we have all the info. Strongest answer is that all those things are opaque handle like things that go 1:1 with bindings and have no internal structure to address with. The handles do not change though they reference data that might change. Set of objects with same set of properties so this organizes them in the spec and programmers mind so they may as well be called a storage class.
  • MM: DM said what I’d say, if in type why provide separate. Understand the organization argument. Could the organization only exist in the spec and not require the programmer to type the keyword?
  • DN: All the info is redundant, so yes. Other spots have things like ‘host sharable types’ we could have ‘opaque handles’ section. Then you’d have var ident : texture then we have module scope declaration which doesn’t have the storage class. Other declarations will have storage class. Earlier talked about keeping storage class always on module scope to keep them distinguished. Worried about removing storage class on module scoped variables then we have to have enumeration and programmers must remember
  • MM: Do they need to remember? If they remember wrong, what type is an incorrect program. What could go wrong?
  • DN: Passing reference to image into helper function which gets rejected.
  • MM: In my mind that’s an operation you can’t do and the storage class is irrelevant.
  • DN: So, what’s the proposal, remove storage class on var?
  • MM: For some of the types. Need for constant buffers and device buffers.
  • DN: Storage buffers
  • MM: Yes, storage buffers. I don’t think you need it for textures or samplers as it’s implied. It is forward compatible as we can add it in the future if the storage class does provide new information. But it is redundant and not necessary to make the programmer type it out.
  • DM: Remember discussion about mandatory classes, but remember it differently. I argued we have to explicitly specify and the majority wanted implicit private. So it isn't mandatory today. So, now more cases are implicit.
  • DN: Must remember where we landed differently. So, there are module scope private variables without the storage class annotation. So, now 2 variables, with different types, 1 is invocation visible and one is ‘uniform’
  • GR: Is not requiring additional typing one of the goals of WGSL? Some other goals are in conflict with that, if this is the primary argument, is it a sound argument? We’ve been very explicit in other places.
  • MM: Would answer that, less typing is not a goal but making the language be human writable is a goal. There is a small but present cost of typing something you don’t need to type. Also typing something that doesn’t exits in other shading languages. Discussing the textures and samplers storage class doesn’t exist in MSL and I don't’ think in HLSL. So, not necessary in those contexts. Tried to thread the needle there.
  • GR: Appreciate where you’re coming from, no strong feelings.
  • MM: Explicit casts, I think does improve writablility as I get bit by implicit casts in c and c++.
  • GR: Specifically said more typing vs writability. Happy with more typing that fixes mistakes.
  • JG: Could be more obvious it’s a handle so you know when writing it there are rules for handles. Could get along without it.
  • MM: Similar to what was said before, the logical leap of this is a texture, therefor a texture therefore have to handle this way is more steps then I think about vs this is a texture can’t do that there.
  • JG: Seems like appetite for a category we talk about in the spec but not one we type
  • MM: Think that’s fine.
  • DN: What about UBO vs SSBO.
  • MM: Whatever we have today is fine.
  • DM: Do we have anything today?
  • DN: PR has storage_buffer and uniform. Slightly awkward, feel free to bikeshed, buffer vs buffer_ro?
  • DM: Would match the textures buffer_ro and buffer_rw.
  • MM: There is a difference, at least in metal, about a buffer that is read only vs in the constant address space. We should preserve that distinction.
  • DN: Leads into the other issue of where read_only goes on the storage buffer.
  • MM: THe difference between is constant address space buffers have limited size. Can’t put 2gig in there, different access patterns. Optimized for broadcast instead of each thread reading it’s element
  • DM: Different alignment for fields, runtime arrays. Strongly for keeping separation.
  • DN: Bikeshed on name.
  • DM: Can we go the same route as textures. Regular buffer is a constant buffer and buffer_ro and buffer_rw would be storage.
  • DS: So 3 types?
  • MM: If you put that in the types, do we need to storage class?
  • DM: Need workgroup and input/output.
  • JG: Feels weird to have buffer, buffer_ro and buffer_rw.
  • MM: Disagree, not weird either way. Both seem fine.
  • JG: I’d forgotten we had those 3 things. In my mind, I’d expect buffer to be ro or rw. Now realizing it’s a different thing.
    MM: Underlying is unifying with textures. If we don’t want 3 types, could we do the same with textures.
  • GR: Not opposed. Whatever names we choose, unless the same as alternatives, we’ll need documentation.
  • JG: That should be in the spec as non-normative translations. You’re here from D3D 12, here is a UAV.
  • GR: That’s what folks will read first
  • MM: Does that include all of the 3 backend APIS and openGL and WebGL and will we have sections for each of those in the spec? Makes spec big
  • JG: I think it’s fine, it’s a table of here is the term we use and in other APIs. 3 primary APIs, maybe OpeNGL and maybe D3D11
  • MM: How about, instead of policy, but if someone makes a PR to add the table we’ll accept it but if it’s missing that’s fine.
  • JG: Sounds good.

Elaborate storage classes section (#1093)

Allow identity conversion of vectors. (#1103)

  • Top of next meeting

Issue with type converting module scoped variables (#1104)

Query size of texture (#1107)

  • Top of next meeting

Is Input/Output access one-way? (#1113)

Invariant qualifier (#893)

Method of ensuring GPUShaderModules can contain MTLLibraries (#1064)

  • (Needs API meeting discussion)

For next meeting

  • Size of texture query #1107
  • Allow identity conversion of vectors #1103
  • Operator precedence #1111