金属着色语言 - 更改缓冲区大小
metal shading language - change buffer size
是否可以在 运行 时更改缓冲区大小?我们在寄存器 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
或者有更好的方法吗?
不,缓冲区创建后不能更改其大小。
为什么您认为每次都需要获取一个新的命令队列?命令队列与缓冲区大小无关。
您唯一需要重新创建的是缓冲区本身。
但是,如果粒子数量有上限,您可以简单地从一开始就创建最大大小的缓冲区。不要求缓冲区正好 与当前需要的一样大。它可以比需要的更大,即使它的一部分被暂时浪费了。
或者,如果你确实想随着粒子数量的增加将它重新分配得更大,我不一定每次都将它重新分配到刚好足够大。相反,我会将当前所需的大小四舍五入为页面大小(4096 字节)的倍数。那样的话,你就有些松懈了。粒子计数可以增加一段时间而不需要重新分配缓冲区。
是否可以在 运行 时更改缓冲区大小?我们在寄存器 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
或者有更好的方法吗?
不,缓冲区创建后不能更改其大小。
为什么您认为每次都需要获取一个新的命令队列?命令队列与缓冲区大小无关。
您唯一需要重新创建的是缓冲区本身。
但是,如果粒子数量有上限,您可以简单地从一开始就创建最大大小的缓冲区。不要求缓冲区正好 与当前需要的一样大。它可以比需要的更大,即使它的一部分被暂时浪费了。
或者,如果你确实想随着粒子数量的增加将它重新分配得更大,我不一定每次都将它重新分配到刚好足够大。相反,我会将当前所需的大小四舍五入为页面大小(4096 字节)的倍数。那样的话,你就有些松懈了。粒子计数可以增加一段时间而不需要重新分配缓冲区。