Files
Memola/Memola/Canvas/Core/PipelineStates.swift
2024-07-14 16:44:21 +07:00

187 lines
9.0 KiB
Swift

//
// PipelineStates.swift
// Memola
//
// Created by Dscyre Scotti on 5/4/24.
//
import MetalKit
import Foundation
enum PipelineStates {
static func createPointGridPipelineState(from renderer: Renderer, pixelFormat: MTLPixelFormat? = nil) -> MTLRenderPipelineState? {
let device = renderer.device
let library = renderer.library
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_point_grid")
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_point_grid")
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
pipelineDescriptor.label = "Point Grid Pipeline State"
let attachment = pipelineDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.rgbBlendOperation = .add
attachment?.sourceRGBBlendFactor = .one
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
attachment?.alphaBlendOperation = .add
attachment?.sourceAlphaBlendFactor = .sourceAlpha
attachment?.destinationAlphaBlendFactor = .oneMinusSourceAlpha
return try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
static func createLineGridPipelineState(from renderer: Renderer, pixelFormat: MTLPixelFormat? = nil) -> MTLRenderPipelineState? {
let device = renderer.device
let library = renderer.library
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_line_grid")
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_line_grid")
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
pipelineDescriptor.label = "Line Grid Pipeline State"
let attachment = pipelineDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.rgbBlendOperation = .add
attachment?.sourceRGBBlendFactor = .one
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
attachment?.alphaBlendOperation = .add
attachment?.sourceAlphaBlendFactor = .sourceAlpha
attachment?.destinationAlphaBlendFactor = .oneMinusSourceAlpha
return try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
static func createGraphicPipelineState(from renderer: Renderer, pixelFormat: MTLPixelFormat? = nil) -> MTLRenderPipelineState? {
let device = renderer.device
let library = renderer.library
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_graphic")
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_graphic")
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
pipelineDescriptor.label = "Graphic Pipeline State"
let attachment = pipelineDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.rgbBlendOperation = .add
attachment?.sourceRGBBlendFactor = .sourceAlpha
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
attachment?.alphaBlendOperation = .add
attachment?.sourceAlphaBlendFactor = .one
attachment?.destinationAlphaBlendFactor = .oneMinusSourceAlpha
return try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
static func createStrokePipelineState(from renderer: Renderer, pixelFormat: MTLPixelFormat? = nil) -> MTLRenderPipelineState? {
let device = renderer.device
let library = renderer.library
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_stroke")
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_stroke")
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
pipelineDescriptor.label = "Stroke Pipeline State"
let attachment = pipelineDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.rgbBlendOperation = .add
attachment?.sourceRGBBlendFactor = .sourceAlpha
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
attachment?.alphaBlendOperation = .add
attachment?.sourceAlphaBlendFactor = .one
attachment?.destinationAlphaBlendFactor = .oneMinusSourceAlpha
return try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
static func createEraserPipelineState(from renderer: Renderer, pixelFormat: MTLPixelFormat? = nil) -> MTLRenderPipelineState? {
let device = renderer.device
let library = renderer.library
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_stroke")
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_stroke_eraser")
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
pipelineDescriptor.label = "Eraser Pipeline State"
let attachment = pipelineDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.rgbBlendOperation = .add
attachment?.sourceRGBBlendFactor = .sourceAlpha
attachment?.destinationRGBBlendFactor = .one
attachment?.alphaBlendOperation = .reverseSubtract
attachment?.sourceAlphaBlendFactor = .sourceAlpha
attachment?.destinationAlphaBlendFactor = .oneMinusSourceAlpha
return try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
static func createPhotoPipelineState(from renderer: Renderer, pixelFormat: MTLPixelFormat? = nil) -> MTLRenderPipelineState? {
let device = renderer.device
let library = renderer.library
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_photo")
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_photo")
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
pipelineDescriptor.label = "Photo Pipeline State"
let attachment = pipelineDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.rgbBlendOperation = .add
attachment?.sourceRGBBlendFactor = .sourceAlpha
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
attachment?.alphaBlendOperation = .add
attachment?.sourceAlphaBlendFactor = .one
attachment?.destinationAlphaBlendFactor = .oneMinusSourceAlpha
return try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
static func createViewPortPipelineState(from renderer: Renderer, pixelFormat: MTLPixelFormat? = nil, isUpdate: Bool = false) -> MTLRenderPipelineState? {
var label: String
var vertexName: String
if isUpdate {
label = "View Port Update Pipeline State"
vertexName = "vertex_viewport_update"
} else {
label = "View Port Pipeline State"
vertexName = "vertex_viewport"
}
let device = renderer.device
let library = renderer.library
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = library.makeFunction(name: vertexName)
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_viewport")
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
pipelineDescriptor.label = label
let attachment = pipelineDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.rgbBlendOperation = .add
attachment?.sourceRGBBlendFactor = .sourceAlpha
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
attachment?.alphaBlendOperation = .add
attachment?.sourceAlphaBlendFactor = .one
attachment?.destinationAlphaBlendFactor = .oneMinusSourceAlpha
return try? device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
static func createCachePipelineState(from renderer: Renderer) -> MTLComputePipelineState? {
let device = renderer.device
let library = renderer.library
guard let function = library.makeFunction(name: "copy_texture_viewport") else {
return nil
}
return try? device.makeComputePipelineState(function: function)
}
static func createQuadPipelineState(from renderer: Renderer) -> MTLComputePipelineState? {
let device = renderer.device
let library = renderer.library
guard let function = library.makeFunction(name: "generate_stroke_vertices") else {
return nil
}
return try? device.makeComputePipelineState(function: function)
}
}