类型的价值' MTLBuffer'没有会员'didModifyRange'

时间:2017-12-21 05:55:20

标签: ios swift xcode metal

我很困惑,因为我在Swift 4中创建了一个MTLBuffer但是我无法使用方法didModifyRange。

有趣的是,我仍然可以在Apple文档中找到这个并且没有听说过这个被更改。

为什么错误Value of type 'MTLBuffer' has no member 'didModifyRange'正在发生?

以下代码会在最新版本的XCode中生成此错误

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

3 个答案:

答案 0 :(得分:1)

根据documentation,该方法的签名如下:

func didModifyRange(_ range: Range<Int>)

你传递的NSRange明显不同于Swift Range<Int>。因此,为了使其工作,只需传递适当的范围对象。

P.S。 Range<Int>定义了min...max方案(例如0...100)。

修改

某些Metal框架签名仅适用于macOS 11.1,包括didModifyRange:,因此如果您尝试在iOS上调用它,即使标题中包含import Metal,也会为您提供错误。

所以下面的代码将在macOS 11.1下编译

import Metal
//  ...

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

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

......并且不会,在iOS下。

答案 1 :(得分:1)

初始化MTLBuffer buffer后,您可以使用来获取指向它的类型化指针

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

这将返回与buffer.contents()相同的地址,但步幅与Float的大小对齐,即您在那里注册了总共capacity个浮点数。根据需要更改这些参数。

现在您可以直接通过以下方式更新/访问数据

x[0] = 3.14

x[5] = 1.59

etc.

有关更多详细信息,请参阅Apple的bindMemory文档。

答案 2 :(得分:0)

在iOS上没有didModifyRange()。仅在macOS上可用。

相反,我最终是这样的:

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
)