Creating a Metal buffer from vDSP DSPSplitComplex in Swift

641 views Asked by At

I am trying to pass Apple vDSP's DSPSplitComplex struct to Apple Metal's newBufferWithBytesNoCopy in Swift to create a Metal buffer object:

    // Create vDSP Split Complex data type
    var iData1Real = [Float](count: Int(lenIData1), repeatedValue: 1.0)
    var iData1Imag = [Float](count: Int(lenIData1), repeatedValue: 2.0)

    withExtendedLifetime(iData1Real) { () -> () in
        withExtendedLifetime(iData1Imag) {
            var iData1 = DSPSplitComplex(realp: &iData1Real, imagp: &iData1Imag)

            // Create a 1D buffer for the first input data (idata1)
            var bufferIData1: MTLBuffer = device.newBufferWithBytesNoCopy(UnsafeMutablePointer<Void>(&iData1), length:Int(lenIData1)*sizeof(Float32), options:nil, deallocator:nil)
        }
      }

This results in an error

Type 'MTLBuffer!' does not conform to protocol 'MTLBuffer'

in the line for creating bufferIData1.

DSPSplitComplex is a struct of two UnsafeMutablePointer's. How can I extract the UnsafeMutablePointer from a struct of two UnsafeMutablePointers? Isn't &iData1 getting a pointer to the struct?

I tried to pass iData1.realp and specify the number of bytes to cover both realp and imagp. This removed the compilation error, but I wasn't sure that the realp and imagp reside in the memory in a contiguous fashion.

Thanks for the help in advance.

1

There are 1 answers

0
rickster On BEST ANSWER

Just pass &iData1 for the first argument to newBufferWithBytesNoCopy.

When interacting with C APIs that take pointers, prefix & already (effectively) gets you a pointer to the prefixed value. Using an UnsafeMutablePointer initializer and passing an &-prefixed value to that essentially gets you a double pointer, which is probably not what the API you're calling wants.

See Pointers in Using Swift with Cocoa and Objective-C for additional details and other valid syntax.