swift-webgpu

WebGPU的 Swift 绑定;一个全新的图形和计算 API。

尽管 WebGPU 是为 Web 设计的,但它也可以在本地使用,从而使开发者能够使用现代的、跨平台的 API,而无需处理较低层图形库的一些复杂性。

目前正在努力通过共享头文件定义 API 的标准本地版本。 请注意,该规范仍在开发中。

目前,swift-webgpu 基于 Dawn 实现,并从 dawn.json 生成。

要求

Dawn

要使用 swift-webgpu,您首先需要构建 Dawn。 假设您不需要处理 Dawn 本身,构建它的最简单方法是按照 使用 CMake 快速入门指南进行操作。

swift-webgpu 依赖于捆绑的 libwebgpu_dawn 库,可以通过以下方式构建和安装:

git clone https://dawn.googlesource.com/dawn
cd dawn
cmake -S . -B out/Release -DDAWN_FETCH_DEPENDENCIES=ON -DDAWN_ENABLE_INSTALL=ON -DDAWN_BUILD_SAMPLES=OFF -DCMAKE_BUILD_TYPE=Release
cmake --build out/Release
[sudo] cmake --install out/Release

这应该会将库和头文件安装到 /usr/local/ - 这可能是目前允许 Swift 找到该库的最简单方法。

在 macOS 上,您可能需要更正库的安装名称,如下所示

sudo install_name_tool -id /usr/local/lib/libwebgpu_dawn.dylib /usr/local/lib/libwebgpu_dawn.dylib

否则,您可能需要将库放在可执行文件旁边,或者为您的可执行文件正确配置 rpath。

pkg-config

您可能需要手动创建一个 pkg-config 文件,具体取决于您使用的工具。 例如,直接从命令行运行 swift build 似乎会自动搜索 /usr/local/,而使用 Xcode 构建则不会。 如果您遇到此问题,请在 /usr/local/lib/pkgconfig/webgpu.pc 创建一个文件,内容如下:

prefix=/usr/local
includedir=${prefix}/include
libdir=${prefix}/lib

Cflags: -I${includedir}
Libs: -L${libdir} -lwebgpu_dawn

dawn.json

此文件包含 WebGPU 本地 API 的描述。 默认情况下,swift-webgpu 将在 /usr/local/share/dawn/ 中查找它,因此您需要手动将其复制到那里:

sudo install -d /usr/local/share/dawn
sudo install src/dawn/dawn.json /usr/local/share/dawn/

或者,您可以在构建 swift-webgpu 时指定一个 DAWN_JSON 环境变量。

运行演示

首先,克隆此项目:

git clone https://github.com/henrybetts/swift-webgpu.git
cd swift-webgpu

构建包(假设 Dawn 已安装并且 Swift 可以自动找到它):

swift build -c release

否则,您可能需要手动指定搜索路径:

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

最后,运行演示:

cd .build/release
./DemoInfo
./DemoClearColor
./DemoTriangle
./DemoCube
./DemoBoids

安装

要将 swift-webgpu 与 Swift Package Manager 一起使用,请将其添加到您的 Package.swift 文件的依赖项中:

.package(url: "https://github.com/henrybetts/swift-webgpu.git", branch: "main")

然后添加 WebGPU 作为目标的依赖项:

.executableTarget(
    name: "MyApp",
    dependencies: [.product(name: "WebGPU", package: "swift-webgpu")],
),

基本用法

在需要的地方导入 WebGPU 模块:

import WebGPU

一个典型的应用程序将从创建一个 Instance 开始,请求一个 Adapter,然后请求一个 Device。 例如:

// create an instance
let instance = createInstance()

// find an adapter
let adapter = try await instance.requestAdapter()
print("Using adapter: \(adapter.info.device)")

// create a device
let device = try await adapter.requestDevice()

您通常需要设置一个错误处理程序,以记录设备产生的任何错误:

let uncapturedErrorCallback: UncapturedErrorCallback = { device, errorType, errorMessage in
    print("Error (\(errorType)): \(errorMessage)")
}

let device = try await adapter.requestDevice(descriptor: .init(
    uncapturedErrorCallback: uncapturedErrorCallback
))

获得设备后,您可以创建大多数其他类型的 WebGPU 对象。 例如,一个着色器模块:

let shaderModule = 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);
        }
      """
    )
  )
)

或者一个渲染管线:

let renderPipeline = device.createRenderPipeline(
  descriptor: .init(
    vertex: VertexState(
      module: shaderModule,
      entryPoint: "vertexMain"
    ),
    fragment: FragmentState(
      module: shaderModule,
      entryPoint: "fragmentMain",
      targets: [ColorTargetState(format: .bgra8Unorm)]
    )
  )
)

大多数对象都是使用描述符创建的。 在某些情况下,WebGPU 使用可链接的结构体模式来支持未来的扩展或平台特定功能。 这由 nextInChain 属性指示。(这方面在 Swift 中有改进人机工程学的空间。)

有关更多用法示例,请参见演示。