Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have all enums have "undefined" as value 0? #45

Closed
Kangz opened this issue Apr 9, 2020 · 13 comments · Fixed by #364
Closed

Have all enums have "undefined" as value 0? #45

Kangz opened this issue Apr 9, 2020 · 13 comments · Fixed by #364
Labels
has resolution Issue is resolved, just needs to be done

Comments

@Kangz
Copy link
Collaborator

Kangz commented Apr 9, 2020

This would allow zero-initializing to be as close as an empty dictionnary as possible in JS. It would also help if the JS API decide in after version 1 to make some enum members optional for example when adding defaults.

@kvark
Copy link
Collaborator

kvark commented Apr 9, 2020

I don't think it's worth mimicking the empty dictionary here, but I do buy the argument about making some stuff optional. How about this compromise: we switch all enum values to start with 1, but only add Undefined = 0 where they can truly be passed as optionals? That would be forward compatible.

@Kangz
Copy link
Collaborator Author

Kangz commented Apr 13, 2020

Great idea. I'll do that, but it will take some time because there's a lot of reordering to do :)

@kainino0x kainino0x added the has resolution Issue is resolved, just needs to be done label May 24, 2023
@kainino0x kainino0x added the !discuss Needs discussion (at meeting or online) label Oct 13, 2023
@kainino0x
Copy link
Collaborator

kainino0x commented Oct 13, 2023

Should we:

  1. have "undefined" variants for enums which are sometimes used with defaults (for example TextureDimension which defaults to "2d" in TextureDescriptor) - and implement the IDL's defaulting in webgpu.h implementations?
  2. or only have them for enums which we use as nullable (for example LoadOp in depthLoadOp/stencilLoadOp, or TextureViewDimension which has nontrivial defaulting)?

I'm tentatively in favor of 2. We can switch to 1 later.

I'm not exactly sure what Dawn does right now, but I'm pretty sure we don't implement the IDL's defaulting, at least in most cases.

@Kangz
Copy link
Collaborator Author

Kangz commented Oct 13, 2023

In Dawn we try to implement the IDL defaulting as much as possible. Though maybe we missed a couple things. In general it's nice if defaulting can be equivalent to zero-initialization as much as possible, so IMHO option 1 would be ideal, with Undefined in every single enum to be future proof when other additions to the header use the enum.

@kainino0x
Copy link
Collaborator

OK with me. I do like having the defaulting there, though because of the various sentinel UNDEFINED values zero-initialization unfortunately doesn't work in general (#158 (comment)). But it does make it somewhat easier to use zero-initialization and initialize only the fields which don't default to 0 (probably going to be common practice even after we add INIT macros).

@kainino0x
Copy link
Collaborator

kainino0x commented Oct 13, 2023

Another question came up when I started implementing this: what should we do with output/status enums?

  • status enums: should success be 0 or should we leave 0 unallocated?
  • status enums that have multiple success values (WGPUWaitStatus)

@kainino0x
Copy link
Collaborator

More questions. Do we actually need these? AFAICT neither of these really needs to have default values.

  • WGPUSType_Invalid?
    • In Dawn's C++ bindings, something is needed as the default value of ChainedStruct/ChainedStructOut, but we currently use SType(0u), not wgpu::SType::Invalid. These structures aren't normally used directly anyway, and all of the subtypes of those structs overwrite the sType in their constructors.
  • WGPUFeatureName_Undefined?
    • Not used in any structs.

I looked in Dawn, and we use these, but I don't think we need them.
https://source.chromium.org/search?q=(%5Cbstype::invalid%20OR%20wgpustype_invalid)%20-f:%2Fgen%2F&ss=chromium
https://source.chromium.org/search?q=(%5Cbfeaturename::undefined%20OR%20wgpufeaturename_undefined)%20-f:%2Fgen%2F&ss=chromium

@Kangz
Copy link
Collaborator Author

Kangz commented Oct 17, 2023

WGPUSType_Invalid is used on the Dawn wire, though we could make it a Dawn-only enum. IMHO it's nice to have so that implementation can validate out extension struct that were zero-intialized and didn't get their sType filled.

No opinion about WGPUFeatureName_Undefined but for consistency we might as well have it? It's cheap

