• Stars
    star
    225
  • Rank 171,417 (Top 4 %)
  • Language
    C++
  • License
    BSD 3-Clause "New...
  • Created over 3 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

System headers for interfacing WebGPU from C programs compiled via Emscripten to WebAssembly

WebGPU in Wasm via Emscripten (or Dawn)

This repository contains an Emscripten system library for utilizing WebGPU from a C/C++ codebase, along with a few small C code examples on how to use it.

To utilize the library in your own application, copy the contents of the lib/ directory into your project:

Additionally, if you are using Closure Compiler, also copy the Closure externs file into your project:

and specify the Emscripten linker argument --closure-args=--externs=/path/to/webgpu-closure-externs.js when linking your project.

Then #include "lib_webgpu.h" to access the API, compile in lib_webpgu.cpp and lib_webgpu_cpp20.cpp with the rest of your project files, and finally link with --js-library /absolute/path/to/lib_webgpu.js on the Emscripten command line to include the code. See the provided CMakeLists.txt for example usage.

For your convenience, a forward declaration header is also provided, and can be included with #include "lib_webgpu_fwd.h".

Using WebGPU via Dawn

It is also possible to target WebGPU outside the browser via Dawn. When doing so, also compile the dawn-specific file with your project:

TODO: add more instructions about targeting Dawn natively.

Implementation Status

The repository was last updated to be up to date with the WebGPU specification as of ๐Ÿ—“ 13th of December 2022.

Features and Design

This bindings library is developed with the following:

๐Ÿ“ 1:1 API mapping with JS

For the most parts, the JavaScript side WebGPU API is directly mapped 1:1 over to WebAssembly side to enable developers to write WebGPU code in C/C++ by using the official specification IDL as reference.

Type names and structs follow a naming convention WGpu*, mapped from JS names by transforming GPUAdapter -> WGpuAdapter. API function names use a prefix wgpu_*, and are mapped using the convention GPUCanvasContext.configure(...) -> wgpu_canvas_context_configure(canvasContext, ...). Enums and #defines use a prefix WGPU_, e.g. GPUPowerPreference -> WGPU_POWER_PREFERENCE.

A few exceptions to this are done in the name of accommodating better Wasm<->JS language marshalling, noted where present in the lib_webgpu.h header.

๐Ÿš€ Best performance and Minimal code size

The primary design goal of the library is to provide absolutely best runtime speed and minimal generated code size overhead, carefully shaving down every individual byte possible. The intent is to enable using this library in extremely code size constrained deployment scenarios.

The library is implemented very C-like, void of high-level JavaScript abstractions, and manually tuned to produce smallest code possible. This has been observed to work best to provide the thinnest JS<->Wasm language marshalling layer that does not get in the way.

๐Ÿ—‘ Mindful about JS garbage generation

Another design goal is to minimize the amount of JS temporary garbage that is generated. Unlike WebGL, WebGPU API is unfortunately quite trashy, and it is not possible to operate WebGPU without generating some runaway garbage each rendered frame. However, the binding layer itself minimizes the amount of generated garbage as much as possible.

If there is a tradeoff between generated garbage, code size, or runtime speed, build flags are provided to favor one over the other. (currently there aren't any, but this is expected to change)

๐Ÿ“œ Custom API for marshalling buffer data

Some WebGPU features do not interop well between JS and Wasm if translated 1:1. Buffer mapping is one of these features. To help JS<->Wasm interop, this library provides custom functions wgpu_buffer_read_mapped_range() and wgpu_buffer_write_mapped_range() that do not exist in the official WebGPU specification.

For an example of how this works in practice, see the sample vertex_buffer/vertex_buffer.c

๐Ÿ”Œ Extensions for binding with other JS APIs

To enable easy uploading of image URLs to WebGPU textures, an extension function wgpu_load_image_bitmap_from_url_async() is provided. For an example of this, see the sample texture/texture.c

๐Ÿšฆ Asyncify support

When building with Emscripten linker flag -sASYNCIFY=1, the following extra functions are available:

  • navigator_gpu_request_adapter_sync and navigator_gpu_request_adapter_sync_simple: Synchronously request a GPUAdapter.
  • wgpu_adapter_request_device_sync and wgpu_adapter_request_device_sync_simple: Synchronously request a GPUDevice.
  • wgpu_buffer_map_sync: Synchronously map a GPUBuffer.

These functions enable a synchronous variant of the _async functions offered in the WebGPU specification. These can be useful for prototyping and test suites etc., though it is not recommended to try to ship a game that uses Asyncify, because it has a very high latency overhead, and breaks ordering and re-entrancy semantics of traditional code execution.

๐Ÿ–ฅ 2GB + 4GB + Wasm64 support

Currently both 2GB and 4GB build modes are supported. Wasm64 is also planned to be supported as soon as it becomes available in web browsers.

๐Ÿšฆ Requirements

Wasm_Webgpu requires Emscripten 3.1.35 or newer.

By default the JS library provides polyfills for browser backwards compatibility for scenarios where WebGPU library might be included in a build that co-targets both WebGL and WebGPU simultaneously. To opt out from polyfills, pass the Emscripten linker flag -jsDWEBGPU_NO_BW_COMPAT=1.

๐Ÿงช Samples

Several test cases are available under the samples/ subdirectory.

Don't expect flashy demos. The test cases exercise features relevant to data marshalling between WebAssembly and JavaScript languages, and are not intended to showcase fancy graphical effects.

To build the samples, first install Emscripten via Emsdk, then enter Emsdk command line environment (emsdk_env), and type

cd path/to/wasm_webgpu
mkdir build
cd build
emcmake cmake ../samples -DCMAKE_BUILD_TYPE=Debug # Or MinSizeRel, RelWithDebInfo or Release
make -j

On Windows, the last make command is not available, so either install Mingw32-make via emsdk and run mingw32-make -j, or install Ninja via emsdk, then pass -G Ninja to the emcmake command line, and then run ninja instead of make.

clear_screen

clear_screen

For the smallest Clear Screen "hello world" example, see clear_screen.c/clear_screen.c.

There is also an Emscripten ASYNCIFY-enabled variant of the same demo, at clear_screen.c/clear_screen_sync.c.

failing_shader_compilation

The demo failing_shader_compilation/failing_shader_compilation.c tests handling of shader compilation errors.

gpu_oom

The demo gpu_oom/gpu_oom.c exhausts the GPU VRAM, testing handling of GPU OOM events.

hello_triangle

hello_triangle

The demo hello_triangle/hello_triangle_minimal.c contains the smallest triangle rendering demo.

The variant hello_triangle/hello_triangle_verbose.c offers the same, but with verbose debug logging.

texture

texture

The sample texture/texture.c tests the wgpu_load_image_bitmap_from_url_async() API.

vertex_buffer

vertex_buffer

The test vertex_buffer/vertex_buffer.c shows an example of how to map a GPU buffer and use the function wgpu_buffer_write_mapped_range().

๐Ÿšง TODOs

The following features are planned:

  • Rendering from a Web Worker support (e.g. Emscripten's -pthread and -sPROXY_TO_PTHREAD=1 linker flags)
  • Multithreading support when WebGPU spec and browsers enable WebGPU multithreaded rendering
  • When more test cases become available, examine how to reduce generated garbage further by e.g. pooling arrays and descriptors.
  • Wasm64 build mode support

More Repositories

1

fbcp-ili9341

A blazing fast display driver for SPI-based LCD displays for Raspberry Pi A, B, 2, 3, 4 and Zero
C++
1,483
star
2

RectangleBinPack

Source code for performing 2d rectangular bin packing.
C++
845
star
3

MathGeoLib

A C++ library for linear algebra and geometry manipulation for computer graphics.
C++
676
star
4

kNet

C++
112
star
5

vs-tool

Visual Studio 2010 plugin to integrate MinGW, Clang and Emscripten to the VS IDE.
C#
85
star
6

gowin_flipflop_drainer

A test case for stress testing Tang Nano 4K and 9K and Primer 20K (Gowin FPGAs)
Verilog
18
star
7

ST7735R

A fast low level Arduino Uno compatible graphics library for the 160x128 pixel 16-bit color TFT LCD display that uses the ST7735R chip.
C
18
star
8

sc2-uqm

The Ur-Quan Masters
C
12
star
9

emrun

Self-sufficient tools for command line automation of browser and Firefox OS tasks. Often used with Emscripten.
Python
10
star
10

webgl-debugger

WebGL API call trace recording and debugging tool
Python
10
star
11

gowin_fpga_code_generators

Interactive code generators for Gowin FPGAs
HTML
9
star
12

HDMI_testikuva

Sipeed Tang Nano 4K FPGA implementation of the static tuning picture I watched on TV as a kid.
Verilog
9
star
13

audio_test_suite

Test files for audio playback with different types of audio effects
HTML
7
star
14

GitSourceMonitor

A command-line tool written in C# that automatically generates checkpoints for the SourceMonitor software.
C#
6
star
15

tiny_chess

A tiny GLES2 based Chess program
C++
6
star
16

crt_terminator

Repository for CRT Terminator hardware related development. https://oummg.com/
C++
5
star
17

KEEN70HZ

Tech demo mod of Commander Keen 4 v1.4 Shareware running smooth at 70fps
C
5
star
18

MacAppFix

Automates the invokation of install_name_tool to fix broken .dylib lookups in OSX app bundles.
C++
5
star
19

emscripten-freetype

C
4
star
20

last_frontier

Tech demo about using WebTransport datagrams to implement a low latency action game in a web browser
HTML
4
star
21

emgc

Toy garbage collector for Emscripten/WebAssembly
C
4
star
22

AngelscriptGenerator

C
3
star
23

emmaster

Emscripten CI build master
Python
3
star
24

crunch-emscripten

A mirror of https://code.google.com/p/crunch/ which builds on Windows, Linux and OSX hosts for Emscripten.
C++
3
star
25

VIDMODE

A small real mode DOS program to test different VGA graphics adapter video mode timings.
C++
2
star
26

emslave

Unit test slave configuration for Emscripten compiler buildbot slaves.
Python
2
star
27

gowin_array_handling_bug

A test case of a possible(?) array handling bug in Gowin synthesizer
Verilog
2
star
28

TheExplorer2D

Project checkout of Unity 2D Game Kit - https://assetstore.unity.com/packages/essentials/tutorial-projects/2d-game-kit-107098
C#
2
star
29

64kalloc

A 64KB aligned memory allocator for DOS Sound Blaster DMA programming
C
1
star
30

CodeStructure

A C# library project that reads in doxygen-generated code structure XML description files.
C#
1
star
31

webgl_render_test

Small example of WebGL rendering with Emscripten & WebAssembly
C
1
star
32

tgifelse

Programming puzzles
HTML
1
star
33

Raspberry-Pi-DMA-Example

Simplest example of copying memory from one region to another using DMA in userland
C
1
star
34

AOC2022

Advent of Code 2022 on Borland Turbo C++ 3.0
C++
1
star
35

EmbindGenerator

A C# program that produces embind bindings code automatically from .cpp files.
C#
1
star
36

wasm_feature_test

Code snippets for feature testing availability of different WebAssembly-related subfeatures
HTML
1
star
37

js-main-thread-atomics-wait

Polyfill for enabling Atomics.wait() on the main browser thread
JavaScript
1
star