包含int2数组的MTLBuffer在由计算着色器

时间:2016-08-17 01:06:08

标签: ios swift buffer gpu metal

我试图使用以下类将带有int2数组的缓冲区传递给内核函数:

class MetalHelper {    
    lazy var device: MTLDevice! = { MTLCreateSystemDefaultDevice() }()
    lazy var defaultLibrary: MTLLibrary! = { self.device.newDefaultLibrary() }()
    lazy var commandQueue: MTLCommandQueue! = { return self.device.newCommandQueue() }()
    var pipelineState: MTLComputePipelineState!

    var inTexture: MTLTexture!
    var outTexture: MTLTexture!
    var testBuffer: [int2] = [int2(Int32(3), Int32(-1)), int2(Int32(0), Int32(7)), int2(Int32(2), Int32(-10))] // etc...

    // Additional setup of in and out textures, pipeline state....

    func compute() {
        commandQueue.insertDebugCaptureBoundary()

        let commandBuffer = commandQueue.commandBuffer()
        let commandEncoder = commandBuffer.computeCommandEncoder()

        commandEncoder.setComputePipelineState(pipelineState)
        commandEncoder.setTexture(inTexture, atIndex: 0)
        commandEncoder.setTexture(outTexture, atIndex: 1)

        let buffer = device.newBufferWithBytes(&testBuffer, length: sizeof(int2) * testBuffer.count, options: [.StorageModeShared])
        commandEncoder.setBuffer(buffer, offset: 0, atIndex: 0)

        let threadsPerThreadgroup = MTLSizeMake(16, 16, 1);
        let width = Int(inTexture.width / threadsPerThreadgroup.width)
        let height = Int(inTexture.height / threadsPerThreadgroup.height)
        let threadgroupCount = MTLSizeMake(width, height, 1)

        commandEncoder.dispatchThreadgroups(threadgroupCount, threadsPerThreadgroup: threadsPerThreadgroup)
        commandEncoder.endEncoding()

        commandBuffer.commit()
        commandBuffer.waitUntilCompleted()

        commandQueue.insertDebugCaptureBoundary()
    }
}

在我的着色器函数中,从缓冲区中读取值以获得像素的颜色。已知缓冲区数组长度等于inTexture中的切片数。

kernel void average(texture2d_array<float, access::read> inTexture [[texture(0)]],
                     texture2d<float, access::write> outTexture [[texture(1)]],
                     const device int2 *testBuffer [[buffer(0)]],
                     uint2 gid [[thread_position_in_grid]])
{
    uint total = inTexture.get_array_size();

    uint index;
    float4 averageColor = float4(0, 0, 0, 0);

    for (index = 0; index < total; index++) {
        int2 offset = testBuffer[index];
        const uint2 coordinate = uint2(gid.x + offset[0], gid.y + offset[1]);

        const float4 colorAtPixel = inTexture.read(coordinate, index);
        averageColor += colorAtPixel;
    }

    averageColor = averageColor / total;
    outTexture.write(averageColor, gid);
}

由于某种原因,testBuffer中的值不正确。这是GPU框架:

gputrace

非常感谢任何帮助或指导!

0 个答案:

没有答案