In the keynote presentation discussing the new metal 2 features it was mentioned that you would create an argument buffer from a MTLFunction. When I try that I always end up with a BAD ACCESS error on runtime. What I try to do is:
- define a struct to be buffered in the metal shader
- set the struct to be buffered as a parameter of the kernel function.
- after creating the function from the library I call makeIndirectArgumentEncoder on that kernel function.
Trying to set a buffer, texture orconstant data is then going to fail. What am I missing?
This is what happens on the CPU side:
let library = device.makeDefaultLibrary()!
let function = library.makeFunction(name: "trace")!
let argumentEncoder = function.makeIndirectArgumentEncoder(bufferIndex: 0)
argumentEncoder.setTexture(argumentInImage, index:0) //BAD ACCESS ERROR right here.
argumentEncoder.setBuffer(worldBuffer, offset: 0, index: 1)
And in the metal shader:
struct CameraState {
texture2d<float,access::read_write> in [[id(0)]];
device Sphere *spheres [[id(1)]];
...
};
kernel void trace(
constant CameraState &cameraState [[ buffer(0) ]],
...
){...}
When I look into the assembler code that crashed I can see the comment: ' "0 && "could't found the resource in the Layout Array\n"" '.
As far as I understand makeIndirectArgumentEncoder tries to optimally create the buffer for me that is then used as input at index 0 when I call the function. It seems though that the while making the argument encoder there could not be found a match for the texture buffer in the struct.
Actually I'm not quite sure if the [[id(x)]] declaration in the struct is correct, but that was the only hint I found in the demo code, but it does not work with nor without this.
Maybe knows what I'm doing wrong here. I would be grateful!
Cheers,
Enie