是否可以在运行时更改缓冲区大小?我们在寄存器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
还是有更好的方法吗?
答案 0 :(得分:2)
不,您在创建缓冲区后无法更改缓冲区的大小。
为什么你认为每次都需要获得一个新的命令队列?命令队列与缓冲区大小无关。
你唯一需要重新创建的就是缓冲区本身。
但是,如果粒子数有上限,则可以从头开始以最大大小创建缓冲区。并不要求缓冲区完全与当前需要的一样大。它可能比需要的更大,即使它的某些部分被暂时浪费了。
或者,如果你确实想要随着粒子数量的增加重新分配它,我不一定每次都重新分配它。相反,我会将当前所需的大小舍入为页面大小的倍数(4096字节)。那样,你有些松懈。粒子计数可以增加一段时间而不需要重新分配缓冲区。