From 340448cf4c9b79e26342cee0db1a602ecca9cc9f Mon Sep 17 00:00:00 2001 From: a dinosaur Date: Mon, 16 Jun 2025 07:14:26 +1000 Subject: [PATCH] swift: Linux Support --- Package.swift | 65 ++++++++++++++++++------------- src/swift/Lesson10/lesson10.swift | 2 +- src/swift/Lesson2/lesson2.swift | 2 +- src/swift/Lesson3/lesson3.swift | 2 +- src/swift/Lesson4/lesson4.swift | 2 +- src/swift/Lesson5/lesson5.swift | 2 +- src/swift/Lesson6/lesson6.swift | 4 +- src/swift/Lesson7/lesson7.swift | 2 +- src/swift/Lesson8/lesson8.swift | 2 +- src/swift/Lesson9/lesson9.swift | 8 ++-- src/swift/NeHe/Matrix.swift | 1 + src/swift/NeHe/NeHeContext.swift | 4 +- 12 files changed, 53 insertions(+), 43 deletions(-) diff --git a/Package.swift b/Package.swift index 37babd0..7110083 100644 --- a/Package.swift +++ b/Package.swift @@ -2,6 +2,19 @@ import PackageDescription +func resources(shaders: [String], data: [String] = []) -> [PackageDescription.Resource] { + shaders.flatMap { name in +#if os(macOS) + [ .process("../../../data/shaders/\(name).metallib") ] +#else + [ + .process("../../../data/shaders/\(name).vtx.spv"), + .process("../../../data/shaders/\(name).frg.spv"), + ] +#endif + } + data.map { resource in .process("../../../data/\(resource)") } +} + let package = Package( name: "NeHe-SDL_GPU", products: [ @@ -18,38 +31,34 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/GayPizzaSpecifications/SDL3Swift.git", branch: "main"), + .package(url: "https://github.com/keyvariable/kvSIMD.swift.git", .upToNextMajor(from: "1.1.0")), ], targets: [ .target( name: "NeHe", - dependencies: [ .product(name: "SDLSwift", package: "SDL3Swift") ], + dependencies: [ + .product(name: "SDLSwift", package: "SDL3Swift"), + .product(name: "kvSIMD", package: "kvSIMD.swift"), + ], path: "src/swift/NeHe"), .executableTarget(name: "Lesson1", dependencies: [ "NeHe" ], path: "src/swift/Lesson1"), - .executableTarget(name: "Lesson2", dependencies: [ "NeHe" ], path: "src/swift/Lesson2", resources: [ - .process("../../../data/shaders/lesson2.metallib") ]), - .executableTarget(name: "Lesson3", dependencies: [ "NeHe" ], path: "src/swift/Lesson3", resources: [ - .process("../../../data/shaders/lesson3.metallib") ]), - .executableTarget(name: "Lesson4", dependencies: [ "NeHe" ], path: "src/swift/Lesson4", resources: [ - .process("../../../data/shaders/lesson3.metallib") ]), - .executableTarget(name: "Lesson5", dependencies: [ "NeHe" ], path: "src/swift/Lesson5", resources: [ - .process("../../../data/shaders/lesson3.metallib") ]), - .executableTarget(name: "Lesson6", dependencies: [ "NeHe" ], path: "src/swift/Lesson6", resources: [ - .process("../../../data/shaders/lesson6.metallib"), - .process("../../../data/NeHe.bmp") ]), - .executableTarget(name: "Lesson7", dependencies: [ "NeHe" ], path: "src/swift/Lesson7", resources: [ - .process("../../../data/shaders/lesson6.metallib"), - .process("../../../data/shaders/lesson7.metallib"), - .process("../../../data/Crate.bmp") ]), - .executableTarget(name: "Lesson8", dependencies: [ "NeHe" ], path: "src/swift/Lesson8", resources: [ - .process("../../../data/shaders/lesson7.metallib"), - .process("../../../data/shaders/lesson8.metallib"), - .process("../../../data/Glass.bmp") ]), - .executableTarget(name: "Lesson9", dependencies: [ "NeHe" ], path: "src/swift/Lesson9", resources: [ - .process("../../../data/shaders/lesson9.metallib"), - .process("../../../data/Star.bmp") ]), - .executableTarget(name: "Lesson10", dependencies: [ "NeHe" ], path: "src/swift/Lesson10", resources: [ - .process("../../../data/shaders/lesson6.metallib"), - .process("../../../data/Mud.bmp"), - .process("../../../data/World.txt") ]), - ], + .executableTarget(name: "Lesson2", dependencies: [ "NeHe" ], path: "src/swift/Lesson2", resources: + resources(shaders: [ "lesson2" ])), + .executableTarget(name: "Lesson3", dependencies: [ "NeHe" ], path: "src/swift/Lesson3", resources: + resources(shaders: [ "lesson3" ])), + .executableTarget(name: "Lesson4", dependencies: [ "NeHe" ], path: "src/swift/Lesson4", resources: + resources(shaders: [ "lesson3" ])), + .executableTarget(name: "Lesson5", dependencies: [ "NeHe" ], path: "src/swift/Lesson5", resources: + resources(shaders: [ "lesson3" ])), + .executableTarget(name: "Lesson6", dependencies: [ "NeHe" ], path: "src/swift/Lesson6", resources: + resources(shaders: [ "lesson6" ], data: [ "NeHe.bmp" ])), + .executableTarget(name: "Lesson7", dependencies: [ "NeHe" ], path: "src/swift/Lesson7", resources: + resources(shaders: [ "lesson6", "lesson7" ], data: [ "Crate.bmp" ])), + .executableTarget(name: "Lesson8", dependencies: [ "NeHe" ], path: "src/swift/Lesson8", resources: + resources(shaders: [ "lesson7", "lesson8" ], data: [ "Glass.bmp" ])), + .executableTarget(name: "Lesson9", dependencies: [ "NeHe" ], path: "src/swift/Lesson9", resources: + resources(shaders: [ "lesson9" ], data: [ "Star.bmp" ])), + .executableTarget(name: "Lesson10", dependencies: [ "NeHe" ], path: "src/swift/Lesson10", resources: + resources(shaders: [ "lesson6" ], data: [ "Mud.bmp", "World.txt" ])), + ] ) diff --git a/src/swift/Lesson10/lesson10.swift b/src/swift/Lesson10/lesson10.swift index b00b04e..e6a33b7 100644 --- a/src/swift/Lesson10/lesson10.swift +++ b/src/swift/Lesson10/lesson10.swift @@ -119,7 +119,7 @@ struct Lesson10: AppDelegate var samplers = [OpaquePointer?](repeating: nil, count: 3) var texture: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) var blending = false var filter = 0 diff --git a/src/swift/Lesson2/lesson2.swift b/src/swift/Lesson2/lesson2.swift index b69d593..a734a2e 100644 --- a/src/swift/Lesson2/lesson2.swift +++ b/src/swift/Lesson2/lesson2.swift @@ -34,7 +34,7 @@ struct Lesson2: AppDelegate var pso: OpaquePointer? = nil var vtxBuffer: OpaquePointer? = nil var idxBuffer: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) mutating func `init`(ctx: inout NeHeContext) throws(NeHeError) { diff --git a/src/swift/Lesson3/lesson3.swift b/src/swift/Lesson3/lesson3.swift index a9a2995..5584b4d 100644 --- a/src/swift/Lesson3/lesson3.swift +++ b/src/swift/Lesson3/lesson3.swift @@ -45,7 +45,7 @@ struct Lesson3: AppDelegate var pso: OpaquePointer? = nil var vtxBuffer: OpaquePointer? = nil var idxBuffer: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) mutating func `init`(ctx: inout NeHeContext) throws(NeHeError) { diff --git a/src/swift/Lesson4/lesson4.swift b/src/swift/Lesson4/lesson4.swift index a9aaf41..5407b98 100644 --- a/src/swift/Lesson4/lesson4.swift +++ b/src/swift/Lesson4/lesson4.swift @@ -45,7 +45,7 @@ struct Lesson4: AppDelegate var pso: OpaquePointer? = nil var vtxBuffer: OpaquePointer? = nil var idxBuffer: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) var rotTri: Float = 0.0, rotQuad: Float = 0.0 diff --git a/src/swift/Lesson5/lesson5.swift b/src/swift/Lesson5/lesson5.swift index f750f24..6e953b6 100644 --- a/src/swift/Lesson5/lesson5.swift +++ b/src/swift/Lesson5/lesson5.swift @@ -75,7 +75,7 @@ struct Lesson5: AppDelegate var pso: OpaquePointer? = nil var vtxBuffer: OpaquePointer? = nil var idxBuffer: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) var rotTri: Float = 0.0, rotQuad: Float = 0.0 diff --git a/src/swift/Lesson6/lesson6.swift b/src/swift/Lesson6/lesson6.swift index 422332e..417c5df 100644 --- a/src/swift/Lesson6/lesson6.swift +++ b/src/swift/Lesson6/lesson6.swift @@ -70,7 +70,7 @@ struct Lesson6: AppDelegate var idxBuffer: OpaquePointer? = nil var sampler: OpaquePointer? = nil var texture: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) var rot: SIMD3 = .init(repeating: 0.0) @@ -217,7 +217,7 @@ struct Lesson6: AppDelegate // Push shader uniforms var modelViewProj = self.projection * model - SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, UInt32(MemoryLayout.size)) + SDL_PushGPUVertexUniformData(cmd, 0, &modelViewProj, UInt32(MemoryLayout.size)) // Draw textured cube SDL_DrawGPUIndexedPrimitives(pass, UInt32(Self.indices.count), 1, 0, 0, 0) diff --git a/src/swift/Lesson7/lesson7.swift b/src/swift/Lesson7/lesson7.swift index 478e978..1f7ce54 100644 --- a/src/swift/Lesson7/lesson7.swift +++ b/src/swift/Lesson7/lesson7.swift @@ -72,7 +72,7 @@ struct Lesson7: AppDelegate var idxBuffer: OpaquePointer? = nil var samplers = [OpaquePointer?](repeating: nil, count: 3) var texture: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) struct Light { let ambient: SIMD4, diffuse: SIMD4, position: SIMD4 } diff --git a/src/swift/Lesson8/lesson8.swift b/src/swift/Lesson8/lesson8.swift index 344d10d..36a16e4 100644 --- a/src/swift/Lesson8/lesson8.swift +++ b/src/swift/Lesson8/lesson8.swift @@ -72,7 +72,7 @@ struct Lesson8: AppDelegate var idxBuffer: OpaquePointer? = nil var samplers = [OpaquePointer?](repeating: nil, count: 3) var texture: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) struct Light { let ambient: SIMD4, diffuse: SIMD4, position: SIMD4 } diff --git a/src/swift/Lesson9/lesson9.swift b/src/swift/Lesson9/lesson9.swift index 557184b..ed2db39 100644 --- a/src/swift/Lesson9/lesson9.swift +++ b/src/swift/Lesson9/lesson9.swift @@ -52,7 +52,7 @@ struct Lesson9: AppDelegate struct Instance { - let model: matrix_float4x4 + let model: simd_float4x4 let color: SIMD4 } @@ -85,7 +85,7 @@ struct Lesson9: AppDelegate var sampler: OpaquePointer? = nil var texture: OpaquePointer? = nil - var projection: matrix_float4x4 = .init(1.0) + var projection: simd_float4x4 = .init(1.0) var twinkle = false var stars: [Star] = [] @@ -240,7 +240,7 @@ struct Lesson9: AppDelegate var instanceIDX = 0 for (starIDX, star) in self.stars.enumerated() { - var model = matrix_float4x4.translation(.init(0.0, 0.0, self.zoom)) + var model = simd_float4x4.translation(.init(0.0, 0.0, self.zoom)) model.rotate(angle: self.tilt, axis: .init(1.0, 0.0, 0.0)) model.rotate(angle: star.angle, axis: .init(0.0, 1.0, 0.0)) model.translate(.init(star.distance, 0.0, 0.0)) @@ -305,7 +305,7 @@ struct Lesson9: AppDelegate SDL_BindGPUVertexStorageBuffers(renderPass, 0, &self.instanceBuffer, 1) // Push shader uniforms - SDL_PushGPUVertexUniformData(cmd, 0, &self.projection, UInt32(MemoryLayout.size)) + SDL_PushGPUVertexUniformData(cmd, 0, &self.projection, UInt32(MemoryLayout.size)) // Draw star instances SDL_DrawGPUIndexedPrimitives(renderPass, UInt32(Self.indices.count), UInt32(numInstances), 0, 0, 0) diff --git a/src/swift/NeHe/Matrix.swift b/src/swift/NeHe/Matrix.swift index 5208ac7..e156fef 100644 --- a/src/swift/NeHe/Matrix.swift +++ b/src/swift/NeHe/Matrix.swift @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Zlib */ +import Foundation import simd public extension simd_float4x4 diff --git a/src/swift/NeHe/NeHeContext.swift b/src/swift/NeHe/NeHeContext.swift index dfc4cda..8d8282e 100644 --- a/src/swift/NeHe/NeHeContext.swift +++ b/src/swift/NeHe/NeHeContext.swift @@ -135,9 +135,9 @@ public extension NeHeContext info.format = SDL_GPU_SHADERFORMAT_SPIRV return ( try loadShader(bundle.url(forResource: name, withExtension: "vtx.spv"), - info, SDL_GPU_SHADERSTAGE_VERTEX, "main"), + info, SDL_GPU_SHADERSTAGE_VERTEX, "VertexMain"), try loadShader(bundle.url(forResource: name, withExtension: "frg.spv"), - info, SDL_GPU_SHADERSTAGE_FRAGMENT, "main")) + info, SDL_GPU_SHADERSTAGE_FRAGMENT, "FragmentMain")) } else if availableFormats & SDL_GPU_SHADERFORMAT_DXIL == SDL_GPU_SHADERFORMAT_DXIL {