Skip to content

WGSL 2020 11 03

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


🪑 Chair
Dan Sinclair and everyone


⌨️ Scribe
Google Meet


🗺 Location


WGSL Issues


Open Issues
Marked Issues


Meeting Issues

Tentative Agenda

  • Pull requests
    • Unpack builtins (#1196)
    • Change SPIR-V memory model (#1177)
    • Update storage textures to have template params for access type. (#1182)
    • Add access qualifier to buffer types (#1183)
    • Add data packing builtin functions (#1189)
    • Flip the default texture name. (#1180)
    • WGSL: Begin drafting textureSampleCompare builtins (#1176)
    • Allow e.g. if (cond) break/continue/return/kill; without brackets. (#705)
  • Open Issues
    • Sampling non-float textures is forbidden in HLSL (#1162)
    • Proposal to enhance defining input/output variables. (#1155)
    • WGSL: Proposal - square brackets for constructing an array (#1178)
    • sized arrays must have at least one element (#1195)

📋 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
    • Corentin Wallez
    • Dan Sinclair
    • David Neto
    • Kai Ninomiya
    • Ryan Harrison
    • Sarah Mashayekhi
    • Ben Clayton
  • 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
  • Eduardo H.P. Souza

⚖️ Discussion

WGSL: Begin drafting textureSampleCompare builtins (#1176)

  • BC: This is the minimum set found across the 3 backends. Most controversial bit is named parameters. Attempting to reduce the number of overloads and texture names so you can add bias and lod, etc. After the mandatory params you can have named params at the end. Currently minimal, but may grow that as we increase minimum versions.
  • MM: Is this a general language feature
  • BC: Just for these
  • MM: Is that intentional?
  • BC: Testing the water, been thinking it might be nice generally but want feedback
  • DM: Been discussing shading language for 2 years, don’t want to argue about language features like unicode and generics, etc but that’s what we’re doing. THere is an explosion of methods in textures, maybe there is another way?
  • DN: This is the same kind of pattern in GLSL. In the spec it has ‘ImageParams’ which expand in different ways. Done in a meta why there and similar to SPIR-V which has a word which tells the params to come. Reduces the number of overloads. Used for image params in SPIR-V and one other place. Image params could expand into 13 things with various validations. Similar to printf format strings in C with validation. Alternative is combinatorial explosion of functions. Have to make a bunch of different names. Not entirely foreign to stacks now, a fairly well contained in that prior art.
  • BC: Syntax is different from metal, but almost identical in behaviour
  • RM: Optional params and named params are very nice and I like having them but having them just for some functions but not the rest of the language seems messy and an issue if we want to add them to the rest of the lang. Seems like a big feature to add to the language given how far along we are. My question is, how much of a combinatorial explosion are we looking at if we don’t add these, 20 functions or like 2000?
  • BC: Smaller then 2k. To be honest, probably not that many, was erring on the side of caution for the future
  • MM: Adding to what Robin said, these language features (named/optional params) are interesting language features and probably valuable. The std library vs language features discussion are distinct topics and probably mistake to add language feature to reduce the set of individual texture sampling functions from a reasonable number to another reasonable, smaller, number. Am also totally fine with combinatorial explosion. Compiler doesn’t need to have the explosion inside it.
  • BC: Not difficulty of implementing the compiler, but what the programmer has to deal with. GLSL has a bunch of texture sampling ops with the texture type which reduce down to a texture overload. Remember function name to parameter type is a pain. Admit that right now the number of permutations is low. Could go named for now and reduce down at a later date.
  • GR: Curious about GLSL example, what is the builtin that you said?
  • DN: A lot of texture sampling operations. It’s the way it’s written in the GLSL spec. It’s a templated IMAGEPARAMS which represents some sequence of blah blah blah. Then tables of how this ends up being used. Can’t remember of coord is folder in or not
  • GR: Sounds like a way of representing what is the combinatorial explosion. Something that has been done at the API level in recent apis is to pass a struct. Struct lists what is relevant and what is not and we read them back that way
  • MM: Would programmers have to give all fields?
    GR: Only relevant ones and some way to say what fields are relevant.
  • KN: How many params is it, instead of optional we had nullable, some way to pass null in. How many things would you write in the texture invocation?
  • BC: If you need one per optional arg you’re vanilla texture example would be very verbose.
  • DN: Short of named params, I prefer new functions with an extra suffix for each thing you get. Looking at compat table with other named args. Basically offset and others and the others are mutually exclusive (Bias, lod and gradient).
  • KN: We can have overloads, so we can have a simple overload and ones that take the max args and maybe that’s enough.
  • BC: The trouble with overloads is generally dealing with the type for bias you might trip up in the future you have the same signature for multiple overloads. If the consensus is named params is not the direction, going with explicit texture names for now.
  • JG: Sounds like appetite at some point, but not in this PR
  • MM: Right. One of the things metal does to solve to have multiple function calls with same signature is to have an opaque type. You wrap an int or float into the opaque type and use that to distinguish.
  • DJ: So, resolve ot add explicit forms and open post-mvp issue for named params.
  • MM: Named and optional. Or maybe 2 issues.
  • DJ: Ben can you open the issue?
    BC: One other thing in PR is array index being part of the coordinate or not. 2 out of 3 backends pack it in. As mentioned in bug, if we go with a separate param then 2 out of three will have slight perf hit as you have to pack before the call.
  • MM: Isnt’ that a different type? The array level is an int?
  • BC: Not necessarily, blending between mip levels
  • JG: Not for arrays
  • BC: Right
  • MM: If they are different types we should not pack them
  • BC: Will make them a separate argument.
  • DM: Already one feature we have in stdlib and not available to users is generics.
  • MM: Also overloading rules in stdlib. This doesn’t have to be done by MVP but something that should not be relegated to just the stdlib. If valuable to stdlib then valuable for authors.
  • DM: Don’t want language where stdlib is written different from rest.
  • MM: Not for MVP, but something we’ll open an issue for. Other then formulation of texture functions is there a discussion about substencie? Is this the ones we want?
  • DJ: Everyone agreed this was the right set.
  • JG: Sounds like it’s right but got stopped up by the arguments argument. Would have preferred to see the entry points in current WGSL. Easier to sign off. I haven’t vetted them.
  • DN: If we’re wrong, we’ll fix it.
  • JG: Right. Thanks for doing this.
  • MM: And the spec question if we list out every combinatorial explosion entry or do a table like GLSL has.

Add data packing builtin functions (#1189)

  • DN: So, for doing things like [float, float] -> u32 which has both halves as a 16bit float. Common across apis and great for saving bandwidth. Extra case which is a TODO. When you’re doing float 32 -> float 16, if you’re beyond the normal range for f16 you choose if you snap too the max f16 range or ->infinity. Observed 2 different behaviours on vulkan. A todo to sort out there. Aside from that, everything is straight forward. The unpack ones introduce no new interesting cases, just the inverse generally.
  • MM: These functions look like the conversion through 16 bit float is internal to the operation. Doesn’t require f16 in the language.
  • DN: Correct, that’s the point. You generate the intermediates which dont’ represent in WGSL and you just pack them.
  • MM: Not representable without an extension which we’ve agreed to add
  • DN: Right, the core language features
  • MM: These 5 operations are direct drop in all backend apis?
  • DN: Yes.
  • MM: Cool ship it.
  • DN: If not, we’ll fix it. Should file an issue for the beyond the normal range. Saw swiftshader do something that looks like a bug. Consider it raised by this issue but not resolved by this PR.
  • MM: a portability vs performance trade off
  • JG: This is a general issue we have, just more obvious here.
  • DM: One small mistake in the pr but otherwise agree to land.

Unpack builtins (#1196)

  • DN: This is the 32 bit word to the expanded form but in a 32 bit form. Goes through intermediary type not in core language. This does not have corner cases as far as i know.
  • MM: And backend APIs have this?
  • DN: Yes
  • MM: Cool ship it.
  • DJ: Let’s take it.

Change SPIR-V memory model (#1177)

  • DS: THis is just changing the spec to GLSL450. Should be non-controversial.
  • DM: You want this to target the devices that do not support the Vulkan memory model?
  • DS: Yes. We’d have to do this because the Vulkan MM isn’t well supported.
  • RM: Do you have a reference to the GLSL 450 model? I can’t find it, whereas the Vulkan MM is well specified.
  • DN: It isn’t well specified.
  • DM: Wouldn’t it be more useful to write the specification with a reference to the Vulkan MM?
  • RM: I think it would be more clean.
  • DN: What we end up with should be the same as Vulkan but without acquire/release. The fact that we’re mapping it behind the scenes is not important. If it doesn’t work, we can fix that bug.
  • DN: You should definitely consider starting with the Vulkan MM.
  • MM: Reject this patch then?
  • DN: It’s not needed in the preamble.
  • DM: Can’t the spec just say it is Vulkan MM?
  • MM: Agreed.
  • DN: Maybe we should take this preamble section out of the spec? And refer to Vulkan MM?
  • DM: Sounds good!
  • MM: Sounds good!

Update storage textures to have template params for access type. (#1182)

  • DS: Fallout from the F2F. Renaming texture names and access control attributes to various things. This one is updating storage textures to have “storage” in the name, remove “ro”, and “wo”, and moving to access-control param in the template part of the type. Main discussion point, is DM took issue with consistency with the buffer names.
  • DM: Also concerned (but not yet put on the issue); seems hard for me to see how the user would write similar code if they could have generics. Read, and read_write are what; they are not types. What is it generic over? It’s not a type.
  • MM: Could solve this like C++ where we add read_only and read_write as an enum, then template over types.
  • JG: could also make a raw type as well. Type “write” and type “read”.
  • DM: Ok, that would work if we wanted to go that way. Still question of making it consistent with buffers. What’s the value in not making it consistent.
  • DS: Buffers is 1183.

Add access qualifier to buffer types (#1183)

  • DS: Current PR adds decoration to the type part of the buffer variable declaration, and also on the struct type itself. Why in both places? Would be easier to implement if only one place …. [MISSED]
  • JG: For buffers, you’re accessing structured data via structs incoming from the API. Having to do annotations on the buffers, feels for buffers like there’s a desire to reuse a struct in different ways. Feels like we want to reuse struct BAR and const struct BAR, where one decays into another. Instead of having to redeclare the type.
  • DS: I guess the first question is if we want access controls on storage buffers to be the same as on storage textures? As a generic type parameter. And if we want that, do we change the keyword.
  • DN: The value is that you’re looking at structured data. So it is useful to keep using the same types.
  • DS: Those are slightly different (block decorated, array stride, etc).
  • DN: But if I want to pick out a value in the middle of it and load it in… e.g. pick out a vector from the buffer.
  • DM: If you use one structure inside a storage structure, does it need the block and offsets?
  • DN: It needs the offsets, but it cannot have the block keyword. Can’t be a binding point.
  • MM: I plan to open an issue about “this block definition thing”
  • JG: Do you not want the block type?
  • MM: I shouldn’t derail this discussion.
  • DN: We need to work out how to define arrays of bindings in the future.
  • DM: I think we can get rid of the separate types for storage and uniform buffers.
  • JG: What we did for storage buffers is different from textures, because they have different uses.
  • DS: DM, do you mean the types are redundant with access control?
  • DM: Few things are redundant. Topic for another call.
  • DS: DM, would you be able to write up what you see as block struct / uniform struc?
  • DM: Yes
  • DN: And there is a difference between read-only and read-write storage buffers. The thing we get from struct is that there is only one way to describe “structures”. Any new name will sound a lot like struct anyway.
  • [MISSED]
  • MM: So I have a struct with offsets and strides, and use it locally, it is unobservable if those offsets were used. But it doesn’t impact the type system?
  • DN: Yes.
  • MM: If you have two structs with the same members, only one of which has offsets, you can’t assign between them?
  • DN: Yes.
  • JG: I feel like doing access(read) is a lot like “const struct” in C++. It would be nice if this was concise.

Flip the default texture name. (#1180)

  • DS: Came out of the f2f.
  • MM: Thumbs up.
  • MM: Textures should have the word texture in there.
  • JG: What about “tex”? It’s shorter.
  • MM: I don’t think it’s worth shortening words.
  • DN: Vote for full word.
  • Resolved: Accepted.

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

  • JG: The PR does not have dangling else, so it should be ok.
  • JG: Take a look and we can talk about it next week.
  • DS: I had a comment. You added branch stmt into body stmt, which means you could do a function without brackets. Did you mean that?
  • JG: We can resolve that. That’s maybe a little terse.
  • Resolution: To be discussed at a future meeting.

Sampling non-float textures is forbidden in HLSL (#1162)

  • DM: The proposal is to restrict WGSL to have texture sampling instructions require floating point textures and only return vec4<f32> and nothing else. If the user needs non-floating point they use texture load
  • MM: Discussed this, few different mechanisms to support this. This one proposed is probably the most simple/elegant/best solution.
  • DM: I’ll write a PR?
  • DJ: Yup
  • JG: Since you can only sample with nearest you may as well make it a storage texture?
  • DM: it’s still a sampled texture but you use load to get the value. The wrapping modes are not applied as it isn’t sampled. We can load sampled textures which is what will have to happen on integer textures.
  • JG: Ok.
  • DN: And the return type is the vec4<f32> and all the components are either well defined or some PR will describe that. Don’t know if there is a swizzling features, probably a separate feature.
  • DM: We discussed it in some issue, should be defined other for depth/stencil textures.

sized arrays must have at least one element (#1195)

  • DN: They should.
  • MM: Is this for all arrays? Yea, think that makes sense. We already guarantee that members of structs that aren’t arrays the binding has to be large enough to support them. This just factors into the same type of calculation.
  • DM: Also affects all the internally defined types. For function variables and such.
  • MM: Do textures have to have at least one texel?
  • DN: That’s a good question
  • DM: Why wouldn't’ they?
  • JG: You can have zero sized textures usually.
  • MM: If we had zero sized textures, reading would be out of bounds, what would sampling return?
  • KN: Storage or sampled textures?
  • JG: Sampled in GLSL is an incomplete texture
  • MM: Don’t have concept of incomplete textures. Vote they have 1 texel
  • KN: Cant’ create zero sized textures in the API
  • MM: That’s a validation rule?
  • KN: Yea
  • JG: Thought it was the other way
  • KN: some thing … buffers … something?
  • JG: What did we decide for unsized arrays?
  • DN: Must only appear in buffers mapped from the api and will have the rule the min buffer size includes one element, so it’s non-empty.
  • KN: Don’t think we wrote it down but pretty sure we decided you can’t have zero sized textures
  • JG: Would be cool to call out in the texture section
  • KN: Sampling requires 1 texel as you can’t clamp without one texel
  • MM: There is an out of bounds behaviour for loading/reading but not sampling
  • JG: Sounds reasonable and at the API level if you want zero sized textures you clamp to 1 and everything just works. Fairly reasonable. Make it so.
  • DJ: Can someone take an action to capture the texture part for the spec.
  • JG: Can write that down.
  • (New issue:

For next meeting

  • Proposal to enhance defining input/output variables. (#1155)
  • WGSL: Proposal - square brackets for constructing an array (#1178)