s1ddok/alloy
Alloy is a tiny set of utils and extensions over Apple's Metal framework dedicated to make your Swift GPU code much cleaner and let you prototype your pipelines faster.
Other Alloy-specific types
Other types that are introduces my Alloy are
MTLOffscreenRenderer: this is a class that lets you create simple off-screen renderers to draw something into arbitaryMTLTexturesComputeCommand: this is an experimental class that does a reflection over Metal kernels and lets you assign arguments by name instead of index. This is a subject for improvements.BlendingMode: this type contains the enumeration of eight Alloy's built-in blending modes. You can easily setup one of them just by callingsetup(blending:)function.
``swift let renderPipelineDescriptor = MTLRenderPipelineDescriptor() renderPipelineDescriptor.colorAttachments[0].setup(blending: .alpha) ``
MTLContext minimal usage example
MTLContext is usually being injected in the class, as you usually do with MTLDevice, you should cache the context and all heavy-weighted objects so you can reuse them lates, i.e.:
import Alloy
public class BrightnessEncoder {
public let context: MTLContext
fileprivate let pipelineState: MTLComputePipelineState
/**
* This variable controls the brightness factor. Should be in range of -1.0...1.0
*/
public var intensity: Float = 1.0
public init(context: MTLContext) {
self.context = context
guard let lib = context.shaderLibrary(for: BrightnessEncoder.self),
let state = try? lib.computePipelineState(function: "brightness")
else { fatalError("Error during shader loading") }
self.pipelineState = state
}
public func encode(input: MTLTexture,
in commandBuffer: MTLCommandBuffer) {
commandBuffer.compute { encoder in
encoder.set(textures: [input])
encoder.set(self.intensity, at: 0)
encoder.dispatch2d(state: self.pipelineState,
covering: input.size)
}
}
}Note how simple it is to kick off a kernel with Alloy, no more tedious thredgroup size calculations, multiple encoder initialization with balancing .endEncoding() calls.
Then somewhere else you just do
context.scheduleAndWait { buffer in
self.brightnessEncoder.intensity = sender.floatValue
self.brightnessEncoder.encode(input: texture,
in: buffer)
// For Mac applications
if case .managed = texture.storageMode {
buffer.blit { encoder in
encoder.synchronize(resource: texture)
}
}
}With this approach you can easily stack and build your GPU pipeline layers, group blit, compute and render command encodings with Swift closures, while maintaing full flexibility of Metal API.
Installation
CocoaPods
CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Alloy into your Xcode project using CocoaPods, specify it in your Podfile:
# Optionally add version, i.e. '~> 0.9.0'
pod 'Alloy'License
MIT
Package Metadata
Repository: s1ddok/alloy
Default branch: master
README: README.md