wgpu-native icon indicating copy to clipboard operation
wgpu-native copied to clipboard

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

Open Kimbatt opened this issue 9 months ago • 4 comments

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)

Kimbatt avatar Sep 28 '23 20:09 Kimbatt

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.

grovesNL avatar Oct 01 '23 01:10 grovesNL

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

Kimbatt avatar Oct 01 '23 10:10 Kimbatt