diff --git a/WebGPUDemo/.sourcekit-lsp/config.json b/WebGPUDemo/.sourcekit-lsp/config.json index b789e87..0833e7b 100644 --- a/WebGPUDemo/.sourcekit-lsp/config.json +++ b/WebGPUDemo/.sourcekit-lsp/config.json @@ -1,5 +1,5 @@ { "swiftPM": { - "swiftSDK": "swift-DEVELOPMENT-SNAPSHOT-2025-06-03-a_wasm" + "swiftSDK": "swift-DEVELOPMENT-SNAPSHOT-2025-08-14-a_wasm-embedded" } } diff --git a/WebGPUDemo/Package.resolved b/WebGPUDemo/Package.resolved index 275b55a..52fa2d6 100644 --- a/WebGPUDemo/Package.resolved +++ b/WebGPUDemo/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "dcbd3e085935ccdf4178dc9a180a6938b0e73f641b50437486b67cc0f3d7c82b", + "originHash" : "8b1d9dc30426eb64ddd75cf52781d1b481727ea88d6e78f3147f650919d2e2a6", "pins" : [ { "identity" : "javascriptkit", "kind" : "remoteSourceControl", "location" : "https://github.com/swiftwasm/JavaScriptKit.git", "state" : { - "branch" : "main", - "revision" : "7eb770ee75b3c1832eef6e7a8a1d46d996fc86ae" + "revision" : "7510b04120bb26a25dd287af71de47065d577c7e", + "version" : "0.33.1" } }, { diff --git a/WebGPUDemo/Package.swift b/WebGPUDemo/Package.swift index a766efb..fed0dee 100644 --- a/WebGPUDemo/Package.swift +++ b/WebGPUDemo/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.1 +// swift-tools-version: 6.2 import PackageDescription @@ -11,7 +11,7 @@ let package = Package( ), .package( url: "https://github.com/swiftwasm/JavaScriptKit.git", - branch: "main", + from: "0.33.1", ), ], targets: [ diff --git a/WebGPUDemo/README.md b/WebGPUDemo/README.md index 519ff7a..69b93ad 100644 --- a/WebGPUDemo/README.md +++ b/WebGPUDemo/README.md @@ -9,6 +9,16 @@ the Swift SDK in the following command to the version that matches your installe swift package --swift-sdk swift-6.2-DEVELOPMENT-SNAPSHOT-2025-06-17-a_wasm js --use-cdn ``` +If you'd like to produce a smaller binary (under 400 kB), you'll have to use +`swift-DEVELOPMENT-SNAPSHOT-2025-08-11` or later development snapshot of the `main` Swift toolchain +branch. Earlier versions (including Swift 6.2) have no support for `async` functions in Embedded Swift, +which is required for WebGPU setup. Use the following command to build with Embedded Swift (update for +your installed toolchain version if needed): + +``` +swift package --swift-sdk swift-DEVELOPMENT-SNAPSHOT-2025-08-11-a_wasm-embedded js --use-cdn -c release +``` + WebGPU is enabled by default in beta and technical preview versions of Safari. Safari 17 and 18 require enabling WebGPU feature flag as shown on the screenshot: diff --git a/WebGPUDemo/Sources/Entrypoint.swift b/WebGPUDemo/Sources/Entrypoint.swift index 4cf2a38..4d0d62e 100644 --- a/WebGPUDemo/Sources/Entrypoint.swift +++ b/WebGPUDemo/Sources/Entrypoint.swift @@ -30,32 +30,34 @@ func fetchImageBitmap(url: String) async throws(JSException) -> ImageBitmap { ) } +typealias DefaultExecutorFactory = JavaScriptEventLoop + @main struct Entrypoint { - static func main() { - JavaScriptEventLoop.installGlobalExecutor() + static func main() async { let gpu = Window.global.navigator.gpu - Task { - do throws(JSException) { - let adapter = try await gpu.requestAdapter()! - let device = try await adapter.requestDevice() - - let renderer = try await Renderer( - device: device, - gpu: gpu, - assets: .init( - shaders: fetchString(url: "Resources/shaders.wgsl"), - model: fetchString(url: "Resources/SwiftLogo/Swift3DLogo.obj"), - albedo: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_BaseColor.png"), - normal: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_Normal.png"), - metalRoughness: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_MetalRoughness.png"), - ), - ) - - draw(renderer: renderer) - } catch { - console.error(data: error.thrownValue) - } + + do throws(JSException) { + // Using promises instead of `async` functions due to https://github.com/swiftlang/swift/issues/83750 + let adapterPromise: JSPromise = gpu.requestAdapter() + let devicePromise = JSPromise(from: try await adapterPromise.value().requestDevice())! + let device = try await GPUDevice(unsafelyWrapping: devicePromise.value().object!) + + let renderer = try await Renderer( + device: device, + gpu: gpu, + assets: .init( + shaders: fetchString(url: "Resources/shaders.wgsl"), + model: fetchString(url: "Resources/SwiftLogo/Swift3DLogo.obj"), + albedo: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_BaseColor.png"), + normal: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_Normal.png"), + metalRoughness: fetchImageBitmap(url: "Resources/SwiftLogo/T_M_swiftLogo_MetalRoughness.png"), + ), + ) + + draw(renderer: renderer) + } catch { + console.error(data: error.thrownValue) } } }