ediheld ediheld - 2 months ago 11x
iOS Question

Metal Shading Language - (Console) Output?

Can I debug my metal-shading-language code using console output (like

in Swift)?

If yes, how?

If no, are there any other ways to output variables from my .metal file? (Maybe by passing data from the .metal file to my .swift file using the commandEncoder-buffer?)

I have unsuccessfully tried to pass a reference to an Int variable (which is in my .swift file) via the commandEncoder to my .metal file. In the .metal file, I assign a value to the int variable, but if I print the Int in my swift file, the assigned value is not there.

.swift file:

var myMetalOutput: Int = 0
let printBuffer = device.newBufferWithBytes(&myMetalOutput, length: sizeof(Int), options: MTLResourceOptions.CPUCacheModeDefaultCache)
commandEncoder.setBuffer(printBuffer, offset: 0, atIndex: 8)
print("myMetalOutput: \(myMetalOutput)")

.metal file:

kernel void shader(..., device int &printBuffer [[8]], ...) {
printBuffer = 123;

The console output is always
myMetalOutput: 0


There are a couple of things going wrong here. First, newBufferWithBytes(_:length:) makes a copy of the data you provide, so the address that is written to is not the address of the original variable. Second, you don't seem to be waiting for the compute kernel to complete before attempting to read the result. You can either call waitUntilCompleted() on the corresponding command buffer (which blocks the current thread), or you can call addCompletedHandler() to provide a closure that will be called asynchronously when the kernel finishes running. At that point, you should be able to read back data from the buffer.

There is no facility for printing to the command line from within a Metal shader, so writing to a buffer or texture is pretty much your best option here.