jackxujh
jackxujh

Reputation: 1023

Metal craches on MTLDevice.makeBuffer(bytes:length:options:)

I was working with a simple Metal program for iOS with the book Metal Programming Guide, but the makeBuffer(bytes:length:options:) does not work as stated in the book.

The related code below

let vertexData: [Float] = [
    0.0,  0.5,  0.0,
    -1.0, -0.5,  0.0,
    1.0,  -0.5,  0.0
    ]

let dataSize = vertexData.count * MemoryLayout.size(ofValue: vertexData[0])
vertexBuffer = device.makeBuffer(bytes: vertexData, length: dataSize,
    options: [.storageModePrivate]) // error on this line

...

let renderEncoder = commandBuffer?.makeRenderCommandEncoder(
    descriptor: renderPassDescriptor)
renderEncoder?.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
// skipping other setups
renderEncoder?.endEncoding()

will cause a crash during runtime, and here is the error log:

-[MTLDebugDevice newBufferWithBytes:length:options:]:494: failed assertion `storageModePrivate incompatible with ...WithBytes variant of newBuffer'

However, if I use [] as the argument for options in makeBuffer(bytes:length:options:), the program will work fine:

vertexBuffer = device.makeBuffer(bytes: vertexData, length: dataSize,
    options: []) // this will run

But why is this the case?

Upvotes: 2

Views: 2458

Answers (1)

David Kanenwisher
David Kanenwisher

Reputation: 81

I'm working through the book Metal Programming Guide too and ran into this same problem.

I fixed it by changing the storage mode to .storageModeShared.

I changed the failing line to:

vertexBuffer = device.makeBuffer(bytes: vertexData,
                                 length: dataSize,
                                 options: [.storageModeShared]
)

After that I was able to get the triangle to render on my phone.

Upvotes: 2

Related Questions