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

Create instance from worker #2858

Merged

Conversation

JolifantoBambla
Copy link
Contributor

Checklist

  • Run cargo clippy.
  • Run RUSTFLAGS=--cfg=web_sys_unstable_apis cargo clippy --target wasm32-unknown-unknown if applicable.
  • Add change to CHANGELOG.md. See simple instructions inside file.

Connections
#1986
#1466
#2652

Description
On the WebGPU backend, Context::init() uses web_sys::window() to access navigator.gpu.
Since window is not available on web workers this function panics when called from a web worker (#1986).
This is solved by introducing a Global type the result of js_sys::global() is cast to.
This instance of Global is then used to check whether or not window() is defined to determine if the function was called in a worker context or not. If it's in a worker context, it will use WorkerGlobalScope instead of Window to access the gpu property.
I'm relatively new to rust and took the solution from here after stumbling upon this issue in wasm-bindgen, so it's maybe not the prettiest solution.
Let me know if you have a better solution in mind.

Testing
I added logging of adapter.get_info() to the hello example and am about to submit another PR over at https://github.com/gfx-rs/wgpu-rs.github.io that adds an example running the hello example in a webworker.
Note though, that this example doesn't work in Firefox since it doesn't support loading modules in workers. I tested it in Chromium on Linux.

@JolifantoBambla
Copy link
Contributor Author

the example I used to test this is here: gfx-rs/wgpu-rs.github.io#24

@JolifantoBambla
Copy link
Contributor Author

Hey, @cwfitzgerald, I fixed the formatting. Could you maybe try running the checks again? Thanks :)

@cwfitzgerald
Copy link
Member

cwfitzgerald commented Jul 15, 2022

Re-run! If you see failures on nightly only, ignore them, it's an upstream issue.

@JolifantoBambla
Copy link
Contributor Author

Thanks! Looks like it worked :)

Copy link
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment, but otherwise looks good.

@DemiKal
Copy link

DemiKal commented Oct 5, 2022

Do you have an example with Rust code on how you use a web worker with wgpu? This is an interesting approach, but doesn't #1932 already handle this with offscreencanvas? When using a web worker, don't you need an offscreencanvas to begin with rendering? Where do you get it?

Note that I am using 0.12 and maybe 0.13 does something different and I am overlooking something. Anyway, my approach with wgpu 0.12 would be to pass the offscreencanvas to a web worker and init wgpu with that.

//call this from javascript worker
//pass canvas from the main thread to web worker with canvas.transferControlToOffscreen()

#[wasm_bindgen]
pub async fn run(offscreen_canvas: web_sys::OffscreenCanvas) {
    let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY);
    let surface = unsafe { instance.create_surface_from_offscreen_canvas(offscreen_canvas: ) };
    ...
}

Copy link
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@cwfitzgerald cwfitzgerald enabled auto-merge (squash) October 8, 2022 05:25
@cwfitzgerald cwfitzgerald merged commit 3cd9398 into gfx-rs:master Oct 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants