是否可以在运行时更改缓冲区大小?我们在注册期间分配缓冲尺寸的device
:
device = MTLCreateSystemDefaultDevice()
queue = device!.makeCommandQueue()
do {
let library = device!.newDefaultLibrary()!
let kernel = library.makeFunction(name: "compute")!
cps = try device!.makeComputePipelineState(function: kernel)
} catch let e {
Swift.print("(e)")
}
paramBuffer = device!.makeBuffer(length: MemoryLayout<Float>.size*2, options: [])
然后我们在运行时相应地对其进行更新:
override public func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
if let drawable = currentDrawable {
let command_buffer = queue.makeCommandBuffer()
let command_encoder = command_buffer.makeComputeCommandEncoder()
command_encoder.setComputePipelineState(cps)
command_encoder.setTexture(drawable.texture, at: 0)
command_encoder.setBuffer(paramBuffer, offset: 0, at: 0)
它现在有效。但是,如果我有一个有粒子的方案,处于不同状态的情况有所不同。例如,在一开始,我有500个颗粒,一段时间后,粒子一次慢慢增加10个,例如510,520,530,...
我应该如何处理这种情况?每次粒子计数发生变化时,我都应该重做queue
吗?:
queue = device!.makeCommandQueue()
do {
let library = device!.newDefaultLibrary()!
let kernel = library.makeFunction(name: "compute")!
cps = try device!.makeComputePipelineState(function: kernel)
} catch let e {
Swift.print("(e)")
}
paramBuffer = device!.makeBuffer(length: MemoryLayout<Float>.size*particleCount, options: [])//<--particleCount
或任何更好的方法?
no,您无法在其创建缓冲区的大小。
为什么您认为您每次都需要获得新的命令队列?命令队列与缓冲区大小无关。
您唯一需要重新创建的是缓冲区本身。
如果粒子数量上有一个上限,则可以从开始时只需在该最大尺寸以最大的大小创建缓冲区即可。不需要缓冲区正好当前所需的大小。即使暂时浪费了其中的一部分,它也可能比需要大。
另外,如果您确实想随着粒子数量的增加而将其重新分配给它,那么我不一定会将其重新分配给每次足够大。取而代之的是,我将当前所需的大小绕过页面大小的倍数(4096字节(。这样,您会有些懈怠。粒子计数可以增加一段时间,而无需重新分配缓冲液。