Issuing Our First GPU Command!

Now that we have the basic setup and knowledge to issue our first GPU command, we’ll be rendering an RGBA color value to our MTKView.

The first thing we want to do inside draw is to create our commandBuffer. This will contain the instructions we need to execute our commands!

Creating the pipeline

Our command buffer needs a pipeline to be fed through. The pipeline needs internal information and interface information. We use a MTLRenderPassDescriptor to configure the interface information. For this tutorial, we don’t need to create our own — we can fetch the default one from the MTKView using .currentRenderPassDescriptor .

Now accessing our render pass descriptor’s colorAttachements array property, we can set a value at it’s (0th entry).clearColor which describes the color data for the texture assigned to the view’s current drawable. More simply, this can be thought of as the “background color” for our metal view.

Next, we need a MTLRenderCommandEncoder to configure the inside of the pipeline. It’s compiled from our commandBuffer using the renderDescriptor.

From here we can start inputting vertex data and drawing commands to be drawn on the GPU, or better thought of as “encoding” commands for the GPU to run. For now, we’re not ready to encode any real drawing commands so we’ll leave that for later (I lied to you in the section title :p). We want to see that beautiful blue background color in our MTKView!

We need to do four things to end the encoding and fire off the commandBuffer to be executed on the GPU and displayed to our view!

End the encoding.

renderEncoder.endEncoding()

2. Tell the GPU where to send the rendered result.

commandBuffer.present(view.currentDrawable!)

We can use the MTKView’s currentDrawable, a drawable representing the current frame. A MTLDrawable is a “displayable resource that can be rendered or written to.”

3. Add the instruction to our metalCommandQueue

commandBuffer.commit()

4. Tell our metal view to draw which triggers the draw method, we’ll be adding this at the end of our setupMetal() function, but you can call it anywhere you’d like (after you’ve set up the metal components, of course).

metalView.needsDisplay = true

Our draw function should now look like this.

If you hit run, you should see a blue screen!

Note:

Earlier when we were choosing how to update our MTKView, I mentioned we went with setting it manually using the view’s internal timer because of our reliance on the currentRenderPassDescriptor. If we had gone with issuing the draw() command manually, ignoring its timer, we would have had to call it twice, as the view would not have had a currentRenderDescriptor the first time.

We now need to encode commands into the renderEncoder to let it know what to draw from vertex points passed in. We also need a way to represent this information such that we can create it in our view and the metal shader can use it properly as well. But first, we need to go through a high-level overview of how the GPU actually draws stuff.