Metal/Metal2 + Swift: How to pass complex Swift structure as shader argument?

Viewed 1127

I have a struct in Metal:

struct BlurDesc {
    short fenceRows;
    short offs;
    short sampleCnt;
    float muls[64];
};

It is used as a shader argument:

kernel void hBlurCompute(
    constant BlurDesc & blurDesc [[ buffer(0) ]],
    texture2d<half, access::read> srcTexture [[ texture(0) ]],
    texture2d<half, access::write> hBlurTexture [[ texture(1) ]],
    ushort gid [[ thread_position_in_grid ]]
) {

Here is the corresponding Swift struct:

struct BlurDesc {
    var fenceRows : Int16 = 0
    var offs : Int16 = -32
    var sampleCnt : Int16 = 64
    let muls = Array<Float>(repeating: (1.0/64), count: 64)
}

var blurDesc = BlurDesc()

How can I pass the Swift struct to the shader as argument?

Is it possible to create a byte buffer from it with the right byte order and pass it to: MTLDevice.makeBuffer(bytes pointer: UnsafeRawPointer, length: Int, options: MTLResourceOptions = []) somehow?

2 Answers

Simply use the Apple simd framework to avoid pain.

swift

struct BlurDesc {
    var fenceRows : simd_short1 = 0
    var offs : simd_short1 = -32
    var sampleCnt : simd_short1 = 64
    let muls = Array<simd_float>(repeating: (1.0/64), count: 64)
}
Related