我正在用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]

在我的金属文件中,缓冲区的访问方式如下:
struct Particle {
   float2 position;
   ...
};

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

我需要能够计算给定的MTLBuffer范围。例如,是否可以在say上运行计算内核,从50000值开始,到75000值结束?
似乎offset参数允许我指定起始位置,但它没有length参数。
我看到有个电话:
setBuffers(_:offsets:range:)

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

最佳答案

计算着色器不在缓冲区(或部分)上运行。它在网格上运行,这是一个抽象的概念。就金属而言,网格与缓冲区或其他东西无关。
缓冲区可能是计算着色器使用的输入,但它如何使用取决于您。金属不知道也不在乎。
这是my answer to a similar question
因此,使用计算命令编码器编码的dispatch命令控制调用着色器的次数。它还指示每个调用接收的thread_position_in_grid(和相关)值。如果着色器将每个网格位置与由缓冲区支持的数组元素相关联,则在dispatch命令中指定的线程数将控制最终访问的缓冲区数量。(同样,这不是金属所规定的;这是隐式的,在编写着色器的方式中。)
现在,从第50000个元素开始,使用缓冲区绑定上的偏移量使缓冲区从着色器的角度有效地开始是一个很好的方法。但它也可以工作,只需添加50000的索引着色器计算时,访问缓冲区。而且,如果您只想处理25000个元素(75000减去50000),那么只需分派25000个线程。

10-08 07:20
查看更多