在MTLBuffer的一部分上运行计算内核?

时间:2019-06-15 20:56:17

标签: ios swift buffer metal

我正在用float2向量填充MTLBuffer。缓冲区的创建和填充如下:

struct Particle {
   var position: float2
   ...
}

let particleCount = 100000
let bufferSize = MemoryLayout<Particle>.stride * particleCount
particleBuffer = device.makeBuffer(length: bufferSize)!

var pointer = particleBuffer.contents().bindMemory(to: Particle.self, capacity: particleCount)
pointer = pointer.advanced(by: currentParticles)
pointer.pointee.position = [x, y]

在我的Metal文件中,缓冲区的访问方式如下:

struct Particle {
   float2 position;
   ...
};

kernel void compute(device Particle *particles [[buffer(0)]], 
                    uint id [[thread_position_in_grid]] … ) 

我需要能够计算给定范围的MTLBuffer。例如,是否可以从50,000值开始到75,000值结束运行计算内核?

似乎offset参数允许我指定起始位置,但是它没有长度参数。

我看到有这个电话:

setBuffers(_:offsets:range:)

该范围是否指定要运行的缓冲区的哪一部分?似乎该范围指定了要使用的缓冲区,而不是要使用的值的范围。

1 个答案:

答案 0 :(得分:0)

计算着色器不在缓冲区(或部分)上运行。它在网格上运行,这是一个抽象概念。就Metal而言,网格与缓冲区或其他无关。

缓冲区可能是您的计算着色器使用的输入,但是如何使用取决于您自己。金属不知道或不在乎。

这里是my answer to a similar question

因此,使用计算命令编码器编码的调度命令将控制着色器的调用次数。它还规定了每次调用接收的thread_position_in_grid(及相关)值。 如果,您的着色器将每个网格位置与缓冲区支持的数组元素相关联,那么您在dispatch命令中指定的线程数将控制最终访问的缓冲区数量。 (再次,这不是Metal规定的;它暗含在对着色器进行编码的方式中。)

现在,从第50,000个元素开始,在缓冲区绑定上使用偏移量,以使从着色器的角度来看,缓冲区的有效起点是一个很好的方法。但是,将着色器访问缓冲区时所计算的索引仅添加50,000也可以。而且,如果您只想处理25,000个元素(75,000个减去50,000个),则只需调度25,000个线程即可。