2017-04-23 65 views
1

是否可以在运行时更改缓冲区大小?我们在注册分配的缓冲区大小我们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 = 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 

或者有什么更好的办法来做到这一点的变化一时间queue

回答

2

不,您不能在创建缓冲区后更改其大小。

为什么你觉得每次都需要一个新的命令队列?命令队列与缓冲区大小无关。

你必须重新创建的唯一东西就是缓冲区本身。

但是,如果粒子数量有上限,则可以从一开始就以最大大小创建缓冲区。没有要求的缓冲区为,正好与当前需要的一样大。即使它的一部分被暂时浪费,它也可能比需要的更大。

或者,如果您确实希望随着粒子数量的增加将其重新分配,那么我不一定每次都将其重新分配为足够大。相反,我会将当前所需的大小舍入为页面大小的倍数(4096字节)。那样,你有一些松懈。粒子计数可以增加一段时间而不需要重新分配缓冲液。