Reputation: 412
I have different types of drawings that I do in my app. For example, I draw shapes and grids.
For each type of drawing I have a custom vertex and fragment shader and a class that inherits from MTKViewDelegate. Each of these classes deals with the processing needed to calculate the inputs and a method that looks like this and is called on init:
private func loadMetal(_ mtkView: MTKView) {
mtkView.colorPixelFormat = .bgra8Unorm_srgb
let defaultLibrary = device.makeDefaultLibrary()!
let vertexProgram = defaultLibrary.makeFunction(name: "grid_vertex")
let fragmentProgram = defaultLibrary.makeFunction(name: "grid_fragment")
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat
pipelineState = try! device.makeRenderPipelineState(descriptor: pipelineStateDescriptor)
commandQueue = device.makeCommandQueue()
vertexBuffer = device.makeBuffer(length: bufferCapacity * MemoryLayout<GridVertex>.stride, options: [])
vertexIndices = device.makeBuffer(length: bufferCapacity * MemoryLayout<UInt16>.size,
options: [])
}
So for each pair of vertex/frag shaders I'm creating the pipelineDescriptor and a commandQueue. This works ok, but I was wondering if this is ok or should I reuse the commandQueue/pipeline?
Upvotes: 1
Views: 274
Reputation: 90701
You should reuse the command queue. Except for special cases, there's usually a single command queue per device.
There's no need to reuse the pipeline descriptor object. Those are cheap to create and intended to be transitory. (Pipeline state objects are expensive to create and should be created once and reused, as you appear to be doing.)
See the Transient and Non-transient Objects in Metal section of the Metal Programming Guide.
Upvotes: 2