2

Metal を使用して多面体をレンダリングしています。newBufferWithBytes() を使用して頂点がわずか 1680 バイトのデータで構成される正二十面体エンティティをレンダリングしようとすると、問題が発生します。その後、アプリ全体が停止し、CPU と GPU の両方のフレームがゼロになり、Metal ビューのフリーズを除いてすべてが正常に戻りました。

Node のサブクラスとして、通常の多面体を実装しています。

class Node {
let name : String
var vertexBuffer: MTLBuffer?
var uniformBuffer: MTLBuffer?
var vertexCount : Int = 0

var device : MTLDevice

init(name: String, vertices: [Vertex], device: MTLDevice){
    self.name = name
    self.device = device

    var floatBuffer : [Float] = []
    for vertex in vertices {
        floatBuffer += vertex.floatBuffer
    }
    let floatBufferSize = floatBuffer.count * sizeof(Float)

    self.vertexBuffer = device.newBufferWithBytes(&floatBuffer, length: floatBufferSize, options: nil)
    self.vertexCount = floatBuffer.count
}

func render(commandEncoder: MTLRenderCommandEncoder, parentModelViewMatrix: Matrix4, projectionMatrix: Matrix4){
    commandEncoder.setVertexBuffer(self.vertexBuffer, offset: 0, atIndex: 0)

    // set up uniform transformation matrices
    var nodeModelMatrix = self.modelMatrix()
    nodeModelMatrix.multiplyLeft(parentModelViewMatrix)
    let matrixSize = sizeof(Float) * Matrix4.numberOfElements()
    uniformBuffer = device.newBufferWithLength(matrixSize * 2, options: .OptionCPUCacheModeDefault)
    var bufferPointer = uniformBuffer?.contents()
    memcpy(bufferPointer!, nodeModelMatrix.raw(), matrixSize)
    memcpy(bufferPointer! + matrixSize, projectionMatrix.raw(), matrixSize)
    commandEncoder.setVertexBuffer(self.uniformBuffer, offset: 0, atIndex: 1)

    // can draw
    commandEncoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: self.vertexCount, instanceCount: 1)
}
}
4

2 に答える 2

3

ネハルさんの提案に感謝します。それに応じて回答を修正しました。

Apple Documentation: Metal Feature Set Tablesによると、以下にリストされているハードウェアでは、MTLBuffer の最大長はすべて 256 MB です。

iOS 8 および 9 の Apple A7 ~ A9 GPU。

OS X 10.11: MacBook (early 2015)、MacBook Air (mid 2012 以降)、MacBook Pro (mid 2012 以降)、Mac Mini (late 2012 以降)、iMac (late 2012 以降)、および Mac Pro (late 2012 以降) 2013 年以降)。

于 2016-03-21T04:27:25.367 に答える
3

メタル機能セット テーブルには、MTLBuffer の最大長が記載されなくなりました。iOS 12 および macOS 10.14 以降ではmaxBufferLengthon プロパティがあり、MTLDeviceより大きなバッファーを作成するときにチェックする必要があります。

これをググっただけで、コードを書かずに何らかのアプローチの実行可能性を評価するための数値が必要な場合は、それが私に与えた数値です。

 - iPad Pro (12.9", 2nd generation) iOS 13.3 - 993 MB (1041235968 bytes)
 - iPhone 11 iOS 13.3 - 960 MB (1007468544 bytes) 
 - iPhone 8 iOS 12.4 - 747 MB (783597568 bytes)
 - iPhone 6 iOS 12.1 - 256 MB (268435456 bytes)

これらは、アプリの起動とシステムの再起動の間、同じままであるようです。もちろん、それらは変更される可能性がありますが、アイデアを提供します。常に少なくとも 256MB を取得できると想定するのがおそらく安全です。

于 2020-04-22T17:41:56.780 に答える