- Notifications
You must be signed in to change notification settings - Fork7
henrybetts/swift-webgpu
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Swift bindings forWebGPU; a new graphics and compute API.
Despite being designed for the web, WebGPU can also be used natively, enabling developers with a modern, cross-platform API, without some of the complexities of lower-level graphics libraries.
Efforts are being made to define a standard native version of the API via ashared header. Note, however, that the specification is still work-in-progress.
Currently, swift-webgpu is based on theDawn implementation, and generated fromdawn.json.
To use swift-webgpu, you'll first need to build Dawn. Assuming you don't need to work on Dawn itself, the easiest way to build it is by following theQuickstart with CMake guide.
swift-webgpu depends on the bundledlibwebgpu_dawn library, which can be built and installed like so;
git clone https://dawn.googlesource.com/dawncd dawncmake -S. -B out/Release -DDAWN_FETCH_DEPENDENCIES=ON -DDAWN_ENABLE_INSTALL=ON -DDAWN_BUILD_SAMPLES=OFF -DCMAKE_BUILD_TYPE=Releasecmake --build out/Release[sudo] cmake --install out/Release
This should install the library and headers to/usr/local/ - this is probably the simplest way to allow Swift to find the library currently.
On macOS, you may need to correct the install name of the library, like so:
sudo install_name_tool -id /usr/local/lib/libwebgpu_dawn.dylib /usr/local/lib/libwebgpu_dawn.dylib
Otherwise you will likely need to place the library next to your executable, or configure rpaths appropriately for your executable.
You may need to manually create a pkg-config file, depending on which tools you are using. For example, runningswift build directly from the command line seems to search/usr/local/ automatically, whereas building with Xcode does not. If you run into this issue, create a file at/usr/local/lib/pkgconfig/webgpu.pc with the following contents;
prefix=/usr/localincludedir=${prefix}/includelibdir=${prefix}/libCflags: -I${includedir}Libs: -L${libdir} -lwebgpu_dawnThis file contains a description of the WebGPU native API. By default, swift-webgpu will look for it in/usr/local/share/dawn/, so you will need to copy it there manually;
sudo install -d /usr/local/share/dawnsudo install src/dawn/dawn.json /usr/local/share/dawn/
Alternatively, you can specify aDAWN_JSON environment variable when building swift-webgpu.
First, clone this project;
git clone https://github.com/henrybetts/swift-webgpu.gitcd swift-webgpuBuild the package (assuming that Dawn is installed and Swift can find it automatically);
swift build -c release
Otherwise, you may need to specify the search paths manually;
DAWN_JSON=/path/to/dawn/src/dawn/dawn.json \swift build -c release \-Xcc -I/path/to/dawn/include \-Xcc -I/path/to/dawn/out/Release/gen/include \-Xlinker -L/path/to/dawn/out/Release/src/dawn/native \-Xlinker -rpath -Xlinker /path/to/dawn/out/Release/src/dawn/native
Finally, run the demos;
cd .build/release./DemoInfo./DemoClearColor./DemoTriangle./DemoCube./DemoBoidsTo use swift-webgpu with Swift Package Manager, add it to yourPackage.swift file's dependencies;
.package(url:"https://github.com/henrybetts/swift-webgpu.git", branch:"main")
Then addWebGPU as a dependency of your target;
.executableTarget( name:"MyApp", dependencies:[.product(name:"WebGPU",package:"swift-webgpu")],),
Import the WebGPU module where needed;
import WebGPUA typical application will start by creating anInstance, requesting anAdapter, and then requesting aDevice. For example;
// create an instanceletinstance=createInstance()// find an adapterletadapter=tryawait instance.requestAdapter()print("Using adapter:\(adapter.info.device)")// create a deviceletdevice=tryawait adapter.requestDevice()
You'll usually want to set an error handler, to log any errors produced by the device;
letuncapturedErrorCallback:UncapturedErrorCallback={ device, errorType, errorMessageinprint("Error (\(errorType)):\(errorMessage)")}letdevice=tryawait adapter.requestDevice(descriptor:.init( uncapturedErrorCallback: uncapturedErrorCallback))
With the device obtained, you can create most of the other types of WebGPU objects. A shader module, for example;
letshaderModule= device.createShaderModule( descriptor:.init( nextInChain:ShaderSourceWgsl( code:""" @vertex fn vertexMain() -> @builtin(position) vec4f { return vec4f(0, 0, 0, 1); } @fragment fn fragmentMain() -> @location(0) vec4f { return vec4f(1, 0, 0, 1); }""")))
Or a render pipeline;
letrenderPipeline= device.createRenderPipeline( descriptor:.init( vertex:VertexState( module: shaderModule, entryPoint:"vertexMain"), fragment:FragmentState( module: shaderModule, entryPoint:"fragmentMain", targets:[ColorTargetState(format:.bgra8Unorm)])))
Most objects are created with a descriptor. In some cases, WebGPU uses a chainable struct pattern to support future extensions or platform specific features. This is indicated by thenextInChain property. (There is scope to improve the ergonomics of this in Swift.)
See the demos for further usage examples.
About
Swift bindings for WebGPU
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.