Skip to content
This repository was archived by the owner on Jun 18, 2021. It is now read-only.

Case for using wgpu-core #156

Closed
kvark opened this issue Jan 8, 2020 · 11 comments · Fixed by #281
Closed

Case for using wgpu-core #156

kvark opened this issue Jan 8, 2020 · 11 comments · Fixed by #281
Labels
enhancement New feature or request question Further information is requested

Comments

@kvark
Copy link
Member

kvark commented Jan 8, 2020

Currently, wgpu-rs uses the C API of wgpu-native, which then uses wgpu-core for the gory details. This issue raises the question of whether the middle step can be skipped. In order to answer the question, we need to consider all the possible targets for wgpu-rs:

  1. Native execution with wgpu. This is the only target supported right now. It could easily bypass wgpu-native and call into wgpu-core.
  2. Native execution with Dawn (see https://github.com/gfx-rs/wgpu/issues/47). We'd have to use the API calls according to webgpu-headers. This would technically work if wgpu-native implements the headers and becomes a drop-in replacement for Dawn. The target is incompatible with using wgpu-core directly. cc @Kangz
  3. Browser execution on the Web (see Target the Web directly #101). The plan is to use web-sys directly and thus it doesn't depend on wgpu. cc @grovesNL

With that in mind, the only blocker for using wgpu-core directly is running on Dawn. This is somewhat a minor goal for us, given that we are trying to make wgpu a batter (or comparable) solution.

My proposal would be to turn wgpu-rs into a multi-backend library (like gfx-rs is), enforcing the API with traits. The backends are:

  1. wgpu-core - for fastest native development, no FFI boundary.
  2. webgpu-headers - for generic standard-compatible target with wgpu-native, dawn, and possibly some emscripten drop-in libraries implementing the headers.
  3. web-sys - for web development
@kvark kvark added enhancement New feature or request question Further information is requested labels Jan 8, 2020
@grovesNL
Copy link
Collaborator

grovesNL commented Jan 8, 2020

I think I slightly prefer to go through wgpu-native (keeping the middle step), even if only to ensure that the C API works well through dog-fooding. We could also decide to skip wgpu-native later if it turns out to be problematic. We do pay slightly for the indirection through the FFI layer but we could try to measure the cost of this to understand whether it's actually meaningful in typical use cases.

In contrast, with gfx-hal we were focused on as little indirection as possible, which is why we didn't end up implementing the traits from ash or implement the Vulkan API directly. But maybe some amount of indirection isn't too bad in wgpu, especially because of the API design.

@Kangz
Copy link

Kangz commented Jan 9, 2020

Either keeping wgpu-native in the middle all the time, or having wgpu-rs support three backend make sense imho. I agree that wgpu-rs targeting Dawn is minor, but my hope is that an ecosystem develops around webgpu.h so that it benefits to both Dawn and wgpu-native. You lose this is wgpu-rs doesn't at least support an option to go through C FFI.

@kvark
Copy link
Member Author

kvark commented Jan 18, 2020

@grovesNL another feature I found to be important, that opens up if we depend on wgpu-core directly, is avoiding the global state. webgpu-native has lazy-static Global that is accessed on each and every function. wgpu-rs has structs instead of pointer-sized handles, so it could easily add an Arc<Global> member to them. Doing this would make the code paths more explicit, easier to debug, and possibly slightly more performant, since Arc knows at compile time that there is an object it can access, while lazy_static has to check on every invocation (and has the initialization code nearby, thus polluting the instruction cache).

@grovesNL
Copy link
Collaborator

@kvark will we end up moving globals into Instance anyway?

@kvark
Copy link
Member Author

kvark commented Jan 18, 2020

I don't think we can do what @Kangz described there (without rewriting a large piece, that it). Our approach requires us to have &Global one way or another before calling into wgpu-core methods. In wgpu-native, all we have is raw IDs, so there is nowhere to get the &Global other than the lazy static/global. That is not a problem for Gecko, since it manages the globals explicitly and passes them into wgpu-remote. And it could be better for wgpu-rs, since it's not limited to IDs, which is what my comment above is about. But wgpu-native doesn't look like it can be helped.

@dakom
Copy link
Contributor

dakom commented Jan 20, 2020

Disclaimer: I'm coming more from a "web dev" perspective and do not yet understand the nuance of WebGPU or the lower-level api's like Vulkan/Metal it builds upon, so I may be missing out on exactly what decisions wgpu-rs needs to make that other crates would choose differently.

For the browser target, if I understand the ecosystem correctly I think it's like this:

  • web-sys: direct wrappers generated from the WebIDL. Not very idiomatic Rust.
  • gloo: abstractions over web-sys, providing Rust APIs that are idiomatic but also inherently opinionated. However, it varies between "mid-level" and "high-level" and mid-level APIs are straightforward wrappers.
  • non rustwasm projects (such as this): builds upon web-sys and gloo to provide higher-level functionality

With that in mind, I'd like to ask the same question as the issue here in terms of where the it fits in the above. If it's mostly an issue of making an idiomatic Rust API to work with web-sys, and there aren't too many opinions that would be debated, then perhaps it would be better to focus the browser efforts in gloo? (e.g. a web developer would be "avoiding the middleman" as well - since they'd likely be using gloo as a real-world interface to other web apis like requestAnimationFrame and event listeners)

@grovesNL
Copy link
Collaborator

The idea is that wgpu-rs will support both:

  1. running natively with the wgpu-native crate, which in turn uses the wgpu-core crate
  2. running in the browser with web-sys

In this issue we're talking about the first point: pros/cons of using wgpu-native vs. wgpu-core directly when running natively.

For the second point, I think wrappers such as gloo probably aren't necessary within wgpu itself because it will be easier to use web-sys directly. Although we do want to make it possible to easily use with gloo, like requestAnimationFrame wrappers, but that shouldn't be a problem.

@dakom
Copy link
Contributor

dakom commented Jan 20, 2020

Yeah - wasn't sure which issue to comment on since the web target is also the third bullet on the original post here... forgive me for muddying the waters a bit :) But since we're already talking about it...

I think I understand better now, the plan is for wgpu-rs to not need wgpu at all, not even wgpu-core? i.e. it'd be completely feature-gated out when targeting web?

@grovesNL
Copy link
Collaborator

Yeah, wgpu-rs when targeting the web would use web-sys directly (i.e. wgpu-native and wgpu-core wouldn't be included in the wasm bundle). wgpu-rs when targeting native would use either wgpu-native or wgpu-core.

We will probably still share some common types or helper functions between both web and native.

@aloucks
Copy link
Contributor

aloucks commented Mar 6, 2020

My proposal would be to turn wgpu-rs into a multi-backend library (like gfx-rs is), enforcing the API with traits.

Part of the allure of wgpu-rs (for me) is it's simplicity and minimal use of of traits compared to gfx-hal.

@kvark
Copy link
Member Author

kvark commented Apr 21, 2020

Now that we have wgpu-native in a separate repository, updating the chain of wgpu / wgpu-native / wgpu-rs becomes pretty tedious. I think we should start working on the wgpu-core backend in order to exclude one link from that chain, and coincidentally make it a bit faster.

As for the "native" backend for wgpu-rs, I think what we should do is, instead of linking directly to wgpu-native, is to link to a dynamic native library that implements webgpu-native. This means that we don't explicitly make wgpu-rs dependent on wgpu-native at all. Instead, we use GetProcAddress in a dynamically loaded library, and we are hypothetically compatible to both wgpu-native and Dawn.

A nice side effect is that we don't have to update wgpu-native in sync with everything else. It can have releases less often, and there is a very strong incentive for it to align with Dawn (gfx-rs/wgpu-native#6).

@bors bors bot closed this as completed in 49640d2 Apr 27, 2020
@bors bors bot closed this as completed in #281 Apr 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants