2017-04-23 7 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 개의 입자가 있습니다. 잠시 후 510, 520, 530 등의 입자가 한 번에 10 씩 천천히 증가합니다.

이 시나리오에 어떻게 접근해야합니까? 나는 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 

또는이 작업을 수행하는 더 나은 방법에 변화가있을 때마다 다시 실행해야합니까?

답변

2

아니요, 버퍼를 만든 후에는 버퍼의 크기를 변경할 수 없습니다.

매번 새로운 명령 대기열을 가져와야한다고 생각하는 이유는 무엇입니까? 명령 대기열은 버퍼 크기와 관련이 없습니다.

다시 작성해야 할 것은 버퍼 자체뿐입니다.

입자 수에 상한이있는 경우 처음부터 최대 크기로 간단하게 버퍼를 만들 수 있습니다. 현재 버퍼가 인 정확히 일 필요는 없습니다. 일부분이 일시적으로 낭비 되더라도 필요한 것보다 더 클 수 있습니다.

입자 수의 증가에 따라 입자를 더 많이 할당하려면 매번 입자 크기를 늘릴 필요가 없습니다. 대신 현재 필요한 크기를 페이지 크기 (4096 바이트)의 배수로 반올림합니다. 그런 식으로, 당신은 약간의 여유가 있습니다. 파티클 수는 버퍼를 재 할당 할 필요없이 잠시 증가 할 수 있습니다.