@kainino0x
Copy link
Collaborator

kainino0x commented Oct 24, 2023

webgpu.h meeting: We should implement the defaulting in the C API (and have _Undefined variants for all enums that are used as optional in JS). This is actually very useful for WASM (implementing the C API over the JS API):

It means we don't have to inject WebGPU validation errors when you use Undefined in a place where C doesn't allow it but JS will do defaulting. (Technically we could crash instead, but in #115 I think we decided we didn't want to do things like that.)

It also means we can translate the _Undefined variant into undefined in JS, rather than implementing defaulting (which may not necessarily always be the same for a given enum used in different places)


EDIT(2024-06): posting the full minutes because I didn't capture everything in my summary:

  • Have “undefined” variants for enums that have trivial defaults (have defaults in upstream IDL, and can have defaults in other languages that support them)?
    • CF: If we disallowed 0, we could catch when people use zero-init
    • KN: In WASM, if it’s an error, we have to inject the error
    • Allow undefined, do the defaulting, have it in the enums.
  • Status enums: success=0, or leave 0 unallocated?
    • Don’t need to reserve 0 for output enums.
  • Status enums with multiple success values (WGPUWaitStatus)?
    • This is fine
  • WGPUSType_Invalid: define or just leave 0 unallocated?
    • No harm in this, keep it
    • Don’t name this.
  • WGPUFeatureName_Undefined: define or just leave 0 unallocated?
    • (discussion about extensibility of this enum)
    • AE: Should never get this from EnumerateFeatures. Could mislead people into thinking they need to handle it
    • CF: Can add a comment that 0 is reserved and will always be invalid.
    • Don’t name this.
  • Are there any other enums that reserve 0 but don’t name it?
    • Example: WGPUVertexFormat
    • Don’t name this.
  • Policy: don’t name 0s that are always invalid to use.

@kainino0x
Copy link
Collaborator

Dec 21 meeting

  • KN: Have been working on implementing this in Dawn. A pain because Dawn uses the header structs all the way through its stack
  • Question: Reserve 0 value for CallbackMode and PresentMode?
  • CallbackMode - 0 is currently “WaitAnyOnly” which is sort of the default
    • LK: Some callbacks will “default” to spontaneous but won’t take a callbackmode (next topic). So arguably not always the default. But since they don’t take the enum it doesn’t have to reserve 0.
    • KN: Other enums with 0 not called undefined: CompositeAlphaMode_Auto, and some output enums (Success, NoError)
    • KN: Propose just reserving 0 in case we want to use it. Have to also add validation in Dawn’s implementation
    • Do that
  • PresentMode - 0 is currently “Fifo” but I don’t know if we want to hardcode this as the default. (Should 0=Undefined be invalid or should it default to Fifo?)
    • CF: Fifo is the only present mode available everywhere
    • RM: Would vote for consistency, reserve 0
    • Reserve 0 but it’s not valid and doesn’t do defaulting.

copybara-service bot pushed a commit to google/dawn that referenced this issue Jan 6, 2024
webgpu-native/webgpu-headers#45 (comment)

Bug: dawn:2224
Change-Id: Ib7b8df5ebf0ca7458045a130fb8ee8ad4b3995a7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/166900
Commit-Queue: Kai Ninomiya <[email protected]>
Kokoro: Kokoro <[email protected]>
Reviewed-by: Loko Kung <[email protected]>
@austinEng
Copy link
Collaborator

We did the last of these in Dawn, but also did it for the output enums.

In my opinion, it's marginally nicer to also have output enums start from 1 for consistency. It will avoid problems if there is an unexpected case where an enum becomes used in an input in the future.
It's also nice for zero-initialization; you can initialize to 0 and the implementation will write a non-zero value to it.

@kainino0x kainino0x added the !discuss Needs discussion (at meeting or online) label Jun 12, 2024
@kainino0x
Copy link
Collaborator

Jul 18 meeting:

  • Should we be doing this for output enums?
  • SGTM

@kainino0x kainino0x removed the !discuss Needs discussion (at meeting or online) label Jul 18, 2024
@kainino0x
Copy link
Collaborator

This was fixed in #364, I forgot to link it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has resolution Issue is resolved, just needs to be done
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants