【问题标题】:Metal shader output data (GPGPU)金属着色器输出数据 (GPGPU)
【发布时间】:2018-06-26 16:04:53
【问题描述】:

我正在尝试在 ios 上实现一些图像检测算法,并且我需要一些数据准备工作,这些数据准备工作应该用作着色器(金属),因此它应该将输出数组与结果数据一起传递。

小例子:SWIFT

...
// Create buffer
var resultBuffer = device.makeBuffer(length: SIZE * MemoryLayout<Int32>.size, options: .storageModeShared)!

// Set buffer to encoder
computeCommandEncoder?.setBuffer(resultBuffer, offset: 0, index: 0)
...
// Call shader
commandBuffer.commit()
commandBuffer.waitUntilCompleted()

// Print first element for test
var p = resultBuffer.contents()
let first = p.load(as: UInt32.self)
print("first = \(first)")

MSL(金属着色器)

...
kernel void preparation(
  texture2d<float, access::read> inTexture [[texture(0)]], // Input texture

  texture2d<float, access::write> outTexture [[texture(1)]], // Output texture
  device uint* result [[ buffer(0) ]], // Output buffer
                uint2 gid [[thread_position_in_grid]])
{
    result[0] = 5; // Just for test set first element to 5
    float4 colorAtPixel = inTexture.read(gid);
    outTexture.write(colorAtPixel, gid); // Copy color from input texture to output texture
}

所以我希望它应该打印出来

first = 5

但它会打印出来

first = 0

所以着色器似乎不会改变缓冲区内容?任何想法如何使它工作?

PS 我使用 iOS 11.2、iPhone 5S、XCode 9.2

【问题讨论】:

  • 在 iOS 11.2.2、iPhone X、Xcode 9.2 上为我工作。如果可能,请分享一个完整的示例项目来演示该问题。

标签: ios image-processing shader gpgpu metal


【解决方案1】:

您正试图从线程组中的每个像素写入相同的输出内存位置。如果您正在写入内存位置,则必须特别注意仅将每个 gid 元素标识的每个像素写入 1 个内存位置。更好的方法是从输入纹理中读取并写入每个像素的输出纹理,只需删除 uint*result 缓冲区并直接使用纹理,您的头痛就会消失。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多