gpt4 book ai didi

swift - Metal/Swift - 顶点缓冲区的第一个元素有一个错误值

转载 作者:行者123 更新时间:2023-11-30 10:29:32 24 4
gpt4 key购买 nike

我只是尝试使用 Metal 渲染红色正方形,并且我正在从如下所示的顶点结构数组创建顶点缓冲区:

struct Vertex {
var position: SIMD3<Float>
var color: SIMD4<Float>
}

这是我渲染正方形的地方:

var vertices: [Vertex] = [
Vertex(position: [-0.5, -0.5, 0], color: [1, 0, 0, 1]),
Vertex(position: [-0.5, 0.5, 0], color: [1, 0, 0, 1]),
Vertex(position: [0.5, -0.5, 0], color: [1, 0, 0, 1]),
Vertex(position: [0.5, 0.5, 0], color: [1, 0, 0, 1])
]

var vertexBuffer: MTLBuffer?

func render(using renderCommandEncoder: MTLRenderCommandEncoder) {
if self.vertexBuffer == nil {
self.vertexBuffer = self.device.makeBuffer(
bytes: self.vertices,
length: MemoryLayout<Vertex>.stride * self.vertices.count,
options: []
)
}

if let vertexBuffer = self.vertexBuffer {
renderCommandEncoder.setRenderPipelineState(RenderPipelineStates.defaultState)
renderCommandEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderCommandEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: vertexBuffer.length / MemoryLayout<Vertex>.stride)
}
}

这就是我的渲染管道状态:

let library = device.makeDefaultLibrary()!
let vertexShader = library.makeFunction(name: "basicVertexShader")
let fragmentShader = library.makeFunction(name: "basicFragmentShader")

let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
renderPipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
renderPipelineDescriptor.vertexFunction = vertexShader
renderPipelineDescriptor.fragmentFunction = fragmentShader
renderPipelineDescriptor.sampleCount = 4

let vertexDescriptor = MTLVertexDescriptor()

vertexDescriptor.attributes[0].format = .float3
vertexDescriptor.attributes[0].bufferIndex = 0 // Position
vertexDescriptor.attributes[0].offset = 0

vertexDescriptor.attributes[1].format = .float4
vertexDescriptor.attributes[1].bufferIndex = 0 // Color
vertexDescriptor.attributes[1].offset = MemoryLayout<SIMD3<Float>>.stride

vertexDescriptor.layouts[0].stride = MemoryLayout<Vertex>.stride
renderPipelineDescriptor.vertexDescriptor = vertexDescriptor

self.defaultState = try! device.makeRenderPipelineState(descriptor: renderPipelineDescriptor)

顶点和片段着色器仅传递位置和颜色。由于某种原因,当渲染时,第一个顶点颜色的第一个 float 作为极小的值进入顶点着色器,有效地显示黑色。它仅发生在数组中第一个顶点的红色值上。

有一个黑色顶点的红色正方形

enter image description here

通过调试 GPU 帧,我可以看到第一个顶点的红色分量为 5E-41(本质上为 0)。 enter image description here

我不知道为什么会出现这种情况,当顶点添加到顶点缓冲区时就会发生这种情况。我猜这与我的渲染管道顶点描述符有关,但我无法找出问题所在。感谢您的帮助!

最佳答案

This is, with high likelihood, a duplicate of this question. I'd encourage you to consider the workarounds there, and also to file your own feedback to raise visibility of this bug. - warrenm

正确,这似乎是某种驱动程序错误。我通过向 makeBuffer 添加 cpuCacheModeWriteCombined 选项来修复该问题,并已提交反馈。

 self.vertexBuffer = self.device.makeBuffer(
bytes: self.vertices,
length: MemoryLayout<Vertex>.stride * self.vertices.count,
options: [.cpuCacheModeWriteCombined]
)

关于swift - Metal/Swift - 顶点缓冲区的第一个元素有一个错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59439285/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com