Skip to content

Commit a2423c8

Browse files
authored
Support Embedded Swift in WebGPUDemo (#44)
This adopts new `DefaultExecutorFactory`, which means we can mark `main` entrypoint as `async`. Due to swiftlang/swift#83750 we have to use `JSPromise`-returning functions from WebAPIKit, but otherwise this is now fully compatible with Embedded Swift. Final binary size with full optimization: 390.5 kB.
1 parent 97aabc5 commit a2423c8

File tree

5 files changed

+41
-29
lines changed

5 files changed

+41
-29
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"swiftPM": {
3-
"swiftSDK": "swift-DEVELOPMENT-SNAPSHOT-2025-06-03-a_wasm"
3+
"swiftSDK": "swift-DEVELOPMENT-SNAPSHOT-2025-08-14-a_wasm-embedded"
44
}
55
}

WebGPUDemo/Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

WebGPUDemo/Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version: 6.1
1+
// swift-tools-version: 6.2
22

33
import PackageDescription
44

@@ -11,7 +11,7 @@ let package = Package(
1111
),
1212
.package(
1313
url: "https://github.com/swiftwasm/JavaScriptKit.git",
14-
branch: "main",
14+
from: "0.33.1",
1515
),
1616
],
1717
targets: [

WebGPUDemo/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ the Swift SDK in the following command to the version that matches your installe
99
swift package --swift-sdk swift-6.2-DEVELOPMENT-SNAPSHOT-2025-06-17-a_wasm js --use-cdn
1010
```
1111

12+
If you'd like to produce a smaller binary (under 400 kB), you'll have to use
13+
`swift-DEVELOPMENT-SNAPSHOT-2025-08-11` or later development snapshot of the `main` Swift toolchain
14+
branch. Earlier versions (including Swift 6.2) have no support for `async` functions in Embedded Swift,
15+
which is required for WebGPU setup. Use the following command to build with Embedded Swift (update for
16+
your installed toolchain version if needed):
17+
18+
```
19+
swift package --swift-sdk swift-DEVELOPMENT-SNAPSHOT-2025-08-11-a_wasm-embedded js --use-cdn -c release
20+
```
21+
1222
WebGPU is enabled by default in beta and technical preview versions of Safari. Safari 17 and 18 require enabling
1323
WebGPU feature flag as shown on the screenshot:
1424

WebGPUDemo/Sources/Entrypoint.swift

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,34 @@ func fetchImageBitmap(url: String) async throws(JSException) -> ImageBitmap {
3030
)
3131
}
3232

33+
typealias DefaultExecutorFactory = JavaScriptEventLoop
34+
3335
@main
3436
struct Entrypoint {
35-
static func main() {
36-
JavaScriptEventLoop.installGlobalExecutor()
37+
static func main() async {
3738
let gpu = Window.global.navigator.gpu
38-
Task {
39-
do throws(JSException) {
40-
let adapter = try await gpu.requestAdapter()!
41-
let device = try await adapter.requestDevice()
42-
43-
let renderer = try await Renderer(
44-
device: device,
45-
gpu: gpu,
46-
assets: .init(
47-
shaders: fetchString(url: "Resources/shaders.wgsl"),
48-
model: fetchString(url: "Resources/SwiftLogo/Swift3DLogo.obj"),
49-
albedo: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_BaseColor.png"),
50-
normal: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_Normal.png"),
51-
metalRoughness: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_MetalRoughness.png"),
52-
),
53-
)
54-
55-
draw(renderer: renderer)
56-
} catch {
57-
console.error(data: error.thrownValue)
58-
}
39+
40+
do throws(JSException) {
41+
// Using promises instead of `async` functions due to https://github.com/swiftlang/swift/issues/83750
42+
let adapterPromise: JSPromise = gpu.requestAdapter()
43+
let devicePromise = JSPromise(from: try await adapterPromise.value().requestDevice())!
44+
let device = try await GPUDevice(unsafelyWrapping: devicePromise.value().object!)
45+
46+
let renderer = try await Renderer(
47+
device: device,
48+
gpu: gpu,
49+
assets: .init(
50+
shaders: fetchString(url: "Resources/shaders.wgsl"),
51+
model: fetchString(url: "Resources/SwiftLogo/Swift3DLogo.obj"),
52+
albedo: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_BaseColor.png"),
53+
normal: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_Normal.png"),
54+
metalRoughness: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_MetalRoughness.png"),
55+
),
56+
)
57+
58+
draw(renderer: renderer)
59+
} catch {
60+
console.error(data: error.thrownValue)
5961
}
6062
}
6163
}

0 commit comments

Comments
 (0)