[使用MemoryLayout使用struct协议的怪异案例,报告了不同的大小

问题描述 投票:0回答:1

我正在使用Metal开发绘图引擎。我正在从以前的版本进行修改,因此从头开始

我遇到错误由于执行期间发生错误,命令缓冲区的执行被中止。导致GPU挂起错误(IOAF代码3)

经过一些调试后,我将责任归咎于我的drawPrimitives例程,我发现这种情况很有趣

我将有各种各样的笔刷,它们都将与特定的顶点信息一起使用

所以我说,为什么不呢?让所有画笔都响应协议]

顶点的协议将是这样:

protocol MetalVertice {}

此特定笔刷使用的顶点信息将是:

struct PointVertex:MetalVertice{
    var pointId:UInt32
    let relativePosition:UInt32
}

可以通过提供先前创建的顶点或通过调用创建这些顶点的函数来调用画笔。无论如何,真正的绘制发生在顶点函数

var vertices:[PointVertex] = [PointVertex].init(repeating: PointVertex(pointId: 0,
                                                                               relativePosition: 0),
                                                        count: totalVertices)

        for (verticeIdx, pointIndex) in pointsIndices.enumerated(){
            vertices[verticeIdx].pointId = UInt32(pointIndex)
        }

 for vertice in vertices{
            print("size: \(MemoryLayout.size(ofValue: vertice))")
        }

        self.renderVertices(vertices: vertices,
                            forStroke: stroke,
                            inDrawing: drawing,
                            commandEncoder: commandEncoder)

        return vertices
    }


    func renderVertices(vertices: [MetalVertice], forStroke stroke: LFStroke, inDrawing drawing:LFDrawing, commandEncoder: MTLRenderCommandEncoder) {

        if vertices.count > 1{
        print("vertices a escribir: \(vertices.count)")
            print("stride: \(MemoryLayout<PointVertex>.stride)")
            print("size of array \(MemoryLayout.size(ofValue: vertices))")
            for vertice in vertices{
                print("ispointvertex: \(vertice is PointVertex)")
                print("size: \(MemoryLayout.size(ofValue: vertice))")
            }
        }
        let vertexBuffer = LFDrawing.device.makeBuffer(bytes: vertices,
                                                       length: MemoryLayout<PointVertex>.stride * vertices.count,
                                                       options: [])

这就是问题,调用此特定代码会在控制台中产生以下结果:

size: 8
size: 8
vertices a escribir: 2
stride: 8
size of array 8
ispointvertex: true
size: 40
ispointvertex: true
size: 40

在上一个函数中,顶点的大小为8个字节,但是由于某些原因,当它们进入下一个函数时,它们变成40个字节,因此缓冲区构造不正确

如果我将功能签名更改为:

    func renderVertices(vertices: [PointVertex], forStroke stroke: LFStroke, inDrawing drawing:LFDrawing, commandEncoder: MTLRenderCommandEncoder) {

正确地将顶点报告为8个字节长,绘制例程按预期工作

我想念什么吗?如果MetalVertice协议引入了一些噪音?

ios swift metal
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.