blazor-webassemblywebassemblydirectx-12

WASM and access to the GPU?


I've been trying to work with Blazor WASM to access hardware accelerated functionality supported by most GPUs, but not having much luck.

I have search Stack overflow but have not found much relevant information specific to WASM and more specifically access to the GPU like we have with DirectX (on the Windows side). I was hoping to find some sort of subset but not having much luck.

I realize WASM is supposed to take advantage of "common hardware capabilities" and because of the nature of code isolation there is always going to be some impact to performance in WASM (it'll never be as fast as native calls to DX). With that said, can anyone point me in a direction on how to get access to accelerated graphics via WASM?


Solution

  • You can use the C# bindings for wgpu-native, and it will give you access to the GPU if the host platform runtime supports it.

    If you're targeting a web browser, WebAssembly binaries can use the GPU via browser APIs such as WebGPU or WebGL (currently, you need some Javascript glue code, but there are plans to support direct Web APIs access from WebAssembly without the JS middleman).

    If you're targeting WASI to run outside a Web browser, you need to pick a runtime that supports GPU access or develop your own glue. For example, a simple Rust host application that uses wasmi and wgpu libraries could expose a GPU interface to your wasm application.

    By the way, wgpu itself is a fantastic library and powers Firefox's WebGPU implementation, but it's not limited to a web context; you can deploy native software with it. For example, the Bevy game engine uses it as a GPU abstraction layer for games that run natively.

    They also have some WebAssembly working examples on their website that uses WebGPU through WebAssembly-compiled code, with fallbacks to WebGL 2.

    While the WebGPU specification supports only one language, WGSL, the wgpu library supports many shading languages, so you can use HLSL or GLSL if you want. The library will pick the most suited language for the host platform, namely DirectX for Windows, Metal for Mac/iOS, Vulkan for Linux/Android, and WebGPU/WebGL2 for Web.

    About your question in the comments:

    WebGL roughly maps in functionality with OpenGL ES 2.0, while WebGPU targets modern GPUs with lower-level access, so you have access to modern features such as Compute Shaders. It's a thin wrapper around DirectX12, Metal, and Vulkan.

    The specs are still a work in progress and not a standard yet, but they have been relatively stable for a while, and Chrome launched WebGPU support earlier this year. As far as I know, Mesh shaders are not supported (yet), but the specs include the concept of language extensions, so they might be available eventually.

    Other links that might be useful to you:

    This excellent article about WebGPU contains some resources on using WebAssembly to interact with WebGPU with example implementations in C++ and Rust.

    WebAssembly roadmap: They are currently working on implementing Garbage Collection, which will enable better integration with higher-level, garbage-collected languages such as C#.