如何使用显式序列化将数据从金属数据获取到Swift结构

时间:2019-04-27 21:50:50

标签: swift gpgpu metal

我正在尝试将数据从Metal Mesh Vertex数组获取到Swift结构。

我知道Swift结构和C结构可能不相等。 我也知道我可以使用c桥接标头来完成此操作,但这会带来其他一些问题。

如何通过从金属数据到Swift结构数组的显式序列化来做到这一点?

也可以看到相同数据的反序列化。

import PlaygroundSupport
import MetalKit
import simd

struct Vertex {
    var position: vector_float3
    var normal: vector_float3
    var texture: vector_float2

    init() {
        position = float3(repeating: 0.0)
        normal = float3(repeating: 0.0)
        texture = float2(repeating: 0.0)
    }

    init(pos: vector_float3, nor: vector_float3, text: vector_float2) {
        position = pos
        normal = nor
        texture = text
    }
}

guard let device = MTLCreateSystemDefaultDevice() else {
    fatalError("GPU is not supported")
}

let allocator = MTKMeshBufferAllocator(device: device)

let mesh = MDLMesh.init(boxWithExtent: [0.75, 0.75, 0.75], segments: [1, 1, 1], inwardNormals: false, geometryType: .quads, allocator: allocator)

// Details about the vertex
print("Details about the vertex")
print( mesh.vertexDescriptor )

// Look at the vertex detail
// This doesn't work because, I think, of the way Swift pads the memory in structs.
print("Number of vertex: ", mesh.vertexCount)
let buff = mesh.vertexBuffers[0]

// This gives the wrong result but is nice code
let count = buff.length / MemoryLayout<Vertex>.stride
print("Wrong result!")
print("Space in buffer for vertex: ", count)
let wrongResult = buff.map().bytes.bindMemory(to: Vertex.self, capacity: count)
for i in 0 ..< count {
    print( "Vertex: ", i, wrongResult[i])
}

// This gives the correct result but is really ugly code
print("Correct result!")
let tempResult = buff.map().bytes.bindMemory(to: Float.self, capacity: mesh.vertexCount*8)
var result = Array(repeating: Vertex(), count: mesh.vertexCount)
for i in 0 ..< mesh.vertexCount {
    result[i].position.x = tempResult[i*8 + 0]
    result[i].position.y = tempResult[i*8 + 1]
    result[i].position.z = tempResult[i*8 + 2]
    result[i].normal.x = tempResult[i*8 + 3]
    result[i].normal.y = tempResult[i*8 + 4]
    result[i].normal.z = tempResult[i*8 + 5]
    result[i].texture.x = tempResult[i*8 + 6]
    result[i].texture.y = tempResult[i*8 + 7]
}
for i in 0 ..< mesh.vertexCount {
    print( "Vertex: ", i, result[i])
}

0 个答案:

没有答案