sooon sooon - 3 months ago 48
Swift Question

MetalKit - Drawable.texture assertion error

I am new to

MetalKit
and trying to convert this tutorial from
playground
back to
OSX
app:

import MetalKit

public class MetalView: MTKView {

var queue: MTLCommandQueue! = nil
var cps: MTLComputePipelineState! = nil

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


override public func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
if let drawable = currentDrawable {
let command_buffer = queue.commandBuffer()
let command_encoder = command_buffer.computeCommandEncoder()
command_encoder.setComputePipelineState(cps)
command_encoder.setTexture(drawable.texture, atIndex: 0)
let threadGroupCount = MTLSizeMake(8, 8, 1)
let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1)
command_encoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount)
command_encoder.endEncoding()
command_buffer.presentDrawable(drawable)
command_buffer.commit()
}
}

func registerShaders() {
queue = device!.newCommandQueue()
do {
let library = device!.newDefaultLibrary()!
let kernel = library.newFunctionWithName("compute")!
cps = try device!.newComputePipelineStateWithFunction(kernel)
} catch let e {
Swift.print("\(e)")
}
}
}


I got an error at the line:

command_encoder.setTexture(drawable.texture, atIndex: 0)



failed assertion `frameBufferOnly texture not supported for compute.'


How can I resolve this?

Answer

If you want to write to a drawable's texture from a compute function, you'll need to tell the MTKView that it should configure its layer not to be framebuffer-only:

metalView.framebufferOnly = false

With this value set to false, your drawable will give you a texture with the shaderWrite usage flag set, which is required when writing a texture from a shader function.

Comments