我正在用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:)
该范围是否指定要运行的缓冲区的哪一部分?似乎该范围指定了要使用的缓冲区,而不是要使用的值的范围。
答案 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个线程即可。