How to use UnsafeMutableRawPointer in Swift 3

In my old tutorial , working with Metal

I have:

var labColorBuffer:MTLBuffer!

labColorBuffer = self.device.makeBuffer(length: 4 * MemoryLayout<Float>.size, options: [])

labColorBuffer.label = "labColors"

to update the date, I had these settings:

let pData = labColorBuffer.contents()
let vData = UnsafeMutablePointer<Float>(pData)
vData[0] = 0.250
vData[1] = 0.250
vData[2] = 0.250
vData[3] = 0.250


Now in my new version:

let pData = labColorBuffer.contents() // returns UnsafeMutableRawPointer


you better do it this way

let pData = labColorBuffer.contents()
pData.initializeMemory(as: Float.self, count: 0, to: 0.250)
pData.initializeMemory(as: Float.self, count: 1, to: 0.250)
pData.initializeMemory(as: Float.self, count: 2, to: 0.250)
pData.initializeMemory(as: Float.self, count: 3, to: 0.250)


or this :

func initRawABCD() -> UnsafeMutableRawPointer {
        let intPtr = UnsafeMutablePointer<Float>.allocate(capacity: 4)
        intPtr[0] = 0.250 /
        intPtr[1] = 0.250 /
        intPtr[2] = 0.250 /
        intPtr[3] = 0.250 /
        return UnsafeMutableRawPointer(intPtr)
    }


labColorBuffer = self.device.makeBuffer(bytes: initRawABCD(), length: MemoryLayout<Float>.size(ofValue: 4), options: [])


also you need deinitialize ?


thanks for your cooperation

Replies

The issue you’re having is the result of SE-0107 UnsafeRawPointer API, which puts Swift’s type aliasing rules on a firm footing. If you’re working with low-level APIs like Metal, I strongly recommend you read the UnsafeRawPointer Migration doc before going further.

As to your specific issue, I’m not a Metal expert but it seems that you’re initialisation of

labColorBuffer
has caused Metal to allocate raw memory that you want to treat as an array of
Float
. If that’s correct, you can do this like so:
let vData = pData.bindMemory(to: Float.self, capacity: 4)
vData.initialize(to: 0.250, count: 4)

The thing to watch out for here is that you don’t bind that raw memory to any other type. That doesn’t look like it’s be a problem in this case, but make sure to avoid it in general. As the docs say:

A memory location may only be bound to one type at a time. The behavior of accessing memory as type

U
while it is bound to an unrelated type
T
is undefined.

… also you need deinitialize ?

When dealing with low-level types like

Float
you don’t need to worry too much deinitialisation; Swift does not need to, for example, release reference counts before the memory goes away.

On the initialisation front, you’ll want to make sure you set up all the elements to avoid junk values leaking out to the rest of your code. You can use

UnsafeMutableRawPointer.initializeMemory(to:count:)
(or one of its variants) to do this, as I’ve shown above.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks eskimo

your explanation was very clear.