Over the last few posts we’ve been talking about the Metal Pipeline as well as the main players involved in getting into Metal. Now let’s have a really quick look at how to get a MTKView in your app and displaying a clear colour on the screen. Just remember, this needs to be run on an actual device and won’t work in the simulator.

Start by setting up a Single View Application, select your root View Controller’s class and select its View. Change the class from good old UIView to a MTKView (Metal Kit View). Next, head over to the class for your View Controller and add the following:

1
2
3
4
5
class ViewController: UIViewController {

   var metalView: MTKView {
   return view as! MTKView
}

Here we just create a computed property that will downcast our class’s root view as a MTKView. MTKView’s need a device to work with (Metal’s idea of a CPU) so let’s add a few class properties next to get going:

1
2
3
4
5
6
7
var device: MTLDevice!
var commandQueue: MTLCommandQueue!
// You thought you'd be using UIColor, right? Nope!
let colour = MTLClearColor(red: 0.5,
green: 0.5,
blue: 0.5,
alpha: 1)

We add a MTLDevice and the command queue that sends render commands to it. We also create a nice clear colour which we’ll use to clear the screen and get something showing up.

Next, in the viewDidLoad method we’ll setup everything:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
override func viewDidLoad() {
   super.viewDidLoad()
   // Get access to the GPU descried as a 'device' in Metal
   device = MTLCreateSystemDefaultDevice()
   // The MTKView needs a device instance to work with
   metalView.device = device
   // The clear colour is the colour that is displayed when the view 'clears'
   metalView.clearColor = colour

   // Let's create out queue to send commands to the GPU
   commandQueue = device.makeCommandQueue()
   // Make space in the buffer to work with - we could store lots here in memory
   let buffer = commandQueue.makeCommandBuffer()
   // Make encoder task to actually render stuff
   let commandEncoder = buffer?.makeRenderCommandEncoder(descriptor: metalView.currentRenderPassDescriptor!)

   // Stop encoding
   commandEncoder?.endEncoding()
   // Get a view to render to
   buffer?.present(metalView.currentDrawable!)
   // Commit the tasks to the GPU and show the screen
   buffer?.commit()
}

Here we first initialise our device and set the Metal View’s device property as that device. It needs this to render stuff. Next we set the clear colour and initialise our command queue by asking the device nicely to set one up for us.

Buffers!

I talked about Buffers in my previous post but basically they are like stuff we need stored in memory that Metal can access to do things with. They might be vertices for example that can be manipulated to create a wavy, heat effect when an object is near a toaster that is on. We use our command queue to make a buffer and create our encoder which is like a task to send off to the GPU to render: maybe the toaster model we mentioned earlier!

We end our encoding task, tell the buffer to present its content in our view and commit. The actual drawing takes place at the commit. Think of these rendering tasks as a batched list of descriptions we want to send off to our GPU – it can handle tasks insanely fast so it wants them all in one go!

This should give you a nice screen with a clear colour. Try changing the colour properties just to mess around with.

Congratulations you’ve just interacted with metal, Metal Kit, MTKViews as well as the other moving parts we’ve discussed in this series. If you’re interested, keep following my journey into metal with the Ray Wenderlich course.