newBufferWithBytes() 有大小限制吗?
Posted
技术标签:
【中文标题】newBufferWithBytes() 有大小限制吗?【英文标题】:Is there a size limit to newBufferWithBytes()? 【发布时间】:2015-06-01 16:08:40 【问题描述】:我一直在使用 Metal 渲染多面体。当我尝试使用 newBufferWithBytes() 渲染一个二十面体实体时,就会出现问题,该实体的顶点仅包含大小为 1680 字节的数据。然后整个应用程序停止,CPU 和 GPU 帧都下降到零,一切都恢复正常,除了金属视图冻结。
我在实现中将常规多面体作为 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)
【问题讨论】:
【参考方案1】:感谢 Nehal 女士的建议。我已经相应地修改了答案。
根据 Apple 文档:Metal Feature Set Tables,使用下面列出的硬件,最大 MTLBuffer 长度均为 256 MB。
ios 8 和 9 上的 Apple A7 ~ A9 GPU。
OS X 10.11:MacBook(2015 年初)、MacBook Air(2012 年中或更新)、MacBook Pro(2012 年中或更新)、Mac Mini(2012 年末或更新)、iMac(2012 年末或更新)和 Mac专业版(2013 年末及更新)。
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效【参考方案2】:金属特征集表不再说明最大 MTLBuffer 长度。
从 iOS 12 和 macOS 10.14 开始,MTLDevice
上有一个 maxBufferLength
属性,您应该在创建更大的缓冲区时检查它。
如果你只是用谷歌搜索了这个并且需要一个数字来评估某种方法的可行性而不编写任何代码,这里是它给我的数字。
- 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 的空间可能是安全的。
【讨论】:
以上是关于newBufferWithBytes() 有大小限制吗?的主要内容,如果未能解决你的问题,请参考以下文章