Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/henrybetts/swift-webgpu
Swift bindings for WebGPU
https://github.com/henrybetts/swift-webgpu
dawn gpu graphics swift webgpu
Last synced: 3 months ago
JSON representation
Swift bindings for WebGPU
- Host: GitHub
- URL: https://github.com/henrybetts/swift-webgpu
- Owner: henrybetts
- License: mit
- Created: 2021-03-23T12:56:45.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-07-08T20:34:01.000Z (4 months ago)
- Last Synced: 2024-07-09T01:46:54.691Z (4 months ago)
- Topics: dawn, gpu, graphics, swift, webgpu
- Language: Swift
- Homepage:
- Size: 310 KB
- Stars: 78
- Watchers: 4
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# swift-webgpu
Swift bindings for [WebGPU](https://gpuweb.github.io/gpuweb/); 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 a [shared header](https://github.com/webgpu-native/webgpu-headers). Note, however, that the specification is still work-in-progress.
Currently, swift-webgpu is based on the [Dawn](https://dawn.googlesource.com/dawn/) implementation, and generated from [dawn.json](https://dawn.googlesource.com/dawn/+/refs/heads/main/src/dawn/dawn.json).
## Requirements
### Dawn
To use swift-webgpu, you'll first need to build Dawn. See Dawn's [documentation](https://dawn.googlesource.com/dawn/+/HEAD/docs/building.md) to get started.
swift-webgpu depends on the bundled `libwebgpu_dawn` library, which can be built and installed like so;
```sh
mkdir -p out/Release
cd out/Release
cmake -DCMAKE_BUILD_TYPE=Release -DDAWN_ENABLE_INSTALL=1 -DDAWN_BUILD_SAMPLES=0 -GNinja ../..
ninja
sudo ninja install
```This should install the library and headers to `/usr/local/` - this is probably the simplest way to allow Swift to find the library currently.
#### pkg-config
You may need to manually create a pkg-config file, depending on which tools you are using. For example, running `swift 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/local
includedir=${prefix}/include
libdir=${prefix}/libCflags: -I${includedir}
Libs: -L${libdir} -lwebgpu_dawn
```#### dawn.json
This 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;
```sh
sudo install -d /usr/local/share/dawn
sudo install ../../src/dawn/dawn.json /usr/local/share/dawn/
```Alternatively, you can specify a `DAWN_JSON` environment variable when building swift-webgpu.
## Running the Demos
First, clone this project;
```sh
git clone https://github.com/henrybetts/swift-webgpu.git
cd swift-webgpu
```Build the package (assuming that Dawn is installed and Swift can find it automatically);
```sh
swift build -c release
```Otherwise, you may need to specify the search paths manually;
```sh
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;
```sh
cd .build/release
./DemoInfo
./DemoClearColor
./DemoTriangle
./DemoCube
./DemoBoids
```## Installation
To use swift-webgpu with Swift Package Manager, add it to your `Package.swift` file's dependencies;
```swift
.package(url: "https://github.com/henrybetts/swift-webgpu.git", branch: "main")
```Then add `WebGPU` as a dependency of your target;
```swift
.executableTarget(
name: "MyApp",
dependencies: [.product(name: "WebGPU", package: "swift-webgpu")],
),
```## Basic Usage
Import the WebGPU module where needed;
```swift
import WebGPU
```A typical application will start by creating an `Instance`, requesting an `Adapter`, and then requesting a `Device`. For example;
```swift
// create an instance
let instance = createInstance()// find an adapter
let adapter = try await instance.requestAdapter()
print("Using adapter: \(adapter.properties.name)")// create a device
let device = try await adapter.requestDevice()
```You'll usually want to set an error handler, to log any errors produced by the device;
```swift
device.setUncapturedErrorCallback { (errorType, errorMessage) in
print("Error (\(errorType)): \(errorMessage)")
}
```With the device obtained, you can create most of the other types of WebGPU objects. A shader module, for example;
```swift
let shaderModule = device.createShaderModule(
descriptor: .init(
nextInChain: ShaderModuleWgslDescriptor(
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;
```swift
let renderPipeline = 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 the `nextInChain` property. (There is scope to improve the ergonomics of this in Swift.)
See the demos for further usage examples.