Within my app, I have a MTLBuffer which is being instantiated using a generic type. In one particular case, the buffer will hold values as related to particles in a point cloud, and is defined as such;
struct ParticleUniforms {
simd_float3 position;
simd_float3 color;
float confidence;
};
I am instantiating my MTLBuffer like so;
guard let buffer = device.makeBuffer(length: MemoryLayout<Element>.stride * count, options: options) else {
fatalError("Failed to create MTLBuffer.")
}
Where I am struggling, however, is to understand how to read the contents of the buffer. More-so, I am looking to copy one element of each item in the buffer to an array on the CPU, which I will use at a later time.
Effectively, the buffer holds a collection of ParticleUniforms, and I would like to access the position value of each item, saving that position to a separate array.
All of the examples I've seen here on Stack Overflow seem to show the MTLBuffer as holding a collection of Floats, though I've not seen any that use a generic type.
It seems what you are looking to achieve can only be done with C structures which hold each member in a contiguous block (arrays of C structs are not necessarily contiguous, but
MemoryLayout<Type>.stridewill account for any potential padding). Swift structure properties may not be contiguous, so the below method for accessing member values would not work in a practical manner. Unfortunately, when working withvoid*you need to know what the data describes, which isn't particularly suited for Swift generic types. However, I will offer a potential solution.C file:
Swift file (bridging header assumed)
This is similar to a
MTLVertexDescriptor, except the memory is accessed manually and not via the[[stage_in]]attribute and the argument table passed to each instance of a vertex of fragment shader. You could even extend the allocator to accept a string parameter with the name of the property and hold some dictionary which maps to member IDs.