I'm trying some test coding with swift, Metal and iOS. I have an MTLBuffer and an Array:
var uint16Array:[UInt16] = Array(repeating: 0, count: 16)
var mtlBuffer:MTLBuffer = device.makeBuffer(bytes: uint16Array, length: 32)!
If I update the array
uint16Array[0] = 22
uint16Array[7] = 22
uint16Array[15] = 22
then I can update the mtlbuffer:
mtlBuffer.contents().copyMemory(from: uint16Array, byteCount:32)
But... If I want to copy from array index != 0.... How to do?.
"pseudocode":
mtlBuffer.contents().copyMemory(from: uint16Array[4], byteCount:22)
(not works, of course)
I have tried some code with "withUnsafeBufferPointer", "UnsafeRawPointer(uint16Array + 4)", etc but without success.
Access the non-zero index of uint16Array via withUnsafePointer
import Metal
var uint16Array:[UInt16] = Array(repeating: 0, count: 16)
let device = MTLCreateSystemDefaultDevice()!
var mtlBuffer: MTLBuffer = device.makeBuffer(
bytes: uint16Array,
length: uint16Array.count * MemoryLayout<Int16>.stride
)!
// Print the original values
print("Original mtlBuffer:")
printBufferValues(buffer: mtlBuffer)
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
uint16Array = [UInt16](0..<16)
let firstIndex = 3
let lastIndex = 10
let range = lastIndex - firstIndex
withUnsafePointer(to: &uint16Array[firstIndex]) {
mtlBuffer
.contents()
.advanced(by: firstIndex * MemoryLayout<Int16>.stride)
.copyMemory(from: $0, byteCount: range * MemoryLayout<Int16>.stride)
}
// Print the modified values
print("\nModified mtlBuffer:")
printBufferValues(buffer: mtlBuffer)
// [0, 0, 0, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0]
// Function to print buffer values
func printBufferValues(buffer: MTLBuffer) {
let pointer = buffer.contents().assumingMemoryBound(to: Int16.self)
let bufferValues = UnsafeBufferPointer(start: pointer, count: buffer.length / MemoryLayout<Int16>.stride)
print(Array(bufferValues))
}