Я пытаюсь понять, как работают вычислительные шейдеры Metal, поэтому я написал этот код :

class AppDelegate: NSObject, NSApplicationDelegate {


    var number:Float!
    var buffer:MTLBuffer!


    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
        let metalDevice = MTLCreateSystemDefaultDevice()!
        let library = metalDevice.newDefaultLibrary()!
        let commandQueue = metalDevice.newCommandQueue()
        let commandBuffer = commandQueue.commandBuffer()
        let commandEncoder = commandBuffer.computeCommandEncoder()


        let pointlessFunction = library.newFunctionWithName("pointless")!
        let pipelineState = try! metalDevice.newComputePipelineStateWithFunction(pointlessFunction)
        commandEncoder.setComputePipelineState(pipelineState)
        number = 12

        buffer = metalDevice.newBufferWithBytes(&number, length: sizeof(Float), options: MTLResourceOptions.StorageModeShared)
        commandEncoder.setBuffer(buffer, offset: 0, atIndex: 0)


        commandEncoder.endEncoding()

        commandBuffer.commit()
        commandBuffer.waitUntilCompleted()

        let data = NSData(bytesNoCopy: buffer.contents(), length: sizeof(Float), freeWhenDone: false)
        var newResult:Float = 0
        data.getBytes(&newResult, length: sizeof(Float))
        print(newResult)




    }

Создавая буфер с помощью StorageModeShared, я хочу, чтобы изменения, внесенные в буфер Metal, отражались в моем Swift-коде, но когда я заполняю переменную newResult, кажется, что буфер имеет то же значение, что и в начале (12), в то время как он должен быть 125 :

.
#include 
using namespace metal;



kernel void pointless (device float* outData [[ buffer(0) ]]) {

    *outData = 125.0;
}

Что я делаю неправильно?

Pop Flamingo

Ответов: 1

Ответы (1)

Функция ядра не запускается, пока вы не отправите ее. Я думаю, вы предполагаете, что если у вас есть функция, то Metal должен запустить ее один раз, пока вы не скажете иначе, но этого не произойдет. Вместо этого она не будет выполняться вообще. Добавьте это перед endEncoding и все готово!

let size = MTLSize(width: 1, height: 1, depth: 1)
commandEncoder.dispatchThreadgroups(size, threadsPerThreadgroup: size)

2022 WebDevInsider