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

Compile error with --target=wasm32-unknown-unknown #298

Open
Kimbatt opened this issue Sep 28, 2023 · 4 comments
Open

Compile error with --target=wasm32-unknown-unknown #298

Kimbatt opened this issue Sep 28, 2023 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@Kimbatt
Copy link

Kimbatt commented Sep 28, 2023

Since commit 07728a35c5e0736c3cec99e7fd9ec33161dbc6fb, webassembly builds fail with this error:

error[E0277]: `(dyn FnOnce(std::result::Result<(), BufferAccessError>) + 'static)` cannot be shared between threads safely
    --> src\lib.rs:4120:41
     |
4120 |             handle_error_fatal(context, cause, "wgpuDevicePoll");
     |             ------------------          ^^^^^ `(dyn FnOnce(std::result::Result<(), BufferAccessError>) + 'static)` cannot be shared between threads safely
     |             |
     |             required by a bound introduced by this call
     |

(and more similar errors)

It seems like the error happens because in lib.rs, the handle_error_fatal and handle_error functions require the cause parameter to be Send + Sync, but this should only be required in non-webassembly builds (in wgpu-core/src/error.rs, ContextError doesn't have this requirement in webassembly builds).

Adding cfg-s to disable the requirements in webassembly builds seems to fix the issue.
(lib.rs, the cause parameter of error handling functions, and the variants of Error enum)

@rajveermalviya rajveermalviya added the help wanted Extra attention is needed label Sep 30, 2023
@grovesNL
Copy link
Collaborator

grovesNL commented Oct 1, 2023

Hi @Kimbatt! How do you use wgpu-native with the wasm32-unknown-unknown target? I think we could probably fix this either way, but the wasm32-unknown-unknown target is usually handled by using wgpu directly instead of wgpu-native.

@Kimbatt
Copy link
Author

Kimbatt commented Oct 1, 2023

Hi,
I have a c++ desktop application, which uses wgpu-native for rendering. I'd like to compile this application to webassembly, using emscripten.
I already managed to compile it without using wgpu-native, using webgpu (this is supported by emscripten). But the browser support for webgpu isn't really great, it'd be much better if I could use webgl2 with wgpu-native.
I've seen the examples for wgpu which use webgl2, so I think this should be possible to do.
So my final goal is compiling a c++ application to webassembly, with webgl2 support, using wgpu-native.

Maybe I don't even need wasm32-unknown-unknown; I found wasm32-unknown-emscripten, which got me a bit closer to the solution. (this also has the compile errors I've mentioned above, in addition to some additional errors)

I compiled wgpu-native to a static library, then I linked that to the c++ application.
But I got linker errors for that (not related to wgpu-native):

wasm-ld: error: /home/kimbatt/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/lto/libc.a(htons.o): attempt to add bitcode file after LTO.
... (more similar errors)

I found a workaround, adding this to the linker flags fixed it.
There was another linker error:

wasm-ld: error: ../../libs/wgpu-native-wasm/libwgpu_native.a(wgpu_hal-f216b50e84138b60.wgpu_hal.575218313497e306-cgu.11.rcgu.o): undefined symbol: eglGetPlatformDisplay

I added an empty c++ function with this name to "fix" this.
After this, it finally compiled.
At runtime, I'm getting this error:

TestApp.js:8 thread '<unnamed>' panicked at 'Error: Unsupported Surface', src/conv.rs:1299:5

It seems like map_surface is not implemented for emscripten.
I tried to implement it, but raw_window_handle::WebWindowHandle only has an id: u32 field, while the WGPUSurfaceDescriptorFromCanvasHTMLSelector has a string (char*) selector, so I'm not sure what to do here.
Also, I'm getting validation errors after running:

Validation Error
Caused by:
    No suitable adapter found

@rafaelbeckel
Copy link

Hi @Kimbatt, did you manage to solve this problem? I've found this validation error recently in upstream Rust wgpu, and it seems that for WebGL targets, it's just a matter of creating a surface before creating the adapter, even if you never use the surface.

This is the relevant discussion: gfx-rs/wgpu#5190

It worked for me in my pure Rust project, so it's very likely it will work for yours.

I'm now facing the challenge of compiling C and Rust together under the same binary for wasm32-unknown-unknown and going down the rabbit hole of the current state of the ecosystem. There has been significant progress on that front by the Rust compiler and wasm-bindgen teams, but as of today, it seems wasm32-unknown-emscripten and wasm32-wasi are still the only way to link C and Rust together, so I'm considering linking against wgpu-native instead using a C compiler and emscriptem directly.

@Kimbatt
Copy link
Author

Kimbatt commented May 24, 2024

If I remember correctly, the validation issue happened because I didn't use the correct version of the header in the c++ program. I also switched to wasm32-unknown-emscripten.
For the other part, I've added a new parameter to map_surface for wasm32, and just created an empty display handle and window handle. But this code has changed in wgpu-native since then, and I haven't tried the new version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants