J.Doe
J.Doe

Reputation: 1552

Value of type 'MTLBuffer' has no member 'didModifyRange'

I am confused as I have created a MTLBuffer in Swift 4 yet am unable to use the method didModifyRange.

Interestingly enough I can still find this in the Apple documentation and have not heard of this being changed.

Why is the error Value of type 'MTLBuffer' has no member 'didModifyRange' happening?

The following code would generate this error in the latest version of XCode

let device = MTLCreateSystemDefaultDevice()
var buffer = device?.makeBuffer(length: 3, options: [])
let range = Range<Int>(NSRange())
buffer.didModifyRange(range)

Upvotes: 4

Views: 835

Answers (3)

user1300214
user1300214

Reputation:

Once you have initialised your MTLBuffer buffer you can obtain a typed pointer to it using

let x = buffer.contents().bindMemory(to: Float.self, capacity: 1000)

This returns the same address as buffer.contents() but it's stride is aligned to the size of Float, where you have registered there being capacity floats in total. Change these parameters as required.

Now you can directly update/access the data via

x[0] = 3.14

x[5] = 1.59

etc.

See Apples's bindMemory documentation for more details.

Upvotes: 1

neoneye
neoneye

Reputation: 52231

On iOS there is no didModifyRange(). It's only available on macOS.

Instead I ended up doing like this:

var myVertices: [MyVertex]

...
myVertices[0].color = float4(x: 1, y: 0, z: 0, w: 1)
...

mltBuffer.contents().copyMemory(
    from: myVertices, 
    byteCount: myVertices.count * MemoryLayout<MyVertex>.stride
)

Upvotes: 0

Hexfire
Hexfire

Reputation: 6058

According to documentation, signature of the method looks like this:

func didModifyRange(_ range: Range<Int>)

You pass NSRange which is obviously different from Swift Range<Int>. So to get it work, simply pass proper range object.

P.S. Range<Int> is defined with min...max scheme (e.g. 0...100).

EDIT:

Some Metal framework signatures are only available on macOS 11.1, including didModifyRange:, so if you try to call it on iOS, even having import Metal in the header, will give you that error.

So the following code will compile under macOS 11.1

import Metal
//  ...

    guard
        let device = MTLCreateSystemDefaultDevice(),
        let buffer = device.makeBuffer(length: 3, options: [])
        else {
            return
    }

    buffer.didModifyRange(Range<Int>(1...10))

...and will not, under iOS.

Upvotes: 2

Related Questions