I tried using iOS Metal in a simple application, but when I call the device.newDefaultLibrary () function, I get an error at runtime:
/BuildRoot/Library/Caches/com.apple.xbs/Sources/Metal/Metal-56.7/Framework/MTLLibrary.mm:1842: unsuccessful statement "No default metal library found"
Does anyone know what a cloud is? I followed this guide: https://www.raywenderlich.com/77488/ios-8-metal-tutorial-swift-getting-started
The code is a bit old, but it works with tiny changes. Here is my viewController code:
import UIKit
import Metal
import QuartzCore
class ViewController: UIViewController {
var device: MTLDevice! = nil
var metalLayer: CAMetalLayer! = nil
let vertexData:[Float] = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0]
var vertexBuffer: MTLBuffer! = nil
var pipelineState: MTLRenderPipelineState! = nil
var commandQueue: MTLCommandQueue! = nil
var timer: CADisplayLink! = nil
override func viewDidLoad() {
super.viewDidLoad()
device = MTLCreateSystemDefaultDevice()
metalLayer = CAMetalLayer()
metalLayer.device = device
metalLayer.pixelFormat = .BGRA8Unorm
metalLayer.framebufferOnly = true
metalLayer.frame = view.layer.frame
view.layer.addSublayer(metalLayer)
let dataSize = vertexData.count * sizeofValue(vertexData[0])
vertexBuffer = device.newBufferWithBytes(vertexData, length: dataSize, options: MTLResourceOptions.CPUCacheModeDefaultCache)
let defaultLibrary = device.newDefaultLibrary()
let fragmentProgram = defaultLibrary!.newFunctionWithName("basic_fragment")
let vertexProgram = defaultLibrary!.newFunctionWithName("basic_vertex")
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm
do {
try pipelineState = device.newRenderPipelineStateWithDescriptor(pipelineStateDescriptor)
} catch _ {
print("Failed to create pipeline state, error")
}
commandQueue = device.newCommandQueue()
timer = CADisplayLink(target: self, selector: Selector("gameloop"))
timer.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func render() {
let commandBuffer = commandQueue.commandBuffer()
let drawable = metalLayer.nextDrawable()
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = drawable!.texture
renderPassDescriptor.colorAttachments[0].loadAction = .Clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 0.0, green: 104.0/255.0, blue: 5.0/255.0, alpha: 1.0)
let renderEncoderOpt = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
renderEncoderOpt.setRenderPipelineState(pipelineState)
renderEncoderOpt.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 0)
renderEncoderOpt.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)
renderEncoderOpt.endEncoding()
commandBuffer.presentDrawable(drawable!)
commandBuffer.commit()
}
func gameloop() {
autoreleasepool {
self.render()
}
}
}
I am using iPhone 5s with iOS 9.3 for testing.