Thanks everyone, I got it working with Teras code and now mixed in 1-877s code. There was actually 6 functions with this warning, 2 each of makeEZBuffer, setEZVertexBytes, and copyFrom. setEZVertexBytes is the only pair being used in this project and it’s still running properly!
About size vs stride, that’s something I’ve been long undecided on. I have a vague recollection reading that Metal wants its memory in ‘aligned’ units, which to me means a struct of 13 bytes should be padded up to 16 or whatever the alignment is. That’s why I was using stride. However I share Teras concern that this is then copying memory from beyond the end of the struct. The thing is I did some experiments before with structs of varied sizes and both size and stride worked. Neither crashed or drew wrong stuff in Metal, so that’s why I’m undecided which is correct.
aside: I’m also doing something else i believe is a no-no ;) These structs I’m sending to Metal are simply Swift structs and I heard that the order of properties in memory isn’t guaranteed, so when accessing it on the Metal shader C++ side it could possibly be mangled. The solution is to somehow link with C++ defined structs which guarantee order but I’m using iPad Playgrounds atm and can’t do that. Yet thankfully so far these Swift structs have always yielded memory with properties in the order defined, never had a problem with this possible issue🤞. (Today though I open an Xcode device and can put this concern to rest).
One last small question I ran into while rectifying my functions. In the copyFrom function pair it introduced the warning “Result of call to ‘withUnsafeBytes/Pointer’ is unused”. These functions copy the memory of structs to the contents() pointer of an existing MTLBuffer. memcpy returns an UnsafeMutableRawPointer? but I wasn’t being warned about this previously.
extension MTLBuffer {
func copyFrom(array: [some Any]) {
array.withUnsafeBytes { //<< warning
memcpy(self.contents(), $0.baseAddress!, $0.count)
}
}
func copyFrom<T>(single: T) {
withUnsafePointer(to: single) { //<< warning
memcpy(self.contents(), $0, MemoryLayout<T>.stride)
}
}
}
My fix is to add “let _ =“
let _ = array.withUnsafeBytes {
But it also works to add it to the memcpy line
let _ = memcpy(self.contents(), $0.baseAddress!, $0.count)
Is this the way you’d fix it and is there any meaningful preference to which line to add it to?