gpgpumetalmtlbuffer

How to pass dynamic sized super large array to Metal Argument buffers?


I have a large array with more than 1 million struct instance. The size is actually dynamic. It works fine with MTLBuffer, it appears to be a pointer in Metal shader, and I don't have to write some hardcoded size or length.

The problem is, I don't want to bind or set it for each frame. So, I am looking into ArgumentBuffers and Heap. But I didn't find solution or example for my use case. It looks like everything in array inside ArgumentBuffers will take some slot. That's not a good idea for my large array. And I didn't find good example which have pointer in ArgumentBuffers.

After all, what is best practice for my use case?


Solution

  • Let me answer my own question. To support dynamic sized array inside Argument buffer. We need the device supporting Metal 2 Tier 2.

    [argumentEncoder setArgumentBuffer:_argumentBuffer startOffset:0 arrayElement:0];
    // Then, write some code to fill the data for first element
    [argumentEncoder setArgumentBuffer:_argumentBuffer startOffset:0 arrayElement:1];
    // Then, write some code to fill the data for second element
    

    While, on the GPU side you can simple use the pointer reference below.

    constant TheBufferTypeName* theBuffer [[buffer(0)]]

    Then, use it with theBuffer[0] or theBuffer[1].

    It's done without any hardcoded size.