Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Metal default library not found

Tags:

ios

swift

metal

I tried using iOS Metal in a simple app but when i call the device.newDefaultLibrary() function then I get an error in runtime:

/BuildRoot/Library/Caches/com.apple.xbs/Sources/Metal/Metal-56.7/Framework/MTLLibrary.mm:1842: failed assertion `Metal default library not found'

Has anyone any idea what cloud be the problem? I followed this tutorial: https://www.raywenderlich.com/77488/ios-8-metal-tutorial-swift-getting-started The code is a little old but with tiny changes it work. Here is my viewController code:

import UIKit
import Metal
import QuartzCore

class ViewController: UIViewController {

    //11A
        var device: MTLDevice! = nil

        //11B
        var metalLayer: CAMetalLayer! = nil

        //11C
        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

        //11F
        var pipelineState: MTLRenderPipelineState! = nil

        //11G
        var commandQueue: MTLCommandQueue! = nil

        //12A
        var timer: CADisplayLink! = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //11A
        device = MTLCreateSystemDefaultDevice()

        //11B
        metalLayer = CAMetalLayer()          // 1
        metalLayer.device = device           // 2
        metalLayer.pixelFormat = .BGRA8Unorm // 3
        metalLayer.framebufferOnly = true    // 4
        metalLayer.frame = view.layer.frame  // 5
        view.layer.addSublayer(metalLayer)   // 6

        //11C
        let dataSize = vertexData.count * sizeofValue(vertexData[0]) // 1
        vertexBuffer = device.newBufferWithBytes(vertexData, length: dataSize, options: MTLResourceOptions.CPUCacheModeDefaultCache) // 2

        //11F
        // 1
        let defaultLibrary = device.newDefaultLibrary() //The error is generating here
        let fragmentProgram = defaultLibrary!.newFunctionWithName("basic_fragment")
        let vertexProgram = defaultLibrary!.newFunctionWithName("basic_vertex")

        // 2
        let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
        pipelineStateDescriptor.vertexFunction = vertexProgram
        pipelineStateDescriptor.fragmentFunction = fragmentProgram
        pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm

        // 3
        do {
            try pipelineState = device.newRenderPipelineStateWithDescriptor(pipelineStateDescriptor)
        } catch _ {
            print("Failed to create pipeline state, error")
        }

        //11G
        commandQueue = device.newCommandQueue()

        //12A
        timer = CADisplayLink(target: self, selector: Selector("gameloop"))
        timer.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //MARK: Custom Methodes

    //12A
    func render() {

        //12C
        let commandBuffer = commandQueue.commandBuffer()

        //12B
        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)

        //12D
        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()

        //12E
        commandBuffer.presentDrawable(drawable!)
        commandBuffer.commit()

    }

    func gameloop() {
        autoreleasepool {
            self.render()
        }
    }

}

I use an iPhone 5s device with iOS 9.3 for testing.

like image 496
Gulyás István Avatar asked Mar 24 '16 15:03

Gulyás István


1 Answers

The default library is only included in your app when you have at least one .metal file in your app target's Compile Sources build phase. I assume you've followed the steps of the tutorial where you created the Metal shader source file and added the vertex and fragment functions, so you simply need to use the + icon in the build phases setting to add that file to your compilation phase:

Compile Sources Build Phase

like image 166
warrenm Avatar answered Nov 20 '22 01:11

warrenm