Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShaderStringBuilder #1

Merged
merged 1 commit into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 13 additions & 20 deletions Examples/ExampleMacOS/ExampleMacOS/Logic/Functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,23 @@ class MyCompute1: SCMetalComputeFunction {
@EMArgument("tex") var tex: SCMetalTexture = .init(texture: nil, usage: .read_write)
@EMArgument("col") var col: Float = 0

init() {
super.init(
functionName: "myCompute1",
impl: [
"tex.write(float4(col, 0.1, col, 1), gid);"
]
)
@ShaderStringBuilder
override var impl: String {
"tex.write(float4(col, 0.1, col, 1), gid);"
}
}

class MyRender1: SCMetalRenderFunction {

init() {
super.init(
functionName: "myRender1",
vertImpl: [
"rd.size = 1;",
"rd.position = input;",
"rd.color = float4(1, 0.6, 0.8, 1);",
],
fragImpl: [
"return rd.color;"
],
targetPixelFormat: .bgra8Unorm
)
@ShaderStringBuilder
override var vertImpl: String {
"rd.size = 1;"
"rd.position = input;"
"rd.color = float4(1, 0.6, 0.8, 1);"
}

@ShaderStringBuilder
override var fragImpl: String {
"return rd.color;"
}
}
2 changes: 1 addition & 1 deletion Examples/ExampleMacOS/ExampleMacOS/Logic/MyRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class MyRenderer: ShaderRenderer {
}()

let compute1 = MyCompute1()
let render1 = MyRender1()
let render1 = MyRender1(targetPixelFormat: .bgra8Unorm)

override func draw(view: MTKView, drawable: CAMetalDrawable) {
let dispatch = SCMetalDispatch()
Expand Down
33 changes: 13 additions & 20 deletions Examples/ExampleiOS/ExampleiOS/Logic/Functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,23 @@ class MyCompute1: SCMetalComputeFunction {
@EMArgument("tex") var tex: SCMetalTexture = .init(texture: nil, usage: .read_write)
@EMArgument("col") var col: Float = 0

init() {
super.init(
functionName: "myCompute1",
impl: [
"tex.write(float4(col, 0.1, col, 1), gid);"
]
)
@ShaderStringBuilder
override var impl: String {
"tex.write(float4(col, 0.1, col, 1), gid);"
}
}

class MyRender1: SCMetalRenderFunction {

init() {
super.init(
functionName: "myRender1",
vertImpl: [
"rd.size = 1;",
"rd.position = input;",
"rd.color = float4(1, 0.6, 0.8, 1);",
],
fragImpl: [
"return rd.color;"
],
targetPixelFormat: .bgra8Unorm
)
@ShaderStringBuilder
override var vertImpl: String {
"rd.size = 1;"
"rd.position = input;"
"rd.color = float4(1, 0.6, 0.8, 1);"
}

@ShaderStringBuilder
override var fragImpl: String {
"return rd.color;"
}
}
2 changes: 1 addition & 1 deletion Examples/ExampleiOS/ExampleiOS/Logic/MyRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class MyRenderer: ShaderRenderer {
}()

let compute1 = MyCompute1()
let render1 = MyRender1()
let render1 = MyRender1(targetPixelFormat: .bgra8Unorm)

override func draw(view: MTKView, drawable: CAMetalDrawable) {
let dispatch = SCMetalDispatch()
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.7
// swift-tools-version: 5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
30 changes: 30 additions & 0 deletions Sources/EasyMetalShader/Builder/ShaderStringBuilder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// File.swift
//
//
// Created by Yuki Kuwashima on 2024/01/09.
//

import Foundation

@resultBuilder
public struct ShaderStringBuilder {
public static func buildBlock(_ component: String) -> String{
component
}
public static func buildBlock(_ components: String...) -> String {
components.joined()
}
public static func buildBlock(_ components: [String]) -> String {
components.joined()
}
public static func buildBlock(_ components: [String], _ components2: [String]) -> String {
components.joined() + components2.joined()
}
public static func buildArray(_ components: [String]) -> String {
components.joined()
}
public static func buildArray(_ components: [[String]]) -> String {
components.joined().joined()
}
}
16 changes: 11 additions & 5 deletions Sources/EasyMetalShader/Pipelines/SCMetalComputeFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,21 @@ open class SCMetalComputeFunction: NSObject, SCMetalFunction {

public var args: [String: SCMetalArgument] = [:]

public init(functionName: String, impl: [String]) {

@ShaderStringBuilder
open var impl: String {
""
}

public override init() {
super.init()

MirrorUtil.setInitialValue(for: self)

let tempFunctionName = "f" + UUID().uuidString.lowercased().replacingOccurrences(of: "-", with: "")

var functionImpl = ""
functionImpl += Self.initialMetalHeader
functionImpl += "kernel void \(functionName)("
functionImpl += "kernel void \(tempFunctionName)("

for (i, key) in args.keys.enumerated() {
switch args[key] {
Expand Down Expand Up @@ -91,7 +97,7 @@ open class SCMetalComputeFunction: NSObject, SCMetalFunction {
}
}

functionImpl += impl.joined()
functionImpl += impl
functionImpl += "}"

let library = try! ShaderCore.device.makeLibrary(
Expand All @@ -100,7 +106,7 @@ open class SCMetalComputeFunction: NSObject, SCMetalFunction {
)
self.computePipelineState = try! ShaderCore.device.makeComputePipelineState(
function: library.makeFunction(
name: functionName
name: tempFunctionName
)!
)
}
Expand Down
21 changes: 13 additions & 8 deletions Sources/EasyMetalShader/Pipelines/SCMetalRenderFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import simd

@objcMembers
open class SCMetalRenderFunction: NSObject, SCMetalFunction {

private static let initialMetalHeader = MetalPreLibrary.include + MetalPreLibrary.rand + MetalPreLibrary.svd + MetalPreLibrary.rasterizerData

public var args: [String: SCMetalArgument] = [:]
Expand All @@ -19,17 +20,21 @@ open class SCMetalRenderFunction: NSObject, SCMetalFunction {
var renderTargetTexture: MTLTexture!
var needsClear: Bool = false

public init(functionName: String, vertImpl: [String], fragImpl: [String], targetPixelFormat: MTLPixelFormat) {

@ShaderStringBuilder open var vertImpl: String { "" }
@ShaderStringBuilder open var fragImpl: String { "" }

public init(targetPixelFormat: MTLPixelFormat) {
super.init()

MirrorUtil.setInitialValue(for: self)

let tempFunctionName = "f" + UUID().uuidString.lowercased().replacingOccurrences(of: "-", with: "")

var functionImpl = ""
functionImpl += Self.initialMetalHeader

//vertex
functionImpl += "vertex RasterizerData \(functionName)_vert("
functionImpl += "vertex RasterizerData \(tempFunctionName)_vert("

for (i, key) in args.keys.enumerated() {
switch args[key] {
Expand Down Expand Up @@ -96,12 +101,12 @@ open class SCMetalRenderFunction: NSObject, SCMetalFunction {
}
}

functionImpl += vertImpl.joined()
functionImpl += vertImpl
functionImpl += "return rd;"
functionImpl += "}"

//fragment
functionImpl += "fragment float4 \(functionName)_frag("
functionImpl += "fragment float4 \(tempFunctionName)_frag("

for (i, key) in args.keys.enumerated() {
switch args[key] {
Expand Down Expand Up @@ -169,7 +174,7 @@ open class SCMetalRenderFunction: NSObject, SCMetalFunction {
}
}

functionImpl += fragImpl.joined()
functionImpl += fragImpl
functionImpl += "}"


Expand All @@ -178,8 +183,8 @@ open class SCMetalRenderFunction: NSObject, SCMetalFunction {
options: nil
)
let descriptor = MTLRenderPipelineDescriptor()
descriptor.vertexFunction = library.makeFunction(name: functionName + "_vert")
descriptor.fragmentFunction = library.makeFunction(name: functionName + "_frag")
descriptor.vertexFunction = library.makeFunction(name: tempFunctionName + "_vert")
descriptor.fragmentFunction = library.makeFunction(name: tempFunctionName + "_frag")

let vertexDesc = MTLVertexDescriptor()
vertexDesc.attributes[0].format = .float4
Expand Down
Loading