具有输入和输出一维数据缓冲区的金属计算着色器?
Metal compute shader with 1D data buffer in and out?
我知道可以将一维数组缓冲区传递给金属着色器,但是否可以将其输出到一维数组缓冲区?我不希望它写入纹理 - 我只需要一组处理过的值。
我可以使用以下代码通过着色器获取值,但它们一次只有一个值。理想情况下,我可以得到整个数组(与输入一维数组缓冲区的顺序相同)。
任何示例或指示将不胜感激!
var resultdata = [Float](repeating: 0, count: 3)
let outVectorBuffer = device.makeBuffer(bytes: &resultdata, length: MemoryLayout<float3>.size, options: [])
commandEncoder!.setBuffer(outVectorBuffer, offset: 0, index: 6)
commandBuffer!.addCompletedHandler {commandBuffer in
let data = NSData(bytes: outVectorBuffer!.contents(), length: MemoryLayout<float3>.size)
var out: float3 = float3(0,0,0)
data.getBytes(&out, length: MemoryLayout<float3>.size)
print("data: \(out)")
}
//In the Shader:
kernel void compute1d(
...
device float3 &outBuffer [[buffer(6)]],
outBuffer = float3(1.0, 2.0, 3.0);
)
两件事:
您需要创建足够大的缓冲区来容纳任意数量的 float3
元素。不过,在计算缓冲区大小时,您确实需要使用 .stride
和 而不是 .size
。特别是,float3
具有 16 字节对齐,因此数组中的元素之间存在填充。所以,你会使用像 MemoryLayout<float3>.stride * desiredNumberOfElements
.
这样的东西
然后,在着色器中,您需要将outBuffer
的声明从引用更改为指针。所以,device float3 *outBuffer [[buffer(6)]]
。然后你可以索引它来访问元素(例如 outBuffer[2] = ...;
)。
我知道可以将一维数组缓冲区传递给金属着色器,但是否可以将其输出到一维数组缓冲区?我不希望它写入纹理 - 我只需要一组处理过的值。
我可以使用以下代码通过着色器获取值,但它们一次只有一个值。理想情况下,我可以得到整个数组(与输入一维数组缓冲区的顺序相同)。
任何示例或指示将不胜感激!
var resultdata = [Float](repeating: 0, count: 3)
let outVectorBuffer = device.makeBuffer(bytes: &resultdata, length: MemoryLayout<float3>.size, options: [])
commandEncoder!.setBuffer(outVectorBuffer, offset: 0, index: 6)
commandBuffer!.addCompletedHandler {commandBuffer in
let data = NSData(bytes: outVectorBuffer!.contents(), length: MemoryLayout<float3>.size)
var out: float3 = float3(0,0,0)
data.getBytes(&out, length: MemoryLayout<float3>.size)
print("data: \(out)")
}
//In the Shader:
kernel void compute1d(
...
device float3 &outBuffer [[buffer(6)]],
outBuffer = float3(1.0, 2.0, 3.0);
)
两件事:
您需要创建足够大的缓冲区来容纳任意数量的
float3
元素。不过,在计算缓冲区大小时,您确实需要使用.stride
和 而不是.size
。特别是,float3
具有 16 字节对齐,因此数组中的元素之间存在填充。所以,你会使用像MemoryLayout<float3>.stride * desiredNumberOfElements
. 这样的东西
然后,在着色器中,您需要将
outBuffer
的声明从引用更改为指针。所以,device float3 *outBuffer [[buffer(6)]]
。然后你可以索引它来访问元素(例如outBuffer[2] = ...;
)。