One of our readers contacted me about an apparently weird behavior he was seeing: when running the code from our tutorial the `MTLLibrary`

returned nil after a few hundred draw calls. That made me realize I was not taking into consideration the fact that some of the `Metal`

objects are transient and some are not, according to the Metal documentation. Thanks **Mike** for bringing this to my attention!

To deal with this matter, we need to re-organize the code, again! And that is always a good thing to do. We need to get the non-transient `Metal`

objects (devices, queues, data buffers, textures, states and pipelines) out of **drawRect(_:)** and put them in a method that only runs once when the view loads. The command buffers and encoders are the only two transient objects designed for a single use, so we can thus create them with each draw call.

We will pick up where we left off in part 5 of the series. To start, let’s create a new method – an initializer – that only runs once when the view is loaded:

required init(coder: NSCoder) { super.init(coder: coder) device = MTLCreateSystemDefaultDevice() createBuffers() registerShaders() }

Next, delete the **render()** method as well as its call inside `drawRect(_:)`

as we don’t need it anymore. Then move all the code from **sendToGPU()** to `drawRect(_:)`

and delete `sendToGPU()`

as we don’t need this one either. This way we moved all the non-transient objects away from `drawRect(_:)`

and only kept the `command buffer`

and `encoder`

inside, which are the only two transient objects.

override func drawRect(dirtyRect: NSRect) { super.drawRect(dirtyRect) if let rpd = currentRenderPassDescriptor, drawable = currentDrawable { rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) let command_buffer = device!.newCommandQueue().commandBuffer() let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd) command_encoder.setRenderPipelineState(rps) command_encoder.setVertexBuffer(vertex_buffer, offset: 0, atIndex: 0) command_encoder.setVertexBuffer(uniform_buffer, offset: 0, atIndex: 1) command_encoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) command_encoder.endEncoding() command_buffer.presentDrawable(drawable) command_buffer.commit() } }

Finally, let’s create a new class named **MathUtils** and move both `structs`

to it so we have a cleaner view class.

import simd struct Vertex { var position: vector_float4 var color: vector_float4 } struct Matrix { var m: [Float] init() { m = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] } func translationMatrix(var matrix: Matrix, _ position: float3) -> Matrix { matrix.m[12] = position.x matrix.m[13] = position.y matrix.m[14] = position.z return matrix } func scalingMatrix(var matrix: Matrix, _ scale: Float) -> Matrix { matrix.m[0] = scale matrix.m[5] = scale matrix.m[10] = scale matrix.m[15] = 1.0 return matrix } func rotationMatrix(var matrix: Matrix, _ rot: float3) -> Matrix { matrix.m[0] = cos(rot.y) * cos(rot.z) matrix.m[4] = cos(rot.z) * sin(rot.x) * sin(rot.y) - cos(rot.x) * sin(rot.z) matrix.m[8] = cos(rot.x) * cos(rot.z) * sin(rot.y) + sin(rot.x) * sin(rot.z) matrix.m[1] = cos(rot.y) * sin(rot.z) matrix.m[5] = cos(rot.x) * cos(rot.z) + sin(rot.x) * sin(rot.y) * sin(rot.z) matrix.m[9] = -cos(rot.z) * sin(rot.x) + cos(rot.x) * sin(rot.y) * sin(rot.z) matrix.m[2] = -sin(rot.y) matrix.m[6] = cos(rot.y) * sin(rot.x) matrix.m[10] = cos(rot.x) * cos(rot.y) matrix.m[15] = 1.0 return matrix } func modelMatrix(var matrix: Matrix) -> Matrix { matrix = rotationMatrix(matrix, float3(0.0, 0.0, 0.1)) matrix = scalingMatrix(matrix, 0.25) matrix = translationMatrix(matrix, float3(0.0, 0.5, 0.0)) return matrix } }

Run the program to make sure you are still seeing the glorious triangle as we have seen it in the previous part. The source code is posted on Github as usual.

Until next time!