Reputation: 1552
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
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
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
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