2 Replies
      Latest reply on Nov 11, 2016 6:03 AM by FrankP2138
      FrankP2138 Level 1 Level 1 (0 points)

        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

        • Re: How to use UnsafeMutableRawPointer in Swift 3
          eskimo Apple Staff Apple Staff (13,925 points)

          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